Merge "Add optional right icon to Button widget."
diff --git a/.gitignore b/.gitignore
index b275b2e..7e035d0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,7 +23,6 @@
 /bazel-*
 /compile_commands.json
 /fuzz_out/
-/node_modules/
 /out*
 /ui/dist
 /venv/*
@@ -33,4 +32,4 @@
 examples/sdk/build/
 GPATH
 GRTAGS
-GTAGS
\ No newline at end of file
+GTAGS
diff --git a/Android.bp b/Android.bp
index 603f6ca..92728f9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1005,6 +1005,7 @@
         ":perfetto_src_base_version",
         ":perfetto_src_ipc_client",
         ":perfetto_src_ipc_common",
+        ":perfetto_src_perfetto_cmd_bugreport_path",
         ":perfetto_src_perfetto_cmd_perfetto_cmd",
         ":perfetto_src_perfetto_cmd_protos_cpp_gen",
         ":perfetto_src_perfetto_cmd_trigger_producer",
@@ -1191,6 +1192,7 @@
         ":perfetto_src_ipc_perfetto_ipc",
         ":perfetto_src_kallsyms_kallsyms",
         ":perfetto_src_kernel_utils_syscall_table",
+        ":perfetto_src_perfetto_cmd_bugreport_path",
         ":perfetto_src_protozero_filtering_bytecode_common",
         ":perfetto_src_protozero_filtering_bytecode_generator",
         ":perfetto_src_protozero_filtering_bytecode_parser",
@@ -1990,6 +1992,7 @@
         ":perfetto_src_ipc_perfetto_ipc",
         ":perfetto_src_kallsyms_kallsyms",
         ":perfetto_src_kernel_utils_syscall_table",
+        ":perfetto_src_perfetto_cmd_bugreport_path",
         ":perfetto_src_profiling_common_callstack_trie",
         ":perfetto_src_profiling_common_interner",
         ":perfetto_src_profiling_common_interning_output",
@@ -8222,6 +8225,7 @@
 filegroup {
     name: "perfetto_src_base_threading_threading",
     srcs: [
+        "src/base/threading/spawn.cc",
         "src/base/threading/stream_combinators.cc",
         "src/base/threading/thread_pool.cc",
     ],
@@ -8233,6 +8237,7 @@
     srcs: [
         "src/base/threading/channel_unittest.cc",
         "src/base/threading/future_unittest.cc",
+        "src/base/threading/spawn_unittest.cc",
         "src/base/threading/stream_unittest.cc",
         "src/base/threading/thread_pool_unittest.cc",
         "src/base/threading/util_unittest.cc",
@@ -8252,7 +8257,6 @@
         "src/base/logging_unittest.cc",
         "src/base/metatrace_unittest.cc",
         "src/base/no_destructor_unittest.cc",
-        "src/base/optional_unittest.cc",
         "src/base/paged_memory_unittest.cc",
         "src/base/periodic_task_unittest.cc",
         "src/base/scoped_file_unittest.cc",
@@ -8466,6 +8470,11 @@
     ],
 }
 
+// GN: //src/perfetto_cmd:bugreport_path
+filegroup {
+    name: "perfetto_src_perfetto_cmd_bugreport_path",
+}
+
 // GN: //src/perfetto_cmd:gen_cc_config_descriptor
 genrule {
     name: "perfetto_src_perfetto_cmd_gen_cc_config_descriptor",
@@ -8687,6 +8696,7 @@
     name: "perfetto_src_profiling_memory_end_to_end_tests",
     srcs: [
         "src/profiling/memory/heapprofd_end_to_end_test.cc",
+        "src/profiling/memory/heapprofd_producer_integrationtest.cc",
     ],
 }
 
@@ -9295,6 +9305,7 @@
         "src/trace_processor/importers/common/event_tracker.cc",
         "src/trace_processor/importers/common/flow_tracker.cc",
         "src/trace_processor/importers/common/global_args_tracker.cc",
+        "src/trace_processor/importers/common/metadata_tracker.cc",
         "src/trace_processor/importers/common/process_tracker.cc",
         "src/trace_processor/importers/common/slice_tracker.cc",
         "src/trace_processor/importers/common/slice_translation_table.cc",
@@ -9585,7 +9596,6 @@
         "src/trace_processor/importers/proto/memory_tracker_snapshot_module.cc",
         "src/trace_processor/importers/proto/memory_tracker_snapshot_parser.cc",
         "src/trace_processor/importers/proto/metadata_minimal_module.cc",
-        "src/trace_processor/importers/proto/metadata_tracker.cc",
         "src/trace_processor/importers/proto/network_trace_module.cc",
         "src/trace_processor/importers/proto/packet_analyzer.cc",
         "src/trace_processor/importers/proto/packet_sequence_state_generation.cc",
@@ -9624,6 +9634,7 @@
         "src/trace_processor/importers/proto/active_chrome_processes_tracker_unittest.cc",
         "src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc",
         "src/trace_processor/importers/proto/heap_profile_tracker_unittest.cc",
+        "src/trace_processor/importers/proto/network_trace_module_unittest.cc",
         "src/trace_processor/importers/proto/perf_sample_tracker_unittest.cc",
         "src/trace_processor/importers/proto/proto_trace_parser_unittest.cc",
     ],
@@ -10159,7 +10170,13 @@
     name: "perfetto_src_trace_processor_tables_tables_python",
     srcs: [
         "src/trace_processor/tables/android_tables.py",
+        "src/trace_processor/tables/counter_tables.py",
+        "src/trace_processor/tables/flow_tables.py",
+        "src/trace_processor/tables/memory_tables.py",
         "src/trace_processor/tables/metadata_tables.py",
+        "src/trace_processor/tables/profiler_tables.py",
+        "src/trace_processor/tables/slice_tables.py",
+        "src/trace_processor/tables/trace_proto_tables.py",
         "src/trace_processor/tables/track_tables.py",
     ],
     tools: [
@@ -10168,7 +10185,13 @@
     cmd: "$(location perfetto_src_trace_processor_tables_tables_python_binary) --gen-dir=$(genDir) --inputs $(in) --outputs $(out)",
     out: [
         "src/trace_processor/tables/android_tables_py.h",
+        "src/trace_processor/tables/counter_tables_py.h",
+        "src/trace_processor/tables/flow_tables_py.h",
+        "src/trace_processor/tables/memory_tables_py.h",
         "src/trace_processor/tables/metadata_tables_py.h",
+        "src/trace_processor/tables/profiler_tables_py.h",
+        "src/trace_processor/tables/slice_tables_py.h",
+        "src/trace_processor/tables/trace_proto_tables_py.h",
         "src/trace_processor/tables/track_tables_py.h",
     ],
 }
@@ -10181,7 +10204,13 @@
         "python/generators/trace_processor_table/serialize.py",
         "python/generators/trace_processor_table/util.py",
         "src/trace_processor/tables/android_tables.py",
+        "src/trace_processor/tables/counter_tables.py",
+        "src/trace_processor/tables/flow_tables.py",
+        "src/trace_processor/tables/memory_tables.py",
         "src/trace_processor/tables/metadata_tables.py",
+        "src/trace_processor/tables/profiler_tables.py",
+        "src/trace_processor/tables/slice_tables.py",
+        "src/trace_processor/tables/trace_proto_tables.py",
         "src/trace_processor/tables/track_tables.py",
         "tools/gen_tp_table_headers.py",
     ],
@@ -11604,6 +11633,7 @@
         ":perfetto_src_kallsyms_kallsyms",
         ":perfetto_src_kallsyms_unittests",
         ":perfetto_src_kernel_utils_syscall_table",
+        ":perfetto_src_perfetto_cmd_bugreport_path",
         ":perfetto_src_perfetto_cmd_perfetto_cmd",
         ":perfetto_src_perfetto_cmd_protos_cpp_gen",
         ":perfetto_src_perfetto_cmd_trigger_producer",
diff --git a/BUILD b/BUILD
index 080ae05..8cc1999 100644
--- a/BUILD
+++ b/BUILD
@@ -408,7 +408,6 @@
         "include/perfetto/ext/base/metatrace.h",
         "include/perfetto/ext/base/metatrace_events.h",
         "include/perfetto/ext/base/no_destructor.h",
-        "include/perfetto/ext/base/optional.h",
         "include/perfetto/ext/base/paged_memory.h",
         "include/perfetto/ext/base/periodic_task.h",
         "include/perfetto/ext/base/pipe.h",
@@ -906,6 +905,14 @@
     ],
 )
 
+# GN target: //src/perfetto_cmd:bugreport_path
+perfetto_filegroup(
+    name = "src_perfetto_cmd_bugreport_path",
+    srcs = [
+        "src/perfetto_cmd/bugreport_path.h",
+    ],
+)
+
 # GN target: //src/perfetto_cmd:gen_cc_config_descriptor
 perfetto_cc_proto_descriptor(
     name = "src_perfetto_cmd_gen_cc_config_descriptor",
@@ -1121,6 +1128,8 @@
         "src/trace_processor/importers/common/flow_tracker.h",
         "src/trace_processor/importers/common/global_args_tracker.cc",
         "src/trace_processor/importers/common/global_args_tracker.h",
+        "src/trace_processor/importers/common/metadata_tracker.cc",
+        "src/trace_processor/importers/common/metadata_tracker.h",
         "src/trace_processor/importers/common/process_tracker.cc",
         "src/trace_processor/importers/common/process_tracker.h",
         "src/trace_processor/importers/common/slice_tracker.cc",
@@ -1412,8 +1421,6 @@
         "src/trace_processor/importers/proto/memory_tracker_snapshot_parser.h",
         "src/trace_processor/importers/proto/metadata_minimal_module.cc",
         "src/trace_processor/importers/proto/metadata_minimal_module.h",
-        "src/trace_processor/importers/proto/metadata_tracker.cc",
-        "src/trace_processor/importers/proto/metadata_tracker.h",
         "src/trace_processor/importers/proto/network_trace_module.cc",
         "src/trace_processor/importers/proto/network_trace_module.h",
         "src/trace_processor/importers/proto/packet_analyzer.cc",
@@ -1979,17 +1986,13 @@
 perfetto_filegroup(
     name = "src_trace_processor_tables_tables",
     srcs = [
-        "src/trace_processor/tables/android_tables.h",
         "src/trace_processor/tables/counter_tables.h",
         "src/trace_processor/tables/flow_tables.h",
         "src/trace_processor/tables/macros.h",
         "src/trace_processor/tables/macros_internal.h",
-        "src/trace_processor/tables/memory_tables.h",
-        "src/trace_processor/tables/metadata_tables.h",
         "src/trace_processor/tables/profiler_tables.h",
         "src/trace_processor/tables/slice_tables.h",
         "src/trace_processor/tables/table_destructors.cc",
-        "src/trace_processor/tables/trace_proto_tables.h",
     ],
 )
 
@@ -1998,12 +2001,24 @@
     name = "src_trace_processor_tables_tables_python",
     srcs = [
         "src/trace_processor/tables/android_tables.py",
+        "src/trace_processor/tables/counter_tables.py",
+        "src/trace_processor/tables/flow_tables.py",
+        "src/trace_processor/tables/memory_tables.py",
         "src/trace_processor/tables/metadata_tables.py",
+        "src/trace_processor/tables/profiler_tables.py",
+        "src/trace_processor/tables/slice_tables.py",
+        "src/trace_processor/tables/trace_proto_tables.py",
         "src/trace_processor/tables/track_tables.py",
     ],
     outs = [
         "src/trace_processor/tables/android_tables_py.h",
+        "src/trace_processor/tables/counter_tables_py.h",
+        "src/trace_processor/tables/flow_tables_py.h",
+        "src/trace_processor/tables/memory_tables_py.h",
         "src/trace_processor/tables/metadata_tables_py.h",
+        "src/trace_processor/tables/profiler_tables_py.h",
+        "src/trace_processor/tables/slice_tables_py.h",
+        "src/trace_processor/tables/trace_proto_tables_py.h",
         "src/trace_processor/tables/track_tables_py.h",
     ],
 )
@@ -4529,6 +4544,7 @@
         ":include_perfetto_tracing_tracing",
         ":src_android_stats_android_stats",
         ":src_android_stats_perfetto_atoms",
+        ":src_perfetto_cmd_bugreport_path",
         ":src_perfetto_cmd_perfetto_cmd",
         ":src_perfetto_cmd_trigger_producer",
         ":src_tracing_common",
diff --git a/bazel/rules.bzl b/bazel/rules.bzl
index ac83b5d..4021c58 100644
--- a/bazel/rules.bzl
+++ b/bazel/rules.bzl
@@ -309,10 +309,13 @@
     )
 
 def perfetto_cc_tp_tables(name, srcs, outs, **kwargs):
+    if PERFETTO_CONFIG.root[:2] != "//":
+        fail("Expected PERFETTO_CONFIG.root to start with //")
+
     if PERFETTO_CONFIG.root == "//":
-      python_path = PERFETTO_CONFIG.root + "python"
+        python_path = PERFETTO_CONFIG.root + "python"
     else:
-      python_path = PERFETTO_CONFIG.root + "/python"
+        python_path = PERFETTO_CONFIG.root + "/python"
 
     perfetto_py_binary(
         name = name + "_tool",
@@ -330,6 +333,8 @@
     cmd += ["--gen-dir", "$(RULEDIR)"]
     cmd += ["--inputs", "$(SRCS)"]
     cmd += ["--outputs", "$(OUTS)"]
+    if PERFETTO_CONFIG.root != "//":
+        cmd += ["--header-prefix", PERFETTO_CONFIG.root[2:]]
 
     perfetto_genrule(
         name = name + "_gen",
diff --git a/buildtools/BUILD.gn b/buildtools/BUILD.gn
index 0750e3c..2ac2948 100644
--- a/buildtools/BUILD.gn
+++ b/buildtools/BUILD.gn
@@ -1210,6 +1210,10 @@
   public_configs = [ ":zlib_config" ]
   deps = [ "//gn:default_deps" ]
 
+  if (is_win) {
+    defines = [ "X86_WINDOWS" ]
+  }
+
   # TODO(primiano): look into ADLER32_SIMD_SSSE3 and other SIMD optimizations
   # (from chromium's third_party/zlib/BUILD.gn).
 }
diff --git a/gn/standalone/BUILD.gn b/gn/standalone/BUILD.gn
index 1f58eb5..5c7de64 100644
--- a/gn/standalone/BUILD.gn
+++ b/gn/standalone/BUILD.gn
@@ -93,6 +93,12 @@
     # Use after free detection in GCC is still not good enough: it still fails
     # on very obvious false-positives in trace processor.
     cflags_cc += [ "-Wno-use-after-free" ]
+
+    # GCC 7's handling of uninitialized std::optional is flaky at best and
+    # causes many false positives.
+    # TODO(lalitm): remove this when we upgrade to a GCC version which is good
+    # enough to handle this.
+    cflags_cc += [ "-Wno-maybe-uninitialized" ]
   }
 }
 
diff --git a/gn/standalone/wasm.gni b/gn/standalone/wasm.gni
index 7442af9..3b09531 100644
--- a/gn/standalone/wasm.gni
+++ b/gn/standalone/wasm.gni
@@ -40,6 +40,8 @@
       "-s",
       "WASM=1",
       "-s",
+      "ENVIRONMENT=web,worker",
+      "-s",
       "DISABLE_EXCEPTION_CATCHING=1",
       "-s",
       "NO_DYNAMIC_EXECUTION=1",
diff --git a/include/perfetto/ext/base/BUILD.gn b/include/perfetto/ext/base/BUILD.gn
index 5a44be4..6e38737 100644
--- a/include/perfetto/ext/base/BUILD.gn
+++ b/include/perfetto/ext/base/BUILD.gn
@@ -32,7 +32,6 @@
     "metatrace.h",
     "metatrace_events.h",
     "no_destructor.h",
-    "optional.h",
     "paged_memory.h",
     "periodic_task.h",
     "pipe.h",
diff --git a/include/perfetto/ext/base/base64.h b/include/perfetto/ext/base/base64.h
index 030a83d..5a01164 100644
--- a/include/perfetto/ext/base/base64.h
+++ b/include/perfetto/ext/base/base64.h
@@ -17,9 +17,9 @@
 #ifndef INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
 #define INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
 
+#include <optional>
 #include <string>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/ext/base/utils.h"  // For ssize_t.
 
@@ -56,9 +56,9 @@
                      uint8_t* dst,
                      size_t dst_size);
 
-Optional<std::string> Base64Decode(const char* src, size_t src_size);
+std::optional<std::string> Base64Decode(const char* src, size_t src_size);
 
-inline Optional<std::string> Base64Decode(StringView sv) {
+inline std::optional<std::string> Base64Decode(StringView sv) {
   return Base64Decode(sv.data(), sv.size());
 }
 
diff --git a/include/perfetto/ext/base/http/http_server.h b/include/perfetto/ext/base/http/http_server.h
index c251061..2fe563b 100644
--- a/include/perfetto/ext/base/http/http_server.h
+++ b/include/perfetto/ext/base/http/http_server.h
@@ -21,10 +21,10 @@
 #include <initializer_list>
 #include <list>
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "perfetto/base/task_runner.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/paged_memory.h"
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/ext/base/unix_socket.h"
@@ -37,7 +37,7 @@
 struct HttpRequest {
   explicit HttpRequest(HttpServerConnection* c) : conn(c) {}
 
-  Optional<StringView> GetHeader(StringView name) const;
+  std::optional<StringView> GetHeader(StringView name) const;
 
   HttpServerConnection* conn;
 
diff --git a/include/perfetto/ext/base/optional.h b/include/perfetto/ext/base/optional.h
deleted file mode 100644
index f9ef9ff..0000000
--- a/include/perfetto/ext/base/optional.h
+++ /dev/null
@@ -1,898 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
-#define INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
-
-#include <functional>
-#include <type_traits>
-#include <utility>
-
-#include "perfetto/base/logging.h"
-
-namespace perfetto {
-namespace base {
-
-// Specification:
-// http://en.cppreference.com/w/cpp/utility/optional/in_place_t
-struct in_place_t {};
-
-// Specification:
-// http://en.cppreference.com/w/cpp/utility/optional/nullopt_t
-struct nullopt_t {
-  constexpr explicit nullopt_t(int) {}
-};
-
-// Specification:
-// http://en.cppreference.com/w/cpp/utility/optional/in_place
-constexpr in_place_t in_place = {};
-
-// Specification:
-// http://en.cppreference.com/w/cpp/utility/optional/nullopt
-constexpr nullopt_t nullopt(0);
-
-// Forward declaration, which is referred by following helpers.
-template <typename T>
-class Optional;
-
-namespace internal {
-
-template <typename T, bool = std::is_trivially_destructible<T>::value>
-struct OptionalStorageBase {
-  // Initializing |empty_| here instead of using default member initializing
-  // to avoid errors in g++ 4.8.
-  constexpr OptionalStorageBase() : empty_('\0') {}
-
-  template <class... Args>
-  constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
-      : is_populated_(true), value_(std::forward<Args>(args)...) {}
-
-  // When T is not trivially destructible we must call its
-  // destructor before deallocating its memory.
-  // Note that this hides the (implicitly declared) move constructor, which
-  // would be used for constexpr move constructor in OptionalStorage<T>.
-  // It is needed iff T is trivially move constructible. However, the current
-  // is_trivially_{copy,move}_constructible implementation requires
-  // is_trivially_destructible (which looks a bug, cf:
-  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 and
-  // http://cplusplus.github.io/LWG/lwg-active.html#2116), so it is not
-  // necessary for this case at the moment. Please see also the destructor
-  // comment in "is_trivially_destructible = true" specialization below.
-  ~OptionalStorageBase() {
-    if (is_populated_)
-      value_.~T();
-  }
-
-  template <class... Args>
-  void Init(Args&&... args) {
-    PERFETTO_DCHECK(!is_populated_);
-    ::new (&value_) T(std::forward<Args>(args)...);
-    is_populated_ = true;
-  }
-
-  bool is_populated_ = false;
-  union {
-    // |empty_| exists so that the union will always be initialized, even when
-    // it doesn't contain a value. Union members must be initialized for the
-    // constructor to be 'constexpr'.
-    char empty_;
-    T value_;
-  };
-};
-
-template <typename T>
-struct OptionalStorageBase<T, true /* trivially destructible */> {
-  // Initializing |empty_| here instead of using default member initializing
-  // to avoid errors in g++ 4.8.
-  constexpr OptionalStorageBase() : empty_('\0') {}
-
-  template <class... Args>
-  constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
-      : is_populated_(true), value_(std::forward<Args>(args)...) {}
-
-  // When T is trivially destructible (i.e. its destructor does nothing) there
-  // is no need to call it. Implicitly defined destructor is trivial, because
-  // both members (bool and union containing only variants which are trivially
-  // destructible) are trivially destructible.
-  // Explicitly-defaulted destructor is also trivial, but do not use it here,
-  // because it hides the implicit move constructor. It is needed to implement
-  // constexpr move constructor in OptionalStorage iff T is trivially move
-  // constructible. Note that, if T is trivially move constructible, the move
-  // constructor of OptionalStorageBase<T> is also implicitly defined and it is
-  // trivially move constructor. If T is not trivially move constructible,
-  // "not declaring move constructor without destructor declaration" here means
-  // "delete move constructor", which works because any move constructor of
-  // OptionalStorage will not refer to it in that case.
-
-  template <class... Args>
-  void Init(Args&&... args) {
-    PERFETTO_DCHECK(!is_populated_);
-    ::new (&value_) T(std::forward<Args>(args)...);
-    is_populated_ = true;
-  }
-
-  bool is_populated_ = false;
-  union {
-    // |empty_| exists so that the union will always be initialized, even when
-    // it doesn't contain a value. Union members must be initialized for the
-    // constructor to be 'constexpr'.
-    char empty_;
-    T value_;
-  };
-};
-
-// Implement conditional constexpr copy and move constructors. These are
-// constexpr if is_trivially_{copy,move}_constructible<T>::value is true
-// respectively. If each is true, the corresponding constructor is defined as
-// "= default;", which generates a constexpr constructor (In this case,
-// the condition of constexpr-ness is satisfied because the base class also has
-// compiler generated constexpr {copy,move} constructors). Note that
-// placement-new is prohibited in constexpr.
-template <typename T, bool = std::is_trivially_copy_constructible<T>::value>
-struct OptionalStorage : OptionalStorageBase<T> {
-  // This is no trivially {copy,move} constructible case. Other cases are
-  // defined below as specializations.
-
-  // Accessing the members of template base class requires explicit
-  // declaration.
-  using OptionalStorageBase<T>::is_populated_;
-  using OptionalStorageBase<T>::value_;
-  using OptionalStorageBase<T>::Init;
-
-  // Inherit constructors (specifically, the in_place constructor).
-  using OptionalStorageBase<T>::OptionalStorageBase;
-
-  // User defined constructor deletes the default constructor.
-  // Define it explicitly.
-  OptionalStorage() = default;
-
-  OptionalStorage(const OptionalStorage& other) : OptionalStorageBase<T>() {
-    if (other.is_populated_)
-      Init(other.value_);
-  }
-
-  OptionalStorage(OptionalStorage&& other) noexcept(
-      std::is_nothrow_move_constructible<T>::value) {
-    if (other.is_populated_)
-      Init(std::move(other.value_));
-  }
-};
-
-template <typename T>
-struct OptionalStorage<T, true /* trivially copy constructible */>
-    : OptionalStorageBase<T> {
-  using OptionalStorageBase<T>::is_populated_;
-  using OptionalStorageBase<T>::value_;
-  using OptionalStorageBase<T>::Init;
-  using OptionalStorageBase<T>::OptionalStorageBase;
-
-  OptionalStorage() = default;
-  OptionalStorage(const OptionalStorage& other) = default;
-
-  OptionalStorage(OptionalStorage&& other) noexcept(
-      std::is_nothrow_move_constructible<T>::value) {
-    if (other.is_populated_)
-      Init(std::move(other.value_));
-  }
-};
-
-// Base class to support conditionally usable copy-/move- constructors
-// and assign operators.
-template <typename T>
-class OptionalBase {
-  // This class provides implementation rather than public API, so everything
-  // should be hidden. Often we use composition, but we cannot in this case
-  // because of C++ language restriction.
- protected:
-  constexpr OptionalBase() = default;
-  constexpr OptionalBase(const OptionalBase& other) = default;
-  constexpr OptionalBase(OptionalBase&& other) = default;
-
-  template <class... Args>
-  constexpr explicit OptionalBase(in_place_t, Args&&... args)
-      : storage_(in_place, std::forward<Args>(args)...) {}
-
-  // Implementation of converting constructors.
-  template <typename U>
-  explicit OptionalBase(const OptionalBase<U>& other) {
-    if (other.storage_.is_populated_)
-      storage_.Init(other.storage_.value_);
-  }
-
-  template <typename U>
-  explicit OptionalBase(OptionalBase<U>&& other) {
-    if (other.storage_.is_populated_)
-      storage_.Init(std::move(other.storage_.value_));
-  }
-
-  ~OptionalBase() = default;
-
-  OptionalBase& operator=(const OptionalBase& other) {
-    CopyAssign(other);
-    return *this;
-  }
-
-  OptionalBase& operator=(OptionalBase&& other) noexcept(
-      std::is_nothrow_move_assignable<T>::value&&
-          std::is_nothrow_move_constructible<T>::value) {
-    MoveAssign(std::move(other));
-    return *this;
-  }
-
-  template <typename U>
-  void CopyAssign(const OptionalBase<U>& other) {
-    if (other.storage_.is_populated_)
-      InitOrAssign(other.storage_.value_);
-    else
-      FreeIfNeeded();
-  }
-
-  template <typename U>
-  void MoveAssign(OptionalBase<U>&& other) {
-    if (other.storage_.is_populated_)
-      InitOrAssign(std::move(other.storage_.value_));
-    else
-      FreeIfNeeded();
-  }
-
-  template <typename U>
-  void InitOrAssign(U&& value) {
-    if (storage_.is_populated_)
-      storage_.value_ = std::forward<U>(value);
-    else
-      storage_.Init(std::forward<U>(value));
-  }
-
-  void FreeIfNeeded() {
-    if (!storage_.is_populated_)
-      return;
-    storage_.value_.~T();
-    storage_.is_populated_ = false;
-  }
-
-  // For implementing conversion, allow access to other typed OptionalBase
-  // class.
-  template <typename U>
-  friend class OptionalBase;
-
-  OptionalStorage<T> storage_;
-};
-
-// The following {Copy,Move}{Constructible,Assignable} structs are helpers to
-// implement constructor/assign-operator overloading. Specifically, if T is
-// is not movable but copyable, Optional<T>'s move constructor should not
-// participate in overload resolution. This inheritance trick implements that.
-template <bool is_copy_constructible>
-struct CopyConstructible {};
-
-template <>
-struct CopyConstructible<false> {
-  constexpr CopyConstructible() = default;
-  constexpr CopyConstructible(const CopyConstructible&) = delete;
-  constexpr CopyConstructible(CopyConstructible&&) = default;
-  CopyConstructible& operator=(const CopyConstructible&) = default;
-  CopyConstructible& operator=(CopyConstructible&&) = default;
-};
-
-template <bool is_move_constructible>
-struct MoveConstructible {};
-
-template <>
-struct MoveConstructible<false> {
-  constexpr MoveConstructible() = default;
-  constexpr MoveConstructible(const MoveConstructible&) = default;
-  constexpr MoveConstructible(MoveConstructible&&) = delete;
-  MoveConstructible& operator=(const MoveConstructible&) = default;
-  MoveConstructible& operator=(MoveConstructible&&) = default;
-};
-
-template <bool is_copy_assignable>
-struct CopyAssignable {};
-
-template <>
-struct CopyAssignable<false> {
-  constexpr CopyAssignable() = default;
-  constexpr CopyAssignable(const CopyAssignable&) = default;
-  constexpr CopyAssignable(CopyAssignable&&) = default;
-  CopyAssignable& operator=(const CopyAssignable&) = delete;
-  CopyAssignable& operator=(CopyAssignable&&) = default;
-};
-
-template <bool is_move_assignable>
-struct MoveAssignable {};
-
-template <>
-struct MoveAssignable<false> {
-  constexpr MoveAssignable() = default;
-  constexpr MoveAssignable(const MoveAssignable&) = default;
-  constexpr MoveAssignable(MoveAssignable&&) = default;
-  MoveAssignable& operator=(const MoveAssignable&) = default;
-  MoveAssignable& operator=(MoveAssignable&&) = delete;
-};
-
-// Helper to conditionally enable converting constructors and assign operators.
-template <typename T, typename U>
-struct IsConvertibleFromOptional
-    : std::integral_constant<
-          bool,
-          std::is_constructible<T, Optional<U>&>::value ||
-              std::is_constructible<T, const Optional<U>&>::value ||
-              std::is_constructible<T, Optional<U>&&>::value ||
-              std::is_constructible<T, const Optional<U>&&>::value ||
-              std::is_convertible<Optional<U>&, T>::value ||
-              std::is_convertible<const Optional<U>&, T>::value ||
-              std::is_convertible<Optional<U>&&, T>::value ||
-              std::is_convertible<const Optional<U>&&, T>::value> {};
-
-template <typename T, typename U>
-struct IsAssignableFromOptional
-    : std::integral_constant<
-          bool,
-          IsConvertibleFromOptional<T, U>::value ||
-              std::is_assignable<T&, Optional<U>&>::value ||
-              std::is_assignable<T&, const Optional<U>&>::value ||
-              std::is_assignable<T&, Optional<U>&&>::value ||
-              std::is_assignable<T&, const Optional<U>&&>::value> {};
-
-// Forward compatibility for C++17.
-// Introduce one more deeper nested namespace to avoid leaking using std::swap.
-namespace swappable_impl {
-using std::swap;
-
-struct IsSwappableImpl {
-  // Tests if swap can be called. Check<T&>(0) returns true_type iff swap is
-  // available for T. Otherwise, Check's overload resolution falls back to
-  // Check(...) declared below thanks to SFINAE, so returns false_type.
-  template <typename T>
-  static auto Check(int)
-      -> decltype(swap(std::declval<T>(), std::declval<T>()), std::true_type());
-
-  template <typename T>
-  static std::false_type Check(...);
-};
-}  // namespace swappable_impl
-
-template <typename T>
-struct IsSwappable : decltype(swappable_impl::IsSwappableImpl::Check<T&>(0)) {};
-
-// Forward compatibility for C++20.
-template <typename T>
-using RemoveCvRefT =
-    typename std::remove_cv<typename std::remove_reference<T>::type>::type;
-
-}  // namespace internal
-
-// On Windows, by default, empty-base class optimization does not work,
-// which means even if the base class is empty struct, it still consumes one
-// byte for its body. __declspec(empty_bases) enables the optimization.
-// cf)
-// https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
-    !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
-#define OPTIONAL_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
-#else
-#define OPTIONAL_DECLSPEC_EMPTY_BASES
-#endif
-
-// base::Optional is a Chromium version of the C++17 optional class:
-// std::optional documentation:
-// http://en.cppreference.com/w/cpp/utility/optional
-// Chromium documentation:
-// https://chromium.googlesource.com/chromium/src/+/master/docs/optional.md
-//
-// These are the differences between the specification and the implementation:
-// - Constructors do not use 'constexpr' as it is a C++14 extension.
-// - 'constexpr' might be missing in some places for reasons specified locally.
-// - No exceptions are thrown, because they are banned from Chromium.
-//   Marked noexcept for only move constructor and move assign operators.
-// - All the non-members are in the 'base' namespace instead of 'std'.
-//
-// Note that T cannot have a constructor T(Optional<T>) etc. Optional<T>
-// PERFETTO_CHECKs T's constructor (specifically via IsConvertibleFromOptional),
-// and in the PERFETTO_CHECK whether T can be constructible from Optional<T>,
-// which is recursive so it does not work. As of Feb 2018, std::optional C++17
-// implementation in both clang and gcc has same limitation. MSVC SFINAE looks
-// to have different behavior, but anyway it reports an error, too.
-//
-// This file is a modified version of optional.h from Chromium at revision
-// 5e71bd454e60511c1293c0c686544aaa76094424. The changes remove C++14/C++17
-// specific code and replace with C++11 counterparts.
-template <typename T>
-class OPTIONAL_DECLSPEC_EMPTY_BASES Optional
-    : public internal::OptionalBase<T>,
-      public internal::CopyConstructible<std::is_copy_constructible<T>::value>,
-      public internal::MoveConstructible<std::is_move_constructible<T>::value>,
-      public internal::CopyAssignable<std::is_copy_constructible<T>::value &&
-                                      std::is_copy_assignable<T>::value>,
-      public internal::MoveAssignable<std::is_move_constructible<T>::value &&
-                                      std::is_move_assignable<T>::value> {
- public:
-#undef OPTIONAL_DECLSPEC_EMPTY_BASES
-  using value_type = T;
-
-  // Defer default/copy/move constructor implementation to OptionalBase.
-  constexpr Optional() = default;
-  constexpr Optional(const Optional& other) = default;
-  constexpr Optional(Optional&& other) noexcept(
-      std::is_nothrow_move_constructible<T>::value) = default;
-
-  constexpr Optional(nullopt_t) {}  // NOLINT(runtime/explicit)
-
-  // Converting copy constructor. "explicit" only if
-  // std::is_convertible<const U&, T>::value is false. It is implemented by
-  // declaring two almost same constructors, but that condition in enable_if_t
-  // is different, so that either one is chosen, thanks to SFINAE.
-  template <typename U,
-            typename std::enable_if<
-                std::is_constructible<T, const U&>::value &&
-                    !internal::IsConvertibleFromOptional<T, U>::value &&
-                    std::is_convertible<const U&, T>::value,
-                bool>::type = false>
-  Optional(const Optional<U>& other) : internal::OptionalBase<T>(other) {}
-
-  template <typename U,
-            typename std::enable_if<
-                std::is_constructible<T, const U&>::value &&
-                    !internal::IsConvertibleFromOptional<T, U>::value &&
-                    !std::is_convertible<const U&, T>::value,
-                bool>::type = false>
-  explicit Optional(const Optional<U>& other)
-      : internal::OptionalBase<T>(other) {}
-
-  // Converting move constructor. Similar to converting copy constructor,
-  // declaring two (explicit and non-explicit) constructors.
-  template <typename U,
-            typename std::enable_if<
-                std::is_constructible<T, U&&>::value &&
-                    !internal::IsConvertibleFromOptional<T, U>::value &&
-                    std::is_convertible<U&&, T>::value,
-                bool>::type = false>
-  Optional(Optional<U>&& other) : internal::OptionalBase<T>(std::move(other)) {}
-
-  template <typename U,
-            typename std::enable_if<
-                std::is_constructible<T, U&&>::value &&
-                    !internal::IsConvertibleFromOptional<T, U>::value &&
-                    !std::is_convertible<U&&, T>::value,
-                bool>::type = false>
-  explicit Optional(Optional<U>&& other)
-      : internal::OptionalBase<T>(std::move(other)) {}
-
-  template <class... Args>
-  constexpr explicit Optional(in_place_t, Args&&... args)
-      : internal::OptionalBase<T>(in_place, std::forward<Args>(args)...) {}
-
-  template <class U,
-            class... Args,
-            class = typename std::enable_if<
-                std::is_constructible<value_type,
-                                      std::initializer_list<U>&,
-                                      Args...>::value>::type>
-  constexpr explicit Optional(in_place_t,
-                              std::initializer_list<U> il,
-                              Args&&... args)
-      : internal::OptionalBase<T>(in_place, il, std::forward<Args>(args)...) {}
-
-  // Forward value constructor. Similar to converting constructors,
-  // conditionally explicit.
-  template <
-      typename U = value_type,
-      typename std::enable_if<
-          std::is_constructible<T, U&&>::value &&
-              !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
-              !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
-              std::is_convertible<U&&, T>::value,
-          bool>::type = false>
-  constexpr Optional(U&& value)
-      : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
-
-  template <
-      typename U = value_type,
-      typename std::enable_if<
-          std::is_constructible<T, U&&>::value &&
-              !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
-              !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
-              !std::is_convertible<U&&, T>::value,
-          bool>::type = false>
-  constexpr explicit Optional(U&& value)
-      : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
-
-  ~Optional() = default;
-
-  // Defer copy-/move- assign operator implementation to OptionalBase.
-  Optional& operator=(const Optional& other) = default;
-  Optional& operator=(Optional&& other) noexcept(
-      std::is_nothrow_move_assignable<T>::value&&
-          std::is_nothrow_move_constructible<T>::value) = default;
-
-  Optional& operator=(nullopt_t) {
-    FreeIfNeeded();
-    return *this;
-  }
-
-  // Perfect-forwarded assignment.
-  template <typename U>
-  typename std::enable_if<
-      !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
-          std::is_constructible<T, U>::value &&
-          std::is_assignable<T&, U>::value &&
-          (!std::is_scalar<T>::value ||
-           !std::is_same<typename std::decay<U>::type, T>::value),
-      Optional&>::type
-  operator=(U&& value) {
-    InitOrAssign(std::forward<U>(value));
-    return *this;
-  }
-
-  // Copy assign the state of other.
-  template <typename U>
-  typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
-                              std::is_constructible<T, const U&>::value &&
-                              std::is_assignable<T&, const U&>::value,
-                          Optional&>::type
-  operator=(const Optional<U>& other) {
-    CopyAssign(other);
-    return *this;
-  }
-
-  // Move assign the state of other.
-  template <typename U>
-  typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
-                              std::is_constructible<T, U>::value &&
-                              std::is_assignable<T&, U>::value,
-                          Optional&>::type
-  operator=(Optional<U>&& other) {
-    MoveAssign(std::move(other));
-    return *this;
-  }
-
-  const T* operator->() const {
-    PERFETTO_DCHECK(storage_.is_populated_);
-    return &storage_.value_;
-  }
-
-  T* operator->() {
-    PERFETTO_DCHECK(storage_.is_populated_);
-    return &storage_.value_;
-  }
-
-  const T& operator*() const& {
-    PERFETTO_DCHECK(storage_.is_populated_);
-    return storage_.value_;
-  }
-
-  T& operator*() & {
-    PERFETTO_DCHECK(storage_.is_populated_);
-    return storage_.value_;
-  }
-
-  const T&& operator*() const&& {
-    PERFETTO_DCHECK(storage_.is_populated_);
-    return std::move(storage_.value_);
-  }
-
-  T&& operator*() && {
-    PERFETTO_DCHECK(storage_.is_populated_);
-    return std::move(storage_.value_);
-  }
-
-  constexpr explicit operator bool() const { return storage_.is_populated_; }
-
-  constexpr bool has_value() const { return storage_.is_populated_; }
-
-  T& value() & {
-    PERFETTO_CHECK(storage_.is_populated_);
-    return storage_.value_;
-  }
-
-  const T& value() const& {
-    PERFETTO_CHECK(storage_.is_populated_);
-    return storage_.value_;
-  }
-
-  T&& value() && {
-    PERFETTO_CHECK(storage_.is_populated_);
-    return std::move(storage_.value_);
-  }
-
-  const T&& value() const&& {
-    PERFETTO_CHECK(storage_.is_populated_);
-    return std::move(storage_.value_);
-  }
-
-  template <class U>
-  constexpr T value_or(U&& default_value) const& {
-    static_assert(std::is_convertible<U, T>::value,
-                  "U must be convertible to T");
-    return storage_.is_populated_
-               ? storage_.value_
-               : static_cast<T>(std::forward<U>(default_value));
-  }
-
-  template <class U>
-  T value_or(U&& default_value) && {
-    static_assert(std::is_convertible<U, T>::value,
-                  "U must be convertible to T");
-    return storage_.is_populated_
-               ? std::move(storage_.value_)
-               : static_cast<T>(std::forward<U>(default_value));
-  }
-
-  void swap(Optional& other) {
-    if (!storage_.is_populated_ && !other.storage_.is_populated_)
-      return;
-
-    if (storage_.is_populated_ != other.storage_.is_populated_) {
-      if (storage_.is_populated_) {
-        other.storage_.Init(std::move(storage_.value_));
-        FreeIfNeeded();
-      } else {
-        storage_.Init(std::move(other.storage_.value_));
-        other.FreeIfNeeded();
-      }
-      return;
-    }
-
-    PERFETTO_DCHECK(storage_.is_populated_ && other.storage_.is_populated_);
-    using std::swap;
-    swap(**this, *other);
-  }
-
-  void reset() { FreeIfNeeded(); }
-
-  template <class... Args>
-  T& emplace(Args&&... args) {
-    FreeIfNeeded();
-    storage_.Init(std::forward<Args>(args)...);
-    return storage_.value_;
-  }
-
-  template <class U, class... Args>
-  typename std::enable_if<
-      std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value,
-      T&>::type
-  emplace(std::initializer_list<U> il, Args&&... args) {
-    FreeIfNeeded();
-    storage_.Init(il, std::forward<Args>(args)...);
-    return storage_.value_;
-  }
-
- private:
-  // Accessing template base class's protected member needs explicit
-  // declaration to do so.
-  using internal::OptionalBase<T>::CopyAssign;
-  using internal::OptionalBase<T>::FreeIfNeeded;
-  using internal::OptionalBase<T>::InitOrAssign;
-  using internal::OptionalBase<T>::MoveAssign;
-  using internal::OptionalBase<T>::storage_;
-};
-
-// Here after defines comparation operators. The definition follows
-// http://en.cppreference.com/w/cpp/utility/optional/operator_cmp
-// while bool() casting is replaced by has_value() to meet the chromium
-// style guide.
-template <class T, class U>
-bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) {
-  if (lhs.has_value() != rhs.has_value())
-    return false;
-  if (!lhs.has_value())
-    return true;
-  return *lhs == *rhs;
-}
-
-template <class T, class U>
-bool operator!=(const Optional<T>& lhs, const Optional<U>& rhs) {
-  if (lhs.has_value() != rhs.has_value())
-    return true;
-  if (!lhs.has_value())
-    return false;
-  return *lhs != *rhs;
-}
-
-template <class T, class U>
-bool operator<(const Optional<T>& lhs, const Optional<U>& rhs) {
-  if (!rhs.has_value())
-    return false;
-  if (!lhs.has_value())
-    return true;
-  return *lhs < *rhs;
-}
-
-template <class T, class U>
-bool operator<=(const Optional<T>& lhs, const Optional<U>& rhs) {
-  if (!lhs.has_value())
-    return true;
-  if (!rhs.has_value())
-    return false;
-  return *lhs <= *rhs;
-}
-
-template <class T, class U>
-bool operator>(const Optional<T>& lhs, const Optional<U>& rhs) {
-  if (!lhs.has_value())
-    return false;
-  if (!rhs.has_value())
-    return true;
-  return *lhs > *rhs;
-}
-
-template <class T, class U>
-bool operator>=(const Optional<T>& lhs, const Optional<U>& rhs) {
-  if (!rhs.has_value())
-    return true;
-  if (!lhs.has_value())
-    return false;
-  return *lhs >= *rhs;
-}
-
-template <class T>
-constexpr bool operator==(const Optional<T>& opt, nullopt_t) {
-  return !opt;
-}
-
-template <class T>
-constexpr bool operator==(nullopt_t, const Optional<T>& opt) {
-  return !opt;
-}
-
-template <class T>
-constexpr bool operator!=(const Optional<T>& opt, nullopt_t) {
-  return opt.has_value();
-}
-
-template <class T>
-constexpr bool operator!=(nullopt_t, const Optional<T>& opt) {
-  return opt.has_value();
-}
-
-template <class T>
-constexpr bool operator<(const Optional<T>&, nullopt_t) {
-  return false;
-}
-
-template <class T>
-constexpr bool operator<(nullopt_t, const Optional<T>& opt) {
-  return opt.has_value();
-}
-
-template <class T>
-constexpr bool operator<=(const Optional<T>& opt, nullopt_t) {
-  return !opt;
-}
-
-template <class T>
-constexpr bool operator<=(nullopt_t, const Optional<T>&) {
-  return true;
-}
-
-template <class T>
-constexpr bool operator>(const Optional<T>& opt, nullopt_t) {
-  return opt.has_value();
-}
-
-template <class T>
-constexpr bool operator>(nullopt_t, const Optional<T>&) {
-  return false;
-}
-
-template <class T>
-constexpr bool operator>=(const Optional<T>&, nullopt_t) {
-  return true;
-}
-
-template <class T>
-constexpr bool operator>=(nullopt_t, const Optional<T>& opt) {
-  return !opt;
-}
-
-template <class T, class U>
-constexpr bool operator==(const Optional<T>& opt, const U& value) {
-  return opt.has_value() ? *opt == value : false;
-}
-
-template <class T, class U>
-constexpr bool operator==(const U& value, const Optional<T>& opt) {
-  return opt.has_value() ? value == *opt : false;
-}
-
-template <class T, class U>
-constexpr bool operator!=(const Optional<T>& opt, const U& value) {
-  return opt.has_value() ? *opt != value : true;
-}
-
-template <class T, class U>
-constexpr bool operator!=(const U& value, const Optional<T>& opt) {
-  return opt.has_value() ? value != *opt : true;
-}
-
-template <class T, class U>
-constexpr bool operator<(const Optional<T>& opt, const U& value) {
-  return opt.has_value() ? *opt < value : true;
-}
-
-template <class T, class U>
-constexpr bool operator<(const U& value, const Optional<T>& opt) {
-  return opt.has_value() ? value < *opt : false;
-}
-
-template <class T, class U>
-constexpr bool operator<=(const Optional<T>& opt, const U& value) {
-  return opt.has_value() ? *opt <= value : true;
-}
-
-template <class T, class U>
-constexpr bool operator<=(const U& value, const Optional<T>& opt) {
-  return opt.has_value() ? value <= *opt : false;
-}
-
-template <class T, class U>
-constexpr bool operator>(const Optional<T>& opt, const U& value) {
-  return opt.has_value() ? *opt > value : false;
-}
-
-template <class T, class U>
-constexpr bool operator>(const U& value, const Optional<T>& opt) {
-  return opt.has_value() ? value > *opt : true;
-}
-
-template <class T, class U>
-constexpr bool operator>=(const Optional<T>& opt, const U& value) {
-  return opt.has_value() ? *opt >= value : false;
-}
-
-template <class T, class U>
-constexpr bool operator>=(const U& value, const Optional<T>& opt) {
-  return opt.has_value() ? value >= *opt : true;
-}
-
-template <class T>
-constexpr Optional<typename std::decay<T>::type> make_optional(T&& value) {
-  return Optional<typename std::decay<T>::type>(std::forward<T>(value));
-}
-
-template <class T, class... Args>
-constexpr Optional<T> make_optional(Args&&... args) {
-  return Optional<T>(in_place, std::forward<Args>(args)...);
-}
-
-template <class T, class U, class... Args>
-constexpr Optional<T> make_optional(std::initializer_list<U> il,
-                                    Args&&... args) {
-  return Optional<T>(in_place, il, std::forward<Args>(args)...);
-}
-
-// Partial specialization for a function template is not allowed. Also, it is
-// not allowed to add overload function to std namespace, while it is allowed
-// to specialize the template in std. Thus, swap() (kind of) overloading is
-// defined in base namespace, instead.
-template <class T>
-typename std::enable_if<std::is_move_constructible<T>::value &&
-                        internal::IsSwappable<T>::value>::type
-swap(Optional<T>& lhs, Optional<T>& rhs) {
-  lhs.swap(rhs);
-}
-
-}  // namespace base
-}  // namespace perfetto
-
-template <class T>
-struct std::hash<perfetto::base::Optional<T>> {
-  size_t operator()(const perfetto::base::Optional<T>& opt) const {
-    return opt == perfetto::base::nullopt ? 0 : std::hash<T>()(*opt);
-  }
-};
-
-#endif  // INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
diff --git a/include/perfetto/ext/base/status_or.h b/include/perfetto/ext/base/status_or.h
index 7067295..46387d7 100644
--- a/include/perfetto/ext/base/status_or.h
+++ b/include/perfetto/ext/base/status_or.h
@@ -17,8 +17,9 @@
 #ifndef INCLUDE_PERFETTO_EXT_BASE_STATUS_OR_H_
 #define INCLUDE_PERFETTO_EXT_BASE_STATUS_OR_H_
 
+#include <optional>
+
 #include "perfetto/base/status.h"
-#include "perfetto/ext/base/optional.h"
 
 namespace perfetto {
 namespace base {
@@ -38,7 +39,7 @@
 
   // Intentionally implicit to allow idomatic usage (e.g. returning value/status
   // from base::StatusOr returning function).
-  StatusOr(base::Status status) : StatusOr(std::move(status), base::nullopt) {
+  StatusOr(base::Status status) : StatusOr(std::move(status), std::nullopt) {
     if (status.ok()) {
       // Matches what Abseil's approach towards OkStatus being passed to
       // absl::StatusOr<T>.
@@ -63,13 +64,13 @@
   const T* operator->() const { return &value(); }
 
  private:
-  StatusOr(base::Status status, base::Optional<T> value)
+  StatusOr(base::Status status, std::optional<T> value)
       : status_(std::move(status)), value_(std::move(value)) {
     PERFETTO_DCHECK(!status_.ok() || value_.has_value());
   }
 
   base::Status status_;
-  base::Optional<T> value_;
+  std::optional<T> value_;
 };
 
 }  // namespace base
diff --git a/include/perfetto/ext/base/string_utils.h b/include/perfetto/ext/base/string_utils.h
index 828d214..20e5799 100644
--- a/include/perfetto/ext/base/string_utils.h
+++ b/include/perfetto/ext/base/string_utils.h
@@ -22,10 +22,10 @@
 #include <string.h>
 
 #include <cinttypes>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 
 namespace perfetto {
@@ -39,59 +39,63 @@
   return ('a' <= c && c <= 'z') ? static_cast<char>(c + ('A' - 'a')) : c;
 }
 
-inline Optional<uint32_t> CStringToUInt32(const char* s, int base = 10) {
+inline std::optional<uint32_t> CStringToUInt32(const char* s, int base = 10) {
   char* endptr = nullptr;
   auto value = static_cast<uint32_t>(strtoul(s, &endptr, base));
-  return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
+  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
 }
 
-inline Optional<int32_t> CStringToInt32(const char* s, int base = 10) {
+inline std::optional<int32_t> CStringToInt32(const char* s, int base = 10) {
   char* endptr = nullptr;
   auto value = static_cast<int32_t>(strtol(s, &endptr, base));
-  return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
+  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
 }
 
 // Note: it saturates to 7fffffffffffffff if parsing a hex number >= 0x8000...
-inline Optional<int64_t> CStringToInt64(const char* s, int base = 10) {
+inline std::optional<int64_t> CStringToInt64(const char* s, int base = 10) {
   char* endptr = nullptr;
   auto value = static_cast<int64_t>(strtoll(s, &endptr, base));
-  return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
+  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
 }
 
-inline Optional<uint64_t> CStringToUInt64(const char* s, int base = 10) {
+inline std::optional<uint64_t> CStringToUInt64(const char* s, int base = 10) {
   char* endptr = nullptr;
   auto value = static_cast<uint64_t>(strtoull(s, &endptr, base));
-  return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
+  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
 }
 
 double StrToD(const char* nptr, char** endptr);
 
-inline Optional<double> CStringToDouble(const char* s) {
+inline std::optional<double> CStringToDouble(const char* s) {
   char* endptr = nullptr;
   double value = StrToD(s, &endptr);
-  Optional<double> result(base::nullopt);
+  std::optional<double> result(std::nullopt);
   if (*s != '\0' && *endptr == '\0')
     result = value;
   return result;
 }
 
-inline Optional<uint32_t> StringToUInt32(const std::string& s, int base = 10) {
+inline std::optional<uint32_t> StringToUInt32(const std::string& s,
+                                              int base = 10) {
   return CStringToUInt32(s.c_str(), base);
 }
 
-inline Optional<int32_t> StringToInt32(const std::string& s, int base = 10) {
+inline std::optional<int32_t> StringToInt32(const std::string& s,
+                                            int base = 10) {
   return CStringToInt32(s.c_str(), base);
 }
 
-inline Optional<uint64_t> StringToUInt64(const std::string& s, int base = 10) {
+inline std::optional<uint64_t> StringToUInt64(const std::string& s,
+                                              int base = 10) {
   return CStringToUInt64(s.c_str(), base);
 }
 
-inline Optional<int64_t> StringToInt64(const std::string& s, int base = 10) {
+inline std::optional<int64_t> StringToInt64(const std::string& s,
+                                            int base = 10) {
   return CStringToInt64(s.c_str(), base);
 }
 
-inline Optional<double> StringToDouble(const std::string& s) {
+inline std::optional<double> StringToDouble(const std::string& s) {
   return CStringToDouble(s.c_str());
 }
 
@@ -177,10 +181,10 @@
 
 // For given string and offset Pfinds a line with character for
 // which offset points, what number is this line (starts from 1), and the offset
-// inside this line. returns nullopt if the offset points to
+// inside this line. returns std::nullopt if the offset points to
 // line break character or exceeds string length.
-base::Optional<LineWithOffset> FindLineWithOffset(base::StringView str,
-                                                  uint32_t offset);
+std::optional<LineWithOffset> FindLineWithOffset(base::StringView str,
+                                                 uint32_t offset);
 
 // A helper class to facilitate construction and usage of write-once stack
 // strings.
diff --git a/include/perfetto/ext/base/subprocess.h b/include/perfetto/ext/base/subprocess.h
index 6102832..12121e0 100644
--- a/include/perfetto/ext/base/subprocess.h
+++ b/include/perfetto/ext/base/subprocess.h
@@ -21,6 +21,7 @@
 #include <functional>
 #include <initializer_list>
 #include <mutex>
+#include <optional>
 #include <string>
 #include <thread>
 #include <vector>
@@ -30,7 +31,6 @@
 #include "perfetto/base/platform_handle.h"
 #include "perfetto/base/proc_utils.h"
 #include "perfetto/ext/base/event_fd.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/pipe.h"
 #include "perfetto/ext/base/scoped_file.h"
 
@@ -145,7 +145,7 @@
     // setpgid(0 /*self_pid*/, posix_proc_group_id).
     // This can be used to avoid that subprocesses receive CTRL-C from the
     // terminal, while still living in the same session.
-    base::Optional<pid_t> posix_proc_group_id{};
+    std::optional<pid_t> posix_proc_group_id{};
 #endif
 
     // If non-empty, replaces the environment passed to exec().
diff --git a/include/perfetto/ext/base/threading/BUILD.gn b/include/perfetto/ext/base/threading/BUILD.gn
index 9e557ec..d3a7b85 100644
--- a/include/perfetto/ext/base/threading/BUILD.gn
+++ b/include/perfetto/ext/base/threading/BUILD.gn
@@ -20,6 +20,7 @@
     "future.h",
     "future_combinators.h",
     "poll.h",
+    "spawn.h",
     "stream.h",
     "stream_combinators.h",
     "thread_pool.h",
diff --git a/include/perfetto/ext/base/threading/channel.h b/include/perfetto/ext/base/threading/channel.h
index d117ff0..9bf42f5 100644
--- a/include/perfetto/ext/base/threading/channel.h
+++ b/include/perfetto/ext/base/threading/channel.h
@@ -18,12 +18,12 @@
 #define INCLUDE_PERFETTO_EXT_BASE_THREADING_CHANNEL_H_
 
 #include <mutex>
+#include <optional>
 
 #include "perfetto/base/compiler.h"
 #include "perfetto/base/platform_handle.h"
 #include "perfetto/ext/base/circular_queue.h"
 #include "perfetto/ext/base/event_fd.h"
-#include "perfetto/ext/base/optional.h"
 
 namespace perfetto {
 namespace base {
@@ -43,24 +43,24 @@
 class Channel {
  public:
   struct ReadResult {
-    ReadResult(base::Optional<T> _item, bool _is_closed)
+    ReadResult(std::optional<T> _item, bool _is_closed)
         : item(std::move(_item)), is_closed(_is_closed) {}
 
     bool operator==(const ReadResult& res) const {
       return item == res.item && is_closed == res.is_closed;
     }
 
-    // The item read from the channel or base::nullopt if the channel is empty.
+    // The item read from the channel or std::nullopt if the channel is empty.
     // If so, callers can use |read_fd| to be notified when a read operation
     // would succeed.
-    base::Optional<T> item;
+    std::optional<T> item;
 
     // Indicates the channel is closed. Readers can continue to read from the
     // channel and any buffered elements will be correctly returned. Moreover,
     // any future reads will also have |is_closed| == true and |read_fd| will be
     // ready forever.
     //
-    // Once a ReadResult is returned with |item| == base::nullopt and
+    // Once a ReadResult is returned with |item| == std::nullopt and
     // |is_closed| == true, no further values will ever be returned.
     bool is_closed;
   };
@@ -103,7 +103,7 @@
   PERFETTO_WARN_UNUSED_RESULT ReadResult ReadNonBlocking() {
     std::lock_guard<std::mutex> lock(mutex_);
     if (elements_.empty()) {
-      return ReadResult(base::nullopt, is_closed_);
+      return ReadResult(std::nullopt, is_closed_);
     }
     if (elements_.capacity() == elements_.size()) {
       write_fd_.Notify();
diff --git a/include/perfetto/ext/base/threading/future_combinators.h b/include/perfetto/ext/base/threading/future_combinators.h
index 40f7722..d726c66 100644
--- a/include/perfetto/ext/base/threading/future_combinators.h
+++ b/include/perfetto/ext/base/threading/future_combinators.h
@@ -17,11 +17,11 @@
 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREADING_FUTURE_COMBINATORS_H_
 #define INCLUDE_PERFETTO_EXT_BASE_THREADING_FUTURE_COMBINATORS_H_
 
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "perfetto/base/status.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/threading/poll.h"
 
 namespace perfetto {
@@ -57,17 +57,17 @@
     PERFETTO_CHECK((first_ && second_fn_) || second_);
     if (first_) {
       ASSIGN_OR_RETURN_IF_PENDING_FUTURE(res, first_->Poll(context));
-      first_ = nullopt;
+      first_ = std::nullopt;
       second_ = (*second_fn_)(std::move(res));
-      second_fn_ = base::nullopt;
+      second_fn_ = std::nullopt;
     }
     return second_->Poll(context);
   }
 
  private:
-  Optional<Future<A>> first_;
-  Optional<Function> second_fn_;
-  Optional<Future<B>> second_;
+  std::optional<Future<A>> first_;
+  std::optional<Function> second_fn_;
+  std::optional<Future<B>> second_;
 };
 
 }  // namespace base
diff --git a/include/perfetto/ext/base/threading/poll.h b/include/perfetto/ext/base/threading/poll.h
index 5989361..5a4b7e3 100644
--- a/include/perfetto/ext/base/threading/poll.h
+++ b/include/perfetto/ext/base/threading/poll.h
@@ -17,10 +17,11 @@
 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREADING_POLL_H_
 #define INCLUDE_PERFETTO_EXT_BASE_THREADING_POLL_H_
 
+#include <optional>
+
 #include <variant>
 #include "perfetto/base/flat_set.h"
 #include "perfetto/base/platform_handle.h"
-#include "perfetto/ext/base/optional.h"
 
 namespace perfetto {
 namespace base {
diff --git a/include/perfetto/ext/base/threading/spawn.h b/include/perfetto/ext/base/threading/spawn.h
new file mode 100644
index 0000000..df2f8ec
--- /dev/null
+++ b/include/perfetto/ext/base/threading/spawn.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_THREADING_SPAWN_H_
+#define INCLUDE_PERFETTO_EXT_BASE_THREADING_SPAWN_H_
+
+#include <atomic>
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <mutex>
+#include <optional>
+#include <utility>
+#include <vector>
+
+#include "perfetto/base/compiler.h"
+#include "perfetto/base/flat_set.h"
+#include "perfetto/base/platform_handle.h"
+#include "perfetto/base/task_runner.h"
+#include "perfetto/ext/base/event_fd.h"
+#include "perfetto/ext/base/flat_hash_map.h"
+#include "perfetto/ext/base/thread_checker.h"
+#include "perfetto/ext/base/threading/channel.h"
+#include "perfetto/ext/base/threading/future.h"
+#include "perfetto/ext/base/threading/poll.h"
+#include "perfetto/ext/base/threading/stream.h"
+#include "perfetto/ext/base/threading/stream_combinators.h"
+#include "perfetto/ext/base/threading/util.h"
+#include "perfetto/ext/base/uuid.h"
+#include "perfetto/ext/base/weak_ptr.h"
+
+namespace perfetto {
+namespace base {
+
+class PolledFuture;
+
+// A RAII object which tracks the polling of a Future.
+//
+// When this object is dropped, the backing Future will be cancelled as
+// soon as possible. In practice, the cancellation happens on the TaskRunner
+// thread so there can be some delay.
+class SpawnHandle {
+ public:
+  SpawnHandle(TaskRunner* task_runner, std::function<Future<FVoid>()> fn);
+  ~SpawnHandle();
+
+ private:
+  SpawnHandle(const SpawnHandle&) = delete;
+  SpawnHandle& operator=(const SpawnHandle&) = delete;
+
+  TaskRunner* task_runner_ = nullptr;
+  std::shared_ptr<std::unique_ptr<PolledFuture>> polled_future_;
+};
+
+// Specialization of SpawnHandle used by Futures/Streams which return T.
+//
+// Values of T are returned through a Channel<T> which allows reading these
+// values on a different thread to where the polling happens.
+template <typename T>
+class ResultSpawnHandle {
+ public:
+  ResultSpawnHandle(TaskRunner* task_runner,
+                    std::shared_ptr<Channel<T>> channel,
+                    std::function<Future<FVoid>()> fn)
+      : handle_(task_runner, std::move(fn)), channel_(std::move(channel)) {}
+
+  Channel<T>* channel() const { return channel_.get(); }
+
+ private:
+  SpawnHandle handle_;
+  std::shared_ptr<Channel<T>> channel_;
+};
+
+// "Spawns" a Future<FVoid> on the given TaskRunner and returns an RAII
+// SpawnHandle which can be used to cancel the spawn.
+//
+// Spawning a Future means to poll it to completion. In Perfetto, this is done
+// by using a TaskRunner object to track FD readiness and polling the Future
+// when progress can be made.
+//
+// The returned SpawnHandle should be stashed as it is responsible for the
+// lifetime of the pollling. If the SpawnHandle is dropped, the Future is
+// cancelled and dropped ASAP (this happens on the TaskRunner thread so there
+// can be some delay).
+PERFETTO_WARN_UNUSED_RESULT inline SpawnHandle SpawnFuture(
+    TaskRunner* task_runner,
+    std::function<Future<FVoid>()> fn) {
+  return SpawnHandle(task_runner, std::move(fn));
+}
+
+// Variant of |SpawnFuture| for a Stream<T> allowing returning items of T.
+//
+// See ResultSpawnHandle for how elements from the stream can be consumed.
+template <typename T>
+PERFETTO_WARN_UNUSED_RESULT inline ResultSpawnHandle<T> SpawnResultStream(
+    TaskRunner* task_runner,
+    std::function<Stream<T>()> fn) {
+  class AllVoidCollector : public Collector<FVoid, FVoid> {
+   public:
+    std::optional<FVoid> OnNext(FVoid) override { return std::nullopt; }
+    FVoid OnDone() override { return FVoid(); }
+  };
+  auto channel = std::make_shared<Channel<T>>(4);
+  return ResultSpawnHandle<T>(
+      task_runner, channel, [c = channel, fn = std::move(fn)]() {
+        return fn()
+            .MapFuture([c](T value) {
+              return WriteChannelFuture(c.get(), std::move(value));
+            })
+            .Concat(OnDestroyStream<FVoid>([c]() { c->Close(); }))
+            .Collect(std::unique_ptr<Collector<FVoid, FVoid>>(
+                new AllVoidCollector()));
+      });
+}
+
+// Variant of |SpawnFuture| for a Future<T> allowing returning items of T.
+//
+// See ResultSpawnHandle for how elements from the future can be consumed.
+template <typename T>
+PERFETTO_WARN_UNUSED_RESULT inline ResultSpawnHandle<T> SpawnResultFuture(
+    TaskRunner* task_runner,
+    std::function<Future<T>()> fn) {
+  return SpawnResultStream<T>(task_runner, [fn = std::move(fn)]() {
+    return StreamFromFuture(std::move(fn()));
+  });
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_THREADING_SPAWN_H_
diff --git a/include/perfetto/ext/base/threading/stream_combinators.h b/include/perfetto/ext/base/threading/stream_combinators.h
index 5485139..2b7b69e 100644
--- a/include/perfetto/ext/base/threading/stream_combinators.h
+++ b/include/perfetto/ext/base/threading/stream_combinators.h
@@ -18,11 +18,11 @@
 #define INCLUDE_PERFETTO_EXT_BASE_THREADING_STREAM_COMBINATORS_H_
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "perfetto/base/status.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/status_or.h"
 #include "perfetto/ext/base/threading/future_combinators.h"
 #include "perfetto/ext/base/threading/poll.h"
@@ -87,14 +87,14 @@
       future_ = map_fn_(std::move(res.item()));
     }
     ASSIGN_OR_RETURN_IF_PENDING_FUTURE(res, future_->Poll(context));
-    future_ = nullopt;
+    future_ = std::nullopt;
     return res;
   }
 
  private:
   Stream<T> stream_;
   Function map_fn_;
-  Optional<Future<U>> future_;
+  std::optional<Future<U>> future_;
 };
 
 // Implementation of a StreamPollable for creating a concatenating two streams
@@ -111,13 +111,13 @@
       if (!res.IsDone()) {
         return res.item();
       }
-      first_ = base::nullopt;
+      first_ = std::nullopt;
     }
     return second_.PollNext(context);
   }
 
  private:
-  base::Optional<Stream<T>> first_;
+  std::optional<Stream<T>> first_;
   Stream<T> second_;
 };
 
@@ -140,7 +140,7 @@
       if (!stream) {
         continue;
       }
-      Optional<PollContext> ctx = PollContextForStream(upstream, i);
+      std::optional<PollContext> ctx = PollContextForStream(upstream, i);
       if (!ctx) {
         continue;
       }
@@ -154,7 +154,7 @@
       }
       // StreamPollable has returned EOF. Clear it and the registered handles
       // out.
-      stream = nullopt;
+      stream = std::nullopt;
       ++eof_streams_;
       registered_handles_[i].clear();
     }
@@ -172,8 +172,8 @@
   }
 
  private:
-  Optional<PollContext> PollContextForStream(PollContext* upstream,
-                                             uint32_t stream_idx) {
+  std::optional<PollContext> PollContextForStream(PollContext* upstream,
+                                                  uint32_t stream_idx) {
     FlatSet<PlatformHandle>& state = registered_handles_[stream_idx];
     if (state.empty()) {
       return PollContext(&state, &upstream->ready_handles());
@@ -184,10 +184,10 @@
         return PollContext(&state, &upstream->ready_handles());
       }
     }
-    return base::nullopt;
+    return std::nullopt;
   }
 
-  std::vector<Optional<Stream<T>>> streams_;
+  std::vector<std::optional<Stream<T>>> streams_;
   std::vector<FlatSet<PlatformHandle>> registered_handles_;
   uint32_t eof_streams_ = 0;
 };
@@ -226,12 +226,12 @@
 
   // Receives the next item from a Stream<T>. If the wrapping Future<U> can be
   // completed, returns the a value U which completes that future. Otherwise,
-  // returns base::nullopt.
-  virtual Optional<U> OnNext(T value) = 0;
+  // returns std::nullopt.
+  virtual std::optional<U> OnNext(T value) = 0;
 
   // Called when the stream has completed and returns the |U| which will be
   // used to complete the future. This method will only be called if OnNext
-  // returned nullopt for every element in the stream.
+  // returned std::nullopt for every element in the stream.
   virtual U OnDone() = 0;
 };
 
@@ -250,7 +250,7 @@
       if (res.IsDone()) {
         return collector_->OnDone();
       }
-      Optional<U> collected = collector_->OnNext(std::move(res.item()));
+      std::optional<U> collected = collector_->OnNext(std::move(res.item()));
       if (collected.has_value()) {
         return std::move(collected.value());
       }
@@ -267,8 +267,8 @@
  public:
   ~AllOkCollectorImpl() override;
 
-  Optional<Status> OnNext(Status status) override {
-    return status.ok() ? nullopt : make_optional(std::move(status));
+  std::optional<Status> OnNext(Status status) override {
+    return status.ok() ? std::nullopt : std::make_optional(std::move(status));
   }
   Status OnDone() override { return OkStatus(); }
 };
@@ -277,15 +277,15 @@
 template <typename T>
 class FutureCheckedCollectorImpl : public Collector<T, T> {
  public:
-  Optional<T> OnNext(T value) override {
+  std::optional<T> OnNext(T value) override {
     PERFETTO_CHECK(!prev_value_);
     prev_value_ = value;
-    return nullopt;
+    return std::nullopt;
   }
   T OnDone() override { return *prev_value_; }
 
  private:
-  Optional<T> prev_value_;
+  std::optional<T> prev_value_;
 };
 
 // Implementation for |StatusOrVectorCollector|.
@@ -293,13 +293,13 @@
 class StatusOrVectorCollectorImpl
     : public Collector<base::StatusOr<T>, base::StatusOr<std::vector<T>>> {
  public:
-  Optional<base::StatusOr<std::vector<T>>> OnNext(
+  std::optional<base::StatusOr<std::vector<T>>> OnNext(
       base::StatusOr<T> val_or) override {
     if (!val_or.ok()) {
-      return make_optional(val_or.status());
+      return std::make_optional(val_or.status());
     }
     values_.emplace_back(std::move(val_or.value()));
-    return nullopt;
+    return std::nullopt;
   }
   base::StatusOr<std::vector<T>> OnDone() override {
     return std::move(values_);
diff --git a/include/perfetto/ext/base/threading/thread_pool.h b/include/perfetto/ext/base/threading/thread_pool.h
index 1a4b153..e08baaa 100644
--- a/include/perfetto/ext/base/threading/thread_pool.h
+++ b/include/perfetto/ext/base/threading/thread_pool.h
@@ -21,11 +21,11 @@
 #include <functional>
 #include <list>
 #include <mutex>
+#include <optional>
 #include <thread>
 #include <vector>
 
 #include "perfetto/base/task_runner.h"
-#include "perfetto/ext/base/optional.h"
 
 namespace perfetto {
 namespace base {
diff --git a/include/perfetto/ext/base/threading/util.h b/include/perfetto/ext/base/threading/util.h
index 34dccdb..7b2465e 100644
--- a/include/perfetto/ext/base/threading/util.h
+++ b/include/perfetto/ext/base/threading/util.h
@@ -19,13 +19,13 @@
 
 #include <functional>
 #include <memory>
+#include <optional>
 #include <type_traits>
 #include <utility>
 #include <vector>
 
 #include "perfetto/base/status.h"
 #include "perfetto/base/task_runner.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/threading/channel.h"
 #include "perfetto/ext/base/threading/future.h"
 #include "perfetto/ext/base/threading/poll.h"
@@ -104,7 +104,7 @@
 
 // Creates a Stream<T> which yields the result of executing |fn| on |pool|
 // repeatedly. The returned stream only completes when |fn| returns
-// base::nullopt.
+// std::nullopt.
 //
 // The intended usage of this function is to schedule CPU intensive work on a
 // background thread pool and receive regular "updates" on the progress by:
@@ -112,13 +112,13 @@
 // b) returning some indication of progress/partial results through |T|.
 template <typename T>
 Stream<T> RunOnThreadPool(ThreadPool* pool,
-                          std::function<base::Optional<T>()> fn) {
+                          std::function<std::optional<T>()> fn) {
   class RunOnPoolImpl : public StreamPollable<T> {
    public:
     explicit RunOnPoolImpl(ThreadPool* pool,
-                           std::function<base::Optional<T>()> fn)
+                           std::function<std::optional<T>()> fn)
         : pool_(pool),
-          fn_(std::make_shared<std::function<base::Optional<T>()>>(
+          fn_(std::make_shared<std::function<std::optional<T>()>>(
               std::move(fn))),
           channel_(new Channel<T>(1)),
           channel_stream_(ReadChannelStream(channel_.get())) {
@@ -150,7 +150,7 @@
     }
 
     ThreadPool* pool_ = nullptr;
-    std::shared_ptr<std::function<base::Optional<T>()>> fn_;
+    std::shared_ptr<std::function<std::optional<T>()>> fn_;
     std::shared_ptr<Channel<T>> channel_;
     base::Stream<T> channel_stream_;
   };
@@ -166,9 +166,9 @@
 Future<T> RunOnceOnThreadPool(ThreadPool* pool, std::function<T()> fn) {
   return RunOnThreadPool<T>(
              pool,
-             [done = false, fn = std::move(fn)]() mutable -> base::Optional<T> {
+             [done = false, fn = std::move(fn)]() mutable -> std::optional<T> {
                if (done) {
-                 return base::nullopt;
+                 return std::nullopt;
                }
                done = true;
                return fn();
diff --git a/include/perfetto/ext/base/uuid.h b/include/perfetto/ext/base/uuid.h
index 3b3d5d5..2bf5f5b 100644
--- a/include/perfetto/ext/base/uuid.h
+++ b/include/perfetto/ext/base/uuid.h
@@ -17,12 +17,12 @@
 #ifndef INCLUDE_PERFETTO_EXT_BASE_UUID_H_
 #define INCLUDE_PERFETTO_EXT_BASE_UUID_H_
 
+#include <string.h>
 #include <array>
 #include <cstdint>
+#include <optional>
 #include <string>
 
-#include "perfetto/ext/base/optional.h"
-
 namespace perfetto {
 namespace base {
 
diff --git a/include/perfetto/ext/trace_processor/importers/memory_tracker/graph_processor.h b/include/perfetto/ext/trace_processor/importers/memory_tracker/graph_processor.h
index f7b02e7..2d702f7 100644
--- a/include/perfetto/ext/trace_processor/importers/memory_tracker/graph_processor.h
+++ b/include/perfetto/ext/trace_processor/importers/memory_tracker/graph_processor.h
@@ -80,7 +80,7 @@
   static void PropagateNumericsAndDiagnosticsRecursively(
       GlobalNodeGraph::Node* node);
 
-  static base::Optional<uint64_t> AggregateSizeForDescendantNode(
+  static std::optional<uint64_t> AggregateSizeForDescendantNode(
       GlobalNodeGraph::Node* root,
       GlobalNodeGraph::Node* descendant);
 
diff --git a/include/perfetto/ext/tracing/core/basic_types.h b/include/perfetto/ext/tracing/core/basic_types.h
index ac75b4d..0950fe8 100644
--- a/include/perfetto/ext/tracing/core/basic_types.h
+++ b/include/perfetto/ext/tracing/core/basic_types.h
@@ -76,6 +76,11 @@
 
 constexpr uint32_t kDefaultFlushTimeoutMs = 5000;
 
+// The special id 0xffff..ffff represents the tracing session with the highest
+// bugreport score. This is used for CloneSession(kBugreportSessionId).
+constexpr TracingSessionID kBugreportSessionId =
+    static_cast<TracingSessionID>(-1);
+
 }  // namespace perfetto
 
 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
diff --git a/include/perfetto/ext/tracing/core/tracing_service.h b/include/perfetto/ext/tracing/core/tracing_service.h
index 68dc086..82e53f7 100644
--- a/include/perfetto/ext/tracing/core/tracing_service.h
+++ b/include/perfetto/ext/tracing/core/tracing_service.h
@@ -42,9 +42,6 @@
 class SharedMemoryArbiter;
 class TraceWriter;
 
-// Exposed for testing.
-std::string GetBugreportPath();
-
 // TODO: for the moment this assumes that all the calls happen on the same
 // thread/sequence. Not sure this will be the case long term in Chrome.
 
@@ -192,6 +189,8 @@
   // Clones an existing tracing session and attaches to it. The session is
   // cloned in read-only mode and can only be used to read a snapshot of an
   // existing tracing session. Will invoke Consumer::OnSessionCloned().
+  // If TracingSessionID == kBugreportSessionId (0xff...ff) the session with the
+  // highest bugreport score is cloned (if any exists).
   // TODO(primiano): make pure virtual after various 3way patches.
   virtual void CloneSession(TracingSessionID);
 
diff --git a/infra/perfetto.dev/src/gen_sql_tables_reference.js b/infra/perfetto.dev/src/gen_sql_tables_reference.js
index 9af1d32..2f77cea 100644
--- a/infra/perfetto.dev/src/gen_sql_tables_reference.js
+++ b/infra/perfetto.dev/src/gen_sql_tables_reference.js
@@ -111,7 +111,7 @@
     if (m = line.match(/^\s*C\(([^,]+)\s*,\s*(\w+)/)) {
       const col = getOrCreateColumn(/*name=*/ m[2]);
       col.type = m[1];
-      if (m = col.type.match(/Optional<(.*)>/)) {
+      if (m = col.type.match(/std::optional<(.*)>/)) {
         col.type = m[1];
         col.optional = true;
       }
@@ -168,7 +168,7 @@
     // C(StringPool::Id, name)                                    \
     // C(StackProfileMappingTable::Id, mapping)                   \
     // C(int64_t, rel_pc)                                         \
-    // C(base::Optional<uint32_t>, symbol_set_id)
+    // C(std::optional<uint32_t>, symbol_set_id)
     //
     // Where PERFETTO_TP_STACK_PROFILE_FRAME_DEF is |tableDefName|.
     let pattern = `(^[ ]*//.*\n)*`;
diff --git a/protos/perfetto/config/chrome/BUILD.gn b/protos/perfetto/config/chrome/BUILD.gn
index 4f44718..4397cfc 100644
--- a/protos/perfetto/config/chrome/BUILD.gn
+++ b/protos/perfetto/config/chrome/BUILD.gn
@@ -15,6 +15,8 @@
 import("../../../../gn/perfetto.gni")
 import("../../../../gn/proto_library.gni")
 
-perfetto_proto_library("@TYPE@") {
-  sources = [ "chrome_config.proto" ]
+perfetto_proto_library("scenario_descriptor") {
+  proto_generators = [ "descriptor" ]
+  generate_descriptor = "scenario_config.descriptor"
+  sources = [ "scenario_config.proto" ]
 }
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index 3673dd0..2eb9d1a 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -868,7 +868,7 @@
 // Begin of protos/perfetto/config/profiling/heapprofd_config.proto
 
 // Configuration for go/heapprofd.
-// Next id: 27
+// Next id: 28
 message HeapprofdConfig {
   message ContinuousDumpConfig {
     // ms to wait before first dump.
@@ -1550,7 +1550,6 @@
   WTF_OCCURRED = 80;
   LOW_MEM_REPORTED = 81;
   GENERIC_ATOM = 82;
-  KEY_VALUE_PAIRS_ATOM = 83;
   VIBRATOR_STATE_CHANGED = 84;
   DEFERRED_JOB_STATS_REPORTED = 85;
   THERMAL_THROTTLING = 86;
@@ -1799,6 +1798,7 @@
   ART_DATUM_REPORTED = 332;
   DEVICE_ROTATED = 333;
   SIM_SPECIFIC_SETTINGS_RESTORED = 334;
+  TEXT_CLASSIFIER_DOWNLOAD_REPORTED = 335;
   PIN_STORAGE_EVENT = 336;
   FACE_DOWN_REPORTED = 337;
   BLUETOOTH_HAL_CRASH_REASON_REPORTED = 338;
@@ -1843,9 +1843,12 @@
   PRIVACY_SENSOR_TOGGLE_INTERACTION = 381;
   PRIVACY_TOGGLE_DIALOG_INTERACTION = 382;
   APP_SEARCH_OPTIMIZE_STATS_REPORTED = 383;
+  NON_A11Y_TOOL_SERVICE_WARNING_REPORT = 384;
+  APP_SEARCH_SET_SCHEMA_STATS_REPORTED = 385;
   APP_COMPAT_STATE_CHANGED = 386;
   SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED = 387;
   SPLITSCREEN_UI_CHANGED = 388;
+  NETWORK_DNS_HANDSHAKE_REPORTED = 389;
   BLUETOOTH_CODE_PATH_COUNTER = 390;
   BLUETOOTH_LE_BATCH_SCAN_REPORT_DELAY = 392;
   ACCESSIBILITY_FLOATING_MENU_UI_CHANGED = 393;
@@ -1853,21 +1856,122 @@
   NEURALNETWORKS_EXECUTION_COMPLETED = 395;
   NEURALNETWORKS_COMPILATION_FAILED = 396;
   NEURALNETWORKS_EXECUTION_FAILED = 397;
+  CONTEXT_HUB_BOOTED = 398;
+  CONTEXT_HUB_RESTARTED = 399;
+  CONTEXT_HUB_LOADED_NANOAPP_SNAPSHOT_REPORTED = 400;
+  CHRE_CODE_DOWNLOAD_TRANSACTED = 401;
+  UWB_SESSION_INITED = 402;
+  UWB_SESSION_CLOSED = 403;
+  UWB_FIRST_RANGING_RECEIVED = 404;
+  UWB_RANGING_MEASUREMENT_RECEIVED = 405;
+  TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED = 406;
+  TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED = 407;
+  CLIPBOARD_CLEARED = 408;
   VM_CREATION_REQUESTED = 409;
+  NEARBY_DEVICE_SCAN_STATE_CHANGED = 410;
   CAMERA_COMPAT_CONTROL_EVENT_REPORTED = 411;
-  TRACING_SERVICE_REPORT_EVENT = 424;
+  APPLICATION_LOCALES_CHANGED = 412;
+  MEDIAMETRICS_AUDIOTRACKSTATUS_REPORTED = 413;
+  FOLD_STATE_DURATION_REPORTED = 414;
+  LOCATION_TIME_ZONE_PROVIDER_CONTROLLER_STATE_CHANGED = 415;
+  DISPLAY_HBM_STATE_CHANGED = 416;
+  DISPLAY_HBM_BRIGHTNESS_CHANGED = 417;
+  PERSISTENT_URI_PERMISSIONS_FLUSHED = 418;
   EARLY_BOOT_COMP_OS_ARTIFACTS_CHECK_REPORTED = 419;
-  ISOLATED_COMPILATION_SCHEDULED = 457;
-  ISOLATED_COMPILATION_ENDED = 458;
-  TELEPHONY_ANOMALY_DETECTED = 461;
+  VBMETA_DIGEST_REPORTED = 420;
+  APEX_INFO_GATHERED = 421;
+  PVM_INFO_GATHERED = 422;
+  WEAR_SETTINGS_UI_INTERACTED = 423;
+  TRACING_SERVICE_REPORT_EVENT = 424;
+  MEDIAMETRICS_AUDIORECORDSTATUS_REPORTED = 425;
+  LAUNCHER_LATENCY = 426;
+  DROPBOX_ENTRY_DROPPED = 427;
+  WIFI_P2P_CONNECTION_REPORTED = 428;
+  GAME_STATE_CHANGED = 429;
   HOTWORD_DETECTOR_CREATE_REQUESTED = 430;
   HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED = 431;
   HOTWORD_DETECTION_SERVICE_RESTARTED = 432;
   HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED = 433;
   HOTWORD_DETECTOR_EVENTS = 434;
+  BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED = 437;
+  CONTACTS_INDEXER_UPDATE_STATS_REPORTED = 440;
+  APP_BACKGROUND_RESTRICTIONS_INFO = 441;
+  MMS_SMS_PROVIDER_GET_THREAD_ID_FAILED = 442;
+  MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED = 443;
+  PERMISSION_REMINDER_NOTIFICATION_INTERACTED = 444;
+  RECENT_PERMISSION_DECISIONS_INTERACTED = 445;
+  GNSS_PSDS_DOWNLOAD_REPORTED = 446;
+  LE_AUDIO_CONNECTION_SESSION_REPORTED = 447;
+  LE_AUDIO_BROADCAST_SESSION_REPORTED = 448;
+  DREAM_UI_EVENT_REPORTED = 449;
+  TASK_MANAGER_EVENT_REPORTED = 450;
+  CDM_ASSOCIATION_ACTION = 451;
+  MAGNIFICATION_TRIPLE_TAP_AND_HOLD_ACTIVATED_SESSION_REPORTED = 452;
+  MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED = 453;
+  ACCESSIBILITY_TEXT_READING_OPTIONS_CHANGED = 454;
+  WIFI_SETUP_FAILURE_CRASH_REPORTED = 455;
+  UWB_DEVICE_ERROR_REPORTED = 456;
+  ISOLATED_COMPILATION_SCHEDULED = 457;
+  ISOLATED_COMPILATION_ENDED = 458;
+  ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE = 459;
+  TELEPHONY_ANOMALY_DETECTED = 461;
+  LETTERBOX_POSITION_CHANGED = 462;
   REMOTE_KEY_PROVISIONING_ATTEMPT = 463;
   REMOTE_KEY_PROVISIONING_NETWORK_INFO = 464;
   REMOTE_KEY_PROVISIONING_TIMING = 465;
+  MEDIAOUTPUT_OP_INTERACTION_REPORT = 466;
+  BACKGROUND_DEXOPT_JOB_ENDED = 467;
+  SYNC_EXEMPTION_OCCURRED = 468;
+  AUTOFILL_PRESENTATION_EVENT_REPORTED = 469;
+  DOCK_STATE_CHANGED = 470;
+  BROADCAST_DELIVERY_EVENT_REPORTED = 475;
+  SERVICE_REQUEST_EVENT_REPORTED = 476;
+  PROVIDER_ACQUISITION_EVENT_REPORTED = 477;
+  BLUETOOTH_DEVICE_NAME_REPORTED = 478;
+  VIBRATION_REPORTED = 487;
+  UWB_RANGING_START = 489;
+  DISPLAY_BRIGHTNESS_CHANGED = 494;
+  ACTIVITY_ACTION_BLOCKED = 495;
+  NETWORK_DNS_SERVER_SUPPORT_REPORTED = 504;
+  VM_BOOTED = 505;
+  VM_EXITED = 506;
+  AMBIENT_BRIGHTNESS_STATS_REPORTED = 507;
+  MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED = 508;
+  MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED = 509;
+  MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED = 510;
+  MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED = 511;
+  HEARING_AID_INFO_REPORTED = 513;
+  DEVICE_WIDE_JOB_CONSTRAINT_CHANGED = 514;
+  IWLAN_SETUP_DATA_CALL_RESULT_REPORTED = 519;
+  IWLAN_PDN_DISCONNECTED_REASON_REPORTED = 520;
+  AIRPLANE_MODE_SESSION_REPORTED = 521;
+  VM_CPU_STATUS_REPORTED = 522;
+  VM_MEM_STATUS_REPORTED = 523;
+  DEFAULT_NETWORK_REMATCH_INFO = 525;
+  NETWORK_SELECTION_PERFORMANCE = 526;
+  NETWORK_NSD_REPORTED = 527;
+  BLUETOOTH_DISCONNECTION_REASON_REPORTED = 529;
+  BLUETOOTH_LOCAL_VERSIONS_REPORTED = 530;
+  BLUETOOTH_REMOTE_SUPPORTED_FEATURES_REPORTED = 531;
+  BLUETOOTH_LOCAL_SUPPORTED_FEATURES_REPORTED = 532;
+  BLUETOOTH_GATT_APP_INFO = 533;
+  BRIGHTNESS_CONFIGURATION_UPDATED = 534;
+  LAUNCHER_IMPRESSION_EVENT = 547;
+  ODSIGN_REPORTED = 548;
+  ART_DEVICE_DATUM_REPORTED = 550;
+  NETWORK_SLICE_SESSION_ENDED = 558;
+  NETWORK_SLICE_DAILY_DATA_USAGE_REPORTED = 559;
+  NFC_TAG_TYPE_OCCURRED = 560;
+  NFC_AID_CONFLICT_OCCURRED = 561;
+  NFC_READER_CONFLICT_OCCURRED = 562;
+  ART_DATUM_DELTA_REPORTED = 565;
+  MEDIA_DRM_CREATED = 568;
+  MEDIA_DRM_ERRORED = 569;
+  MEDIA_DRM_SESSION_OPENED = 570;
+  MEDIA_DRM_SESSION_CLOSED = 571;
+  PERFORMANCE_HINT_SESSION_REPORTED = 574;
+  HOTWORD_AUDIO_EGRESS_EVENT_REPORTED = 578;
+  NETWORK_VALIDATION_FAILURE_STATS_DAILY_REPORTED = 601;
   WIFI_BYTES_TRANSFER = 10000;
   WIFI_BYTES_TRANSFER_BY_FG_BG = 10001;
   MOBILE_BYTES_TRANSFER = 10002;
@@ -1906,8 +2010,6 @@
   CPU_TIME_PER_THREAD_FREQ = 10037;
   ON_DEVICE_POWER_MEASUREMENT = 10038;
   DEVICE_CALCULATED_POWER_USE = 10039;
-  DEVICE_CALCULATED_POWER_BLAME_UID = 10040;
-  DEVICE_CALCULATED_POWER_BLAME_OTHER = 10041;
   PROCESS_MEMORY_HIGH_WATER_MARK = 10042;
   BATTERY_LEVEL = 10043;
   BUILD_INFORMATION = 10044;
@@ -1992,8 +2094,11 @@
   KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO = 10123;
   RKP_ERROR_STATS = 10124;
   KEYSTORE2_CRASH_STATS = 10125;
+  VENDOR_APEX_INFO = 10126;
   ACCESSIBILITY_SHORTCUT_STATS = 10127;
   ACCESSIBILITY_FLOATING_MENU_STATS = 10128;
+  DATA_USAGE_BYTES_TRANSFER_V2 = 10129;
+  MEDIA_CAPABILITIES = 10130;
   CAR_WATCHDOG_SYSTEM_IO_USAGE_SUMMARY = 10131;
   CAR_WATCHDOG_UID_IO_USAGE_SUMMARY = 10132;
   IMS_REGISTRATION_FEATURE_TAG_STATS = 10133;
@@ -2009,7 +2114,25 @@
   UCE_EVENT_STATS = 10143;
   PRESENCE_NOTIFY_EVENT = 10144;
   GBA_EVENT = 10145;
+  PER_SIM_STATUS = 10146;
+  GPU_WORK_PER_UID = 10147;
+  PERSISTENT_URI_PERMISSIONS_AMOUNT_PER_PACKAGE = 10148;
+  SIGNED_PARTITION_INFO = 10149;
+  PINNED_FILE_SIZES_PER_PACKAGE = 10150;
+  PENDING_INTENTS_PER_PACKAGE = 10151;
+  USER_INFO = 10152;
+  TELEPHONY_NETWORK_REQUESTS_V2 = 10153;
+  DEVICE_TELEPHONY_PROPERTIES = 10154;
   REMOTE_KEY_PROVISIONING_ERROR_COUNTS = 10155;
+  INCOMING_MMS = 10157;
+  OUTGOING_MMS = 10158;
+  MULTI_USER_INFO = 10160;
+  NETWORK_BPF_MAP_INFO = 10161;
+  CONNECTIVITY_STATE_SAMPLE = 10163;
+  NETWORK_SELECTION_REMATCH_REASONS_INFO = 10164;
+  NETWORK_SLICE_REQUEST_COUNT = 10168;
+  ADPF_SYSTEM_COMPONENT_INFO = 10173;
+  NOTIFICATION_MEMORY_USE = 10174;
 }
 
 // End of protos/perfetto/config/statsd/atom_ids.proto
diff --git a/protos/perfetto/config/profiling/heapprofd_config.proto b/protos/perfetto/config/profiling/heapprofd_config.proto
index 2636e06..bb0a700 100644
--- a/protos/perfetto/config/profiling/heapprofd_config.proto
+++ b/protos/perfetto/config/profiling/heapprofd_config.proto
@@ -19,7 +19,7 @@
 package perfetto.protos;
 
 // Configuration for go/heapprofd.
-// Next id: 27
+// Next id: 28
 message HeapprofdConfig {
   message ContinuousDumpConfig {
     // ms to wait before first dump.
diff --git a/protos/perfetto/config/statsd/atom_ids.proto b/protos/perfetto/config/statsd/atom_ids.proto
index 2d987b4..4eed73b 100644
--- a/protos/perfetto/config/statsd/atom_ids.proto
+++ b/protos/perfetto/config/statsd/atom_ids.proto
@@ -99,7 +99,6 @@
   WTF_OCCURRED = 80;
   LOW_MEM_REPORTED = 81;
   GENERIC_ATOM = 82;
-  KEY_VALUE_PAIRS_ATOM = 83;
   VIBRATOR_STATE_CHANGED = 84;
   DEFERRED_JOB_STATS_REPORTED = 85;
   THERMAL_THROTTLING = 86;
@@ -348,6 +347,7 @@
   ART_DATUM_REPORTED = 332;
   DEVICE_ROTATED = 333;
   SIM_SPECIFIC_SETTINGS_RESTORED = 334;
+  TEXT_CLASSIFIER_DOWNLOAD_REPORTED = 335;
   PIN_STORAGE_EVENT = 336;
   FACE_DOWN_REPORTED = 337;
   BLUETOOTH_HAL_CRASH_REASON_REPORTED = 338;
@@ -392,9 +392,12 @@
   PRIVACY_SENSOR_TOGGLE_INTERACTION = 381;
   PRIVACY_TOGGLE_DIALOG_INTERACTION = 382;
   APP_SEARCH_OPTIMIZE_STATS_REPORTED = 383;
+  NON_A11Y_TOOL_SERVICE_WARNING_REPORT = 384;
+  APP_SEARCH_SET_SCHEMA_STATS_REPORTED = 385;
   APP_COMPAT_STATE_CHANGED = 386;
   SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED = 387;
   SPLITSCREEN_UI_CHANGED = 388;
+  NETWORK_DNS_HANDSHAKE_REPORTED = 389;
   BLUETOOTH_CODE_PATH_COUNTER = 390;
   BLUETOOTH_LE_BATCH_SCAN_REPORT_DELAY = 392;
   ACCESSIBILITY_FLOATING_MENU_UI_CHANGED = 393;
@@ -402,21 +405,122 @@
   NEURALNETWORKS_EXECUTION_COMPLETED = 395;
   NEURALNETWORKS_COMPILATION_FAILED = 396;
   NEURALNETWORKS_EXECUTION_FAILED = 397;
+  CONTEXT_HUB_BOOTED = 398;
+  CONTEXT_HUB_RESTARTED = 399;
+  CONTEXT_HUB_LOADED_NANOAPP_SNAPSHOT_REPORTED = 400;
+  CHRE_CODE_DOWNLOAD_TRANSACTED = 401;
+  UWB_SESSION_INITED = 402;
+  UWB_SESSION_CLOSED = 403;
+  UWB_FIRST_RANGING_RECEIVED = 404;
+  UWB_RANGING_MEASUREMENT_RECEIVED = 405;
+  TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED = 406;
+  TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED = 407;
+  CLIPBOARD_CLEARED = 408;
   VM_CREATION_REQUESTED = 409;
+  NEARBY_DEVICE_SCAN_STATE_CHANGED = 410;
   CAMERA_COMPAT_CONTROL_EVENT_REPORTED = 411;
-  TRACING_SERVICE_REPORT_EVENT = 424;
+  APPLICATION_LOCALES_CHANGED = 412;
+  MEDIAMETRICS_AUDIOTRACKSTATUS_REPORTED = 413;
+  FOLD_STATE_DURATION_REPORTED = 414;
+  LOCATION_TIME_ZONE_PROVIDER_CONTROLLER_STATE_CHANGED = 415;
+  DISPLAY_HBM_STATE_CHANGED = 416;
+  DISPLAY_HBM_BRIGHTNESS_CHANGED = 417;
+  PERSISTENT_URI_PERMISSIONS_FLUSHED = 418;
   EARLY_BOOT_COMP_OS_ARTIFACTS_CHECK_REPORTED = 419;
-  ISOLATED_COMPILATION_SCHEDULED = 457;
-  ISOLATED_COMPILATION_ENDED = 458;
-  TELEPHONY_ANOMALY_DETECTED = 461;
+  VBMETA_DIGEST_REPORTED = 420;
+  APEX_INFO_GATHERED = 421;
+  PVM_INFO_GATHERED = 422;
+  WEAR_SETTINGS_UI_INTERACTED = 423;
+  TRACING_SERVICE_REPORT_EVENT = 424;
+  MEDIAMETRICS_AUDIORECORDSTATUS_REPORTED = 425;
+  LAUNCHER_LATENCY = 426;
+  DROPBOX_ENTRY_DROPPED = 427;
+  WIFI_P2P_CONNECTION_REPORTED = 428;
+  GAME_STATE_CHANGED = 429;
   HOTWORD_DETECTOR_CREATE_REQUESTED = 430;
   HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED = 431;
   HOTWORD_DETECTION_SERVICE_RESTARTED = 432;
   HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED = 433;
   HOTWORD_DETECTOR_EVENTS = 434;
+  BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED = 437;
+  CONTACTS_INDEXER_UPDATE_STATS_REPORTED = 440;
+  APP_BACKGROUND_RESTRICTIONS_INFO = 441;
+  MMS_SMS_PROVIDER_GET_THREAD_ID_FAILED = 442;
+  MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED = 443;
+  PERMISSION_REMINDER_NOTIFICATION_INTERACTED = 444;
+  RECENT_PERMISSION_DECISIONS_INTERACTED = 445;
+  GNSS_PSDS_DOWNLOAD_REPORTED = 446;
+  LE_AUDIO_CONNECTION_SESSION_REPORTED = 447;
+  LE_AUDIO_BROADCAST_SESSION_REPORTED = 448;
+  DREAM_UI_EVENT_REPORTED = 449;
+  TASK_MANAGER_EVENT_REPORTED = 450;
+  CDM_ASSOCIATION_ACTION = 451;
+  MAGNIFICATION_TRIPLE_TAP_AND_HOLD_ACTIVATED_SESSION_REPORTED = 452;
+  MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED = 453;
+  ACCESSIBILITY_TEXT_READING_OPTIONS_CHANGED = 454;
+  WIFI_SETUP_FAILURE_CRASH_REPORTED = 455;
+  UWB_DEVICE_ERROR_REPORTED = 456;
+  ISOLATED_COMPILATION_SCHEDULED = 457;
+  ISOLATED_COMPILATION_ENDED = 458;
+  ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE = 459;
+  TELEPHONY_ANOMALY_DETECTED = 461;
+  LETTERBOX_POSITION_CHANGED = 462;
   REMOTE_KEY_PROVISIONING_ATTEMPT = 463;
   REMOTE_KEY_PROVISIONING_NETWORK_INFO = 464;
   REMOTE_KEY_PROVISIONING_TIMING = 465;
+  MEDIAOUTPUT_OP_INTERACTION_REPORT = 466;
+  BACKGROUND_DEXOPT_JOB_ENDED = 467;
+  SYNC_EXEMPTION_OCCURRED = 468;
+  AUTOFILL_PRESENTATION_EVENT_REPORTED = 469;
+  DOCK_STATE_CHANGED = 470;
+  BROADCAST_DELIVERY_EVENT_REPORTED = 475;
+  SERVICE_REQUEST_EVENT_REPORTED = 476;
+  PROVIDER_ACQUISITION_EVENT_REPORTED = 477;
+  BLUETOOTH_DEVICE_NAME_REPORTED = 478;
+  VIBRATION_REPORTED = 487;
+  UWB_RANGING_START = 489;
+  DISPLAY_BRIGHTNESS_CHANGED = 494;
+  ACTIVITY_ACTION_BLOCKED = 495;
+  NETWORK_DNS_SERVER_SUPPORT_REPORTED = 504;
+  VM_BOOTED = 505;
+  VM_EXITED = 506;
+  AMBIENT_BRIGHTNESS_STATS_REPORTED = 507;
+  MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED = 508;
+  MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED = 509;
+  MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED = 510;
+  MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED = 511;
+  HEARING_AID_INFO_REPORTED = 513;
+  DEVICE_WIDE_JOB_CONSTRAINT_CHANGED = 514;
+  IWLAN_SETUP_DATA_CALL_RESULT_REPORTED = 519;
+  IWLAN_PDN_DISCONNECTED_REASON_REPORTED = 520;
+  AIRPLANE_MODE_SESSION_REPORTED = 521;
+  VM_CPU_STATUS_REPORTED = 522;
+  VM_MEM_STATUS_REPORTED = 523;
+  DEFAULT_NETWORK_REMATCH_INFO = 525;
+  NETWORK_SELECTION_PERFORMANCE = 526;
+  NETWORK_NSD_REPORTED = 527;
+  BLUETOOTH_DISCONNECTION_REASON_REPORTED = 529;
+  BLUETOOTH_LOCAL_VERSIONS_REPORTED = 530;
+  BLUETOOTH_REMOTE_SUPPORTED_FEATURES_REPORTED = 531;
+  BLUETOOTH_LOCAL_SUPPORTED_FEATURES_REPORTED = 532;
+  BLUETOOTH_GATT_APP_INFO = 533;
+  BRIGHTNESS_CONFIGURATION_UPDATED = 534;
+  LAUNCHER_IMPRESSION_EVENT = 547;
+  ODSIGN_REPORTED = 548;
+  ART_DEVICE_DATUM_REPORTED = 550;
+  NETWORK_SLICE_SESSION_ENDED = 558;
+  NETWORK_SLICE_DAILY_DATA_USAGE_REPORTED = 559;
+  NFC_TAG_TYPE_OCCURRED = 560;
+  NFC_AID_CONFLICT_OCCURRED = 561;
+  NFC_READER_CONFLICT_OCCURRED = 562;
+  ART_DATUM_DELTA_REPORTED = 565;
+  MEDIA_DRM_CREATED = 568;
+  MEDIA_DRM_ERRORED = 569;
+  MEDIA_DRM_SESSION_OPENED = 570;
+  MEDIA_DRM_SESSION_CLOSED = 571;
+  PERFORMANCE_HINT_SESSION_REPORTED = 574;
+  HOTWORD_AUDIO_EGRESS_EVENT_REPORTED = 578;
+  NETWORK_VALIDATION_FAILURE_STATS_DAILY_REPORTED = 601;
   WIFI_BYTES_TRANSFER = 10000;
   WIFI_BYTES_TRANSFER_BY_FG_BG = 10001;
   MOBILE_BYTES_TRANSFER = 10002;
@@ -455,8 +559,6 @@
   CPU_TIME_PER_THREAD_FREQ = 10037;
   ON_DEVICE_POWER_MEASUREMENT = 10038;
   DEVICE_CALCULATED_POWER_USE = 10039;
-  DEVICE_CALCULATED_POWER_BLAME_UID = 10040;
-  DEVICE_CALCULATED_POWER_BLAME_OTHER = 10041;
   PROCESS_MEMORY_HIGH_WATER_MARK = 10042;
   BATTERY_LEVEL = 10043;
   BUILD_INFORMATION = 10044;
@@ -541,8 +643,11 @@
   KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO = 10123;
   RKP_ERROR_STATS = 10124;
   KEYSTORE2_CRASH_STATS = 10125;
+  VENDOR_APEX_INFO = 10126;
   ACCESSIBILITY_SHORTCUT_STATS = 10127;
   ACCESSIBILITY_FLOATING_MENU_STATS = 10128;
+  DATA_USAGE_BYTES_TRANSFER_V2 = 10129;
+  MEDIA_CAPABILITIES = 10130;
   CAR_WATCHDOG_SYSTEM_IO_USAGE_SUMMARY = 10131;
   CAR_WATCHDOG_UID_IO_USAGE_SUMMARY = 10132;
   IMS_REGISTRATION_FEATURE_TAG_STATS = 10133;
@@ -558,5 +663,23 @@
   UCE_EVENT_STATS = 10143;
   PRESENCE_NOTIFY_EVENT = 10144;
   GBA_EVENT = 10145;
+  PER_SIM_STATUS = 10146;
+  GPU_WORK_PER_UID = 10147;
+  PERSISTENT_URI_PERMISSIONS_AMOUNT_PER_PACKAGE = 10148;
+  SIGNED_PARTITION_INFO = 10149;
+  PINNED_FILE_SIZES_PER_PACKAGE = 10150;
+  PENDING_INTENTS_PER_PACKAGE = 10151;
+  USER_INFO = 10152;
+  TELEPHONY_NETWORK_REQUESTS_V2 = 10153;
+  DEVICE_TELEPHONY_PROPERTIES = 10154;
   REMOTE_KEY_PROVISIONING_ERROR_COUNTS = 10155;
+  INCOMING_MMS = 10157;
+  OUTGOING_MMS = 10158;
+  MULTI_USER_INFO = 10160;
+  NETWORK_BPF_MAP_INFO = 10161;
+  CONNECTIVITY_STATE_SAMPLE = 10163;
+  NETWORK_SELECTION_REMATCH_REASONS_INFO = 10164;
+  NETWORK_SLICE_REQUEST_COUNT = 10168;
+  ADPF_SYSTEM_COMPONENT_INFO = 10173;
+  NOTIFICATION_MEMORY_USE = 10174;
 }
diff --git a/protos/perfetto/ipc/consumer_port.proto b/protos/perfetto/ipc/consumer_port.proto
index aa7fc93..d5a4025 100644
--- a/protos/perfetto/ipc/consumer_port.proto
+++ b/protos/perfetto/ipc/consumer_port.proto
@@ -270,7 +270,7 @@
 // or something failed.
 message SaveTraceForBugreportResponse {
   // If true, an eligible the trace was saved into a known location (on Android
-  // /data/misc/perfetto-traces, see GetBugreportPath()).
+  // /data/misc/perfetto-traces, see GetBugreportTracePath()).
   // If false no trace with bugreport_score > 0 was found or an error occurred.
   // see |msg| in that case for details about the failure.
   optional bool success = 1;
@@ -279,6 +279,8 @@
 
 // Arguments for rpc CloneSession.
 message CloneSessionRequest {
+  // The session ID to clone. If session_id == kBugreportSessionId (0xff...ff)
+  // the session with the highest bugreport score is cloned (if any exists).
   optional uint64 session_id = 1;
 }
 
diff --git a/protos/perfetto/trace/perfetto/tracing_service_event.proto b/protos/perfetto/trace/perfetto/tracing_service_event.proto
index 04923dc..0573be0 100644
--- a/protos/perfetto/trace/perfetto/tracing_service_event.proto
+++ b/protos/perfetto/trace/perfetto/tracing_service_event.proto
@@ -60,6 +60,8 @@
     // the contents are routed onto the bugreport file. This event flags the
     // situation explicitly. Traces that contain this marker should be discarded
     // by test infrastructures / pipelines.
+    // Deprecated since Android U, where --save-for-bugreport uses
+    // non-destructive cloning.
     bool seized_for_bugreport = 6;
   }
 }
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 74d2f17..3efbb44 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -868,7 +868,7 @@
 // Begin of protos/perfetto/config/profiling/heapprofd_config.proto
 
 // Configuration for go/heapprofd.
-// Next id: 27
+// Next id: 28
 message HeapprofdConfig {
   message ContinuousDumpConfig {
     // ms to wait before first dump.
@@ -1550,7 +1550,6 @@
   WTF_OCCURRED = 80;
   LOW_MEM_REPORTED = 81;
   GENERIC_ATOM = 82;
-  KEY_VALUE_PAIRS_ATOM = 83;
   VIBRATOR_STATE_CHANGED = 84;
   DEFERRED_JOB_STATS_REPORTED = 85;
   THERMAL_THROTTLING = 86;
@@ -1799,6 +1798,7 @@
   ART_DATUM_REPORTED = 332;
   DEVICE_ROTATED = 333;
   SIM_SPECIFIC_SETTINGS_RESTORED = 334;
+  TEXT_CLASSIFIER_DOWNLOAD_REPORTED = 335;
   PIN_STORAGE_EVENT = 336;
   FACE_DOWN_REPORTED = 337;
   BLUETOOTH_HAL_CRASH_REASON_REPORTED = 338;
@@ -1843,9 +1843,12 @@
   PRIVACY_SENSOR_TOGGLE_INTERACTION = 381;
   PRIVACY_TOGGLE_DIALOG_INTERACTION = 382;
   APP_SEARCH_OPTIMIZE_STATS_REPORTED = 383;
+  NON_A11Y_TOOL_SERVICE_WARNING_REPORT = 384;
+  APP_SEARCH_SET_SCHEMA_STATS_REPORTED = 385;
   APP_COMPAT_STATE_CHANGED = 386;
   SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED = 387;
   SPLITSCREEN_UI_CHANGED = 388;
+  NETWORK_DNS_HANDSHAKE_REPORTED = 389;
   BLUETOOTH_CODE_PATH_COUNTER = 390;
   BLUETOOTH_LE_BATCH_SCAN_REPORT_DELAY = 392;
   ACCESSIBILITY_FLOATING_MENU_UI_CHANGED = 393;
@@ -1853,21 +1856,122 @@
   NEURALNETWORKS_EXECUTION_COMPLETED = 395;
   NEURALNETWORKS_COMPILATION_FAILED = 396;
   NEURALNETWORKS_EXECUTION_FAILED = 397;
+  CONTEXT_HUB_BOOTED = 398;
+  CONTEXT_HUB_RESTARTED = 399;
+  CONTEXT_HUB_LOADED_NANOAPP_SNAPSHOT_REPORTED = 400;
+  CHRE_CODE_DOWNLOAD_TRANSACTED = 401;
+  UWB_SESSION_INITED = 402;
+  UWB_SESSION_CLOSED = 403;
+  UWB_FIRST_RANGING_RECEIVED = 404;
+  UWB_RANGING_MEASUREMENT_RECEIVED = 405;
+  TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED = 406;
+  TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED = 407;
+  CLIPBOARD_CLEARED = 408;
   VM_CREATION_REQUESTED = 409;
+  NEARBY_DEVICE_SCAN_STATE_CHANGED = 410;
   CAMERA_COMPAT_CONTROL_EVENT_REPORTED = 411;
-  TRACING_SERVICE_REPORT_EVENT = 424;
+  APPLICATION_LOCALES_CHANGED = 412;
+  MEDIAMETRICS_AUDIOTRACKSTATUS_REPORTED = 413;
+  FOLD_STATE_DURATION_REPORTED = 414;
+  LOCATION_TIME_ZONE_PROVIDER_CONTROLLER_STATE_CHANGED = 415;
+  DISPLAY_HBM_STATE_CHANGED = 416;
+  DISPLAY_HBM_BRIGHTNESS_CHANGED = 417;
+  PERSISTENT_URI_PERMISSIONS_FLUSHED = 418;
   EARLY_BOOT_COMP_OS_ARTIFACTS_CHECK_REPORTED = 419;
-  ISOLATED_COMPILATION_SCHEDULED = 457;
-  ISOLATED_COMPILATION_ENDED = 458;
-  TELEPHONY_ANOMALY_DETECTED = 461;
+  VBMETA_DIGEST_REPORTED = 420;
+  APEX_INFO_GATHERED = 421;
+  PVM_INFO_GATHERED = 422;
+  WEAR_SETTINGS_UI_INTERACTED = 423;
+  TRACING_SERVICE_REPORT_EVENT = 424;
+  MEDIAMETRICS_AUDIORECORDSTATUS_REPORTED = 425;
+  LAUNCHER_LATENCY = 426;
+  DROPBOX_ENTRY_DROPPED = 427;
+  WIFI_P2P_CONNECTION_REPORTED = 428;
+  GAME_STATE_CHANGED = 429;
   HOTWORD_DETECTOR_CREATE_REQUESTED = 430;
   HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED = 431;
   HOTWORD_DETECTION_SERVICE_RESTARTED = 432;
   HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED = 433;
   HOTWORD_DETECTOR_EVENTS = 434;
+  BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED = 437;
+  CONTACTS_INDEXER_UPDATE_STATS_REPORTED = 440;
+  APP_BACKGROUND_RESTRICTIONS_INFO = 441;
+  MMS_SMS_PROVIDER_GET_THREAD_ID_FAILED = 442;
+  MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED = 443;
+  PERMISSION_REMINDER_NOTIFICATION_INTERACTED = 444;
+  RECENT_PERMISSION_DECISIONS_INTERACTED = 445;
+  GNSS_PSDS_DOWNLOAD_REPORTED = 446;
+  LE_AUDIO_CONNECTION_SESSION_REPORTED = 447;
+  LE_AUDIO_BROADCAST_SESSION_REPORTED = 448;
+  DREAM_UI_EVENT_REPORTED = 449;
+  TASK_MANAGER_EVENT_REPORTED = 450;
+  CDM_ASSOCIATION_ACTION = 451;
+  MAGNIFICATION_TRIPLE_TAP_AND_HOLD_ACTIVATED_SESSION_REPORTED = 452;
+  MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED = 453;
+  ACCESSIBILITY_TEXT_READING_OPTIONS_CHANGED = 454;
+  WIFI_SETUP_FAILURE_CRASH_REPORTED = 455;
+  UWB_DEVICE_ERROR_REPORTED = 456;
+  ISOLATED_COMPILATION_SCHEDULED = 457;
+  ISOLATED_COMPILATION_ENDED = 458;
+  ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE = 459;
+  TELEPHONY_ANOMALY_DETECTED = 461;
+  LETTERBOX_POSITION_CHANGED = 462;
   REMOTE_KEY_PROVISIONING_ATTEMPT = 463;
   REMOTE_KEY_PROVISIONING_NETWORK_INFO = 464;
   REMOTE_KEY_PROVISIONING_TIMING = 465;
+  MEDIAOUTPUT_OP_INTERACTION_REPORT = 466;
+  BACKGROUND_DEXOPT_JOB_ENDED = 467;
+  SYNC_EXEMPTION_OCCURRED = 468;
+  AUTOFILL_PRESENTATION_EVENT_REPORTED = 469;
+  DOCK_STATE_CHANGED = 470;
+  BROADCAST_DELIVERY_EVENT_REPORTED = 475;
+  SERVICE_REQUEST_EVENT_REPORTED = 476;
+  PROVIDER_ACQUISITION_EVENT_REPORTED = 477;
+  BLUETOOTH_DEVICE_NAME_REPORTED = 478;
+  VIBRATION_REPORTED = 487;
+  UWB_RANGING_START = 489;
+  DISPLAY_BRIGHTNESS_CHANGED = 494;
+  ACTIVITY_ACTION_BLOCKED = 495;
+  NETWORK_DNS_SERVER_SUPPORT_REPORTED = 504;
+  VM_BOOTED = 505;
+  VM_EXITED = 506;
+  AMBIENT_BRIGHTNESS_STATS_REPORTED = 507;
+  MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED = 508;
+  MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED = 509;
+  MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED = 510;
+  MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED = 511;
+  HEARING_AID_INFO_REPORTED = 513;
+  DEVICE_WIDE_JOB_CONSTRAINT_CHANGED = 514;
+  IWLAN_SETUP_DATA_CALL_RESULT_REPORTED = 519;
+  IWLAN_PDN_DISCONNECTED_REASON_REPORTED = 520;
+  AIRPLANE_MODE_SESSION_REPORTED = 521;
+  VM_CPU_STATUS_REPORTED = 522;
+  VM_MEM_STATUS_REPORTED = 523;
+  DEFAULT_NETWORK_REMATCH_INFO = 525;
+  NETWORK_SELECTION_PERFORMANCE = 526;
+  NETWORK_NSD_REPORTED = 527;
+  BLUETOOTH_DISCONNECTION_REASON_REPORTED = 529;
+  BLUETOOTH_LOCAL_VERSIONS_REPORTED = 530;
+  BLUETOOTH_REMOTE_SUPPORTED_FEATURES_REPORTED = 531;
+  BLUETOOTH_LOCAL_SUPPORTED_FEATURES_REPORTED = 532;
+  BLUETOOTH_GATT_APP_INFO = 533;
+  BRIGHTNESS_CONFIGURATION_UPDATED = 534;
+  LAUNCHER_IMPRESSION_EVENT = 547;
+  ODSIGN_REPORTED = 548;
+  ART_DEVICE_DATUM_REPORTED = 550;
+  NETWORK_SLICE_SESSION_ENDED = 558;
+  NETWORK_SLICE_DAILY_DATA_USAGE_REPORTED = 559;
+  NFC_TAG_TYPE_OCCURRED = 560;
+  NFC_AID_CONFLICT_OCCURRED = 561;
+  NFC_READER_CONFLICT_OCCURRED = 562;
+  ART_DATUM_DELTA_REPORTED = 565;
+  MEDIA_DRM_CREATED = 568;
+  MEDIA_DRM_ERRORED = 569;
+  MEDIA_DRM_SESSION_OPENED = 570;
+  MEDIA_DRM_SESSION_CLOSED = 571;
+  PERFORMANCE_HINT_SESSION_REPORTED = 574;
+  HOTWORD_AUDIO_EGRESS_EVENT_REPORTED = 578;
+  NETWORK_VALIDATION_FAILURE_STATS_DAILY_REPORTED = 601;
   WIFI_BYTES_TRANSFER = 10000;
   WIFI_BYTES_TRANSFER_BY_FG_BG = 10001;
   MOBILE_BYTES_TRANSFER = 10002;
@@ -1906,8 +2010,6 @@
   CPU_TIME_PER_THREAD_FREQ = 10037;
   ON_DEVICE_POWER_MEASUREMENT = 10038;
   DEVICE_CALCULATED_POWER_USE = 10039;
-  DEVICE_CALCULATED_POWER_BLAME_UID = 10040;
-  DEVICE_CALCULATED_POWER_BLAME_OTHER = 10041;
   PROCESS_MEMORY_HIGH_WATER_MARK = 10042;
   BATTERY_LEVEL = 10043;
   BUILD_INFORMATION = 10044;
@@ -1992,8 +2094,11 @@
   KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO = 10123;
   RKP_ERROR_STATS = 10124;
   KEYSTORE2_CRASH_STATS = 10125;
+  VENDOR_APEX_INFO = 10126;
   ACCESSIBILITY_SHORTCUT_STATS = 10127;
   ACCESSIBILITY_FLOATING_MENU_STATS = 10128;
+  DATA_USAGE_BYTES_TRANSFER_V2 = 10129;
+  MEDIA_CAPABILITIES = 10130;
   CAR_WATCHDOG_SYSTEM_IO_USAGE_SUMMARY = 10131;
   CAR_WATCHDOG_UID_IO_USAGE_SUMMARY = 10132;
   IMS_REGISTRATION_FEATURE_TAG_STATS = 10133;
@@ -2009,7 +2114,25 @@
   UCE_EVENT_STATS = 10143;
   PRESENCE_NOTIFY_EVENT = 10144;
   GBA_EVENT = 10145;
+  PER_SIM_STATUS = 10146;
+  GPU_WORK_PER_UID = 10147;
+  PERSISTENT_URI_PERMISSIONS_AMOUNT_PER_PACKAGE = 10148;
+  SIGNED_PARTITION_INFO = 10149;
+  PINNED_FILE_SIZES_PER_PACKAGE = 10150;
+  PENDING_INTENTS_PER_PACKAGE = 10151;
+  USER_INFO = 10152;
+  TELEPHONY_NETWORK_REQUESTS_V2 = 10153;
+  DEVICE_TELEPHONY_PROPERTIES = 10154;
   REMOTE_KEY_PROVISIONING_ERROR_COUNTS = 10155;
+  INCOMING_MMS = 10157;
+  OUTGOING_MMS = 10158;
+  MULTI_USER_INFO = 10160;
+  NETWORK_BPF_MAP_INFO = 10161;
+  CONNECTIVITY_STATE_SAMPLE = 10163;
+  NETWORK_SELECTION_REMATCH_REASONS_INFO = 10164;
+  NETWORK_SLICE_REQUEST_COUNT = 10168;
+  ADPF_SYSTEM_COMPONENT_INFO = 10173;
+  NOTIFICATION_MEMORY_USE = 10174;
 }
 
 // End of protos/perfetto/config/statsd/atom_ids.proto
@@ -10249,6 +10372,8 @@
     // the contents are routed onto the bugreport file. This event flags the
     // situation explicitly. Traces that contain this marker should be discarded
     // by test infrastructures / pipelines.
+    // Deprecated since Android U, where --save-for-bugreport uses
+    // non-destructive cloning.
     bool seized_for_bugreport = 6;
   }
 }
@@ -10326,10 +10451,14 @@
     // Index corresponding to the state
     optional int32 state_index = 2;
 
-    // Name of the entity
+    // Name of the entity. This is device-specific, determined by the PowerStats
+    // HAL, and cannot be configured by the user. An example would be
+    // "Bluetooth".
     optional string entity_name = 3;
 
-    // Name of the state
+    // Name of the state. This is device-specific, determined by the PowerStats
+    // HAL, and cannot be configured by the user. An example would be
+    // "Active".
     optional string state_name = 4;
   }
 
@@ -10337,7 +10466,6 @@
   repeated PowerEntityState power_entity_state = 1;
 
   message StateResidency {
-    // Index corresponding to PowerEntityState.entity_index
     optional int32 entity_index = 1;
 
     // Index corresponding to PowerEntityState.state_index
diff --git a/protos/perfetto/trace/power/android_entity_state_residency.proto b/protos/perfetto/trace/power/android_entity_state_residency.proto
index 6ca767d..9f1283f 100644
--- a/protos/perfetto/trace/power/android_entity_state_residency.proto
+++ b/protos/perfetto/trace/power/android_entity_state_residency.proto
@@ -25,10 +25,14 @@
     // Index corresponding to the state
     optional int32 state_index = 2;
 
-    // Name of the entity
+    // Name of the entity. This is device-specific, determined by the PowerStats
+    // HAL, and cannot be configured by the user. An example would be
+    // "Bluetooth".
     optional string entity_name = 3;
 
-    // Name of the state
+    // Name of the state. This is device-specific, determined by the PowerStats
+    // HAL, and cannot be configured by the user. An example would be
+    // "Active".
     optional string state_name = 4;
   }
 
@@ -36,7 +40,6 @@
   repeated PowerEntityState power_entity_state = 1;
 
   message StateResidency {
-    // Index corresponding to PowerEntityState.entity_index
     optional int32 entity_index = 1;
 
     // Index corresponding to PowerEntityState.state_index
diff --git a/python/generators/trace_processor_table/public.py b/python/generators/trace_processor_table/public.py
index f6db0de..abd0aec 100644
--- a/python/generators/trace_processor_table/public.py
+++ b/python/generators/trace_processor_table/public.py
@@ -22,7 +22,7 @@
 from typing import Union
 
 
-@dataclass
+@dataclass(frozen=True)
 class CppColumnType:
   """
   The type of a column on a C++ table.
@@ -40,10 +40,12 @@
   """
   NONE = 0
   SORTED = auto()
+  HIDDEN = auto()
+  DENSE = auto()
   SET_ID = auto()
 
 
-@dataclass
+@dataclass(frozen=True)
 class Column:
   """
   Representation of a column of a C++ table.
@@ -57,13 +59,8 @@
   type: CppColumnType
   flags: ColumnFlag = ColumnFlag.NONE
 
-  # Private fields used by the generator. Do not set these manually.
-  _is_auto_added_id: bool = False
-  _is_auto_added_type: bool = False
-  _is_self_column: bool = True
 
-
-@dataclass
+@dataclass(frozen=True)
 class ColumnDoc:
   """
   Documentation for the C++ table column.
@@ -79,7 +76,7 @@
   joinable: Optional[str] = None
 
 
-@dataclass
+@dataclass(frozen=True)
 class TableDoc:
   """
   Documentation for the C++ table.
@@ -93,8 +90,8 @@
     groups.
     columns: Documentation for each table column.
     skip_id_and_type: Skips publishing these columns in the documentation.
-    Should only be used when these columns
-    are not meaningful or are aliased to something better.
+    Should only be used when these columns are not meaningful or are aliased to
+    something better.
   """
   doc: str
   group: str
@@ -102,7 +99,7 @@
   skip_id_and_type: bool = False
 
 
-@dataclass
+@dataclass(frozen=True)
 class WrappingSqlView:
   """
   Specifies information about SQL view wrapping a table.
@@ -116,7 +113,7 @@
   view_name: str
 
 
-@dataclass
+@dataclass(frozen=True)
 class Table:
   """
   Representation of of a C++ table.
@@ -125,63 +122,64 @@
     class_name: Name of the C++ table class.
     sql_name: Name of the table in SQL.
     columns: The columns in this table.
-    tabledoc: Documentation for this table. Can include
-    documentation overrides for auto-added columns (i.e.
-    id and type) and aliases added in |wrapping_sql_view|.
-    parent: The parent ("super-class") table for this table.
+    tabledoc: Documentation for this table. Can include documentation overrides
+    for auto-added columns (i.e. id and type) and aliases added in
+    |wrapping_sql_view|.
+    parent: The parent table for this table. All columns are inherited from the
+    specified table.
     wrapping_sql_view: See |WrappingSqlView|.
   """
   class_name: str
   sql_name: str
   columns: List[Column]
-  tabledoc: TableDoc
   parent: Optional['Table'] = None
+  tabledoc: Optional[TableDoc] = None
   wrapping_sql_view: Optional[WrappingSqlView] = None
 
 
-@dataclass
+@dataclass(frozen=True)
 class CppInt64(CppColumnType):
   """Represents the int64_t C++ type."""
 
 
-@dataclass
+@dataclass(frozen=True)
 class CppUint32(CppColumnType):
   """Represents the uint32_t C++ type."""
 
 
-@dataclass
+@dataclass(frozen=True)
 class CppInt32(CppColumnType):
   """Represents the int32_t C++ type."""
 
 
-@dataclass
+@dataclass(frozen=True)
 class CppDouble(CppColumnType):
   """Represents the double C++ type."""
 
 
-@dataclass
+@dataclass(frozen=True)
 class CppString(CppColumnType):
   """Represents the StringPool::Id C++ type."""
 
 
-@dataclass
+@dataclass(frozen=True)
 class CppOptional(CppColumnType):
   """Represents the base::Optional C++ type."""
   inner: CppColumnType
 
 
-@dataclass
+@dataclass(frozen=True)
 class CppTableId(CppColumnType):
   """Represents the Table::Id C++ type."""
   table: Table
 
 
-@dataclass
+@dataclass(frozen=True)
 class CppSelfTableId(CppColumnType):
   """Represents the Id C++ type."""
 
 
-@dataclass
+@dataclass(frozen=True)
 class Alias(CppColumnType):
   """Represents a column which aliases another column.
 
diff --git a/python/generators/trace_processor_table/serialize.py b/python/generators/trace_processor_table/serialize.py
index 0401703..0a8715c 100644
--- a/python/generators/trace_processor_table/serialize.py
+++ b/python/generators/trace_processor_table/serialize.py
@@ -16,24 +16,26 @@
 from typing import Optional
 
 from python.generators.trace_processor_table.public import Alias
-from python.generators.trace_processor_table.public import Column
 from python.generators.trace_processor_table.public import ColumnFlag
-from python.generators.trace_processor_table.public import Table
-from python.generators.trace_processor_table.util import parse_type
-from python.generators.trace_processor_table.util import typed_column_type
-from python.generators.trace_processor_table.util import to_cpp_flags
+from python.generators.trace_processor_table.util import ParsedTable
+from python.generators.trace_processor_table.util import ParsedColumn
 
 
 class ColumnSerializer:
   """Functions for serializing a single Column in a table into C++."""
 
-  def __init__(self, table: Table, col_index: int):
+  def __init__(self, table: ParsedTable, column: ParsedColumn, col_index: int):
     self.col_index = col_index
-    self.col = table.columns[col_index]
+    self.parsed_col = column
+    self.col = self.parsed_col.column
     self.name = self.col.name
     self.flags = self.col.flags
-    self.typed_column_type = typed_column_type(table, self.col)
-    self.cpp_type = parse_type(table, self.col.type).cpp_type_with_optionality()
+    self.typed_column_type = table.typed_column_type(self.parsed_col)
+    self.cpp_type = table.parse_type(self.col.type).cpp_type_with_optionality()
+
+    self.is_implicit_id = self.parsed_col.is_implicit_id
+    self.is_implicit_type = self.parsed_col.is_implicit_type
+    self.is_ancestor = self.parsed_col.is_ancestor
 
   def colindex(self) -> str:
     return f'    static constexpr uint32_t {self.name} = {self.col_index};'
@@ -42,28 +44,28 @@
     return f'    using {self.name} = {self.typed_column_type};'
 
   def row_field(self) -> Optional[str]:
-    if self.col._is_auto_added_id or self.col._is_auto_added_type:
+    if self.is_implicit_id or self.is_implicit_type:
       return None
-    if not self.col._is_self_column:
+    if self.is_ancestor:
       return None
     return f'    {self.cpp_type} {self.name};'
 
   def row_param(self) -> Optional[str]:
-    if self.col._is_auto_added_id or self.col._is_auto_added_type:
+    if self.is_implicit_id or self.is_implicit_type:
       return None
     return f'{self.cpp_type} in_{self.name} = {{}}'
 
   def parent_row_initializer(self) -> Optional[str]:
-    if self.col._is_auto_added_id or self.col._is_auto_added_type:
+    if self.is_implicit_id or self.is_implicit_type:
       return None
-    if self.col._is_self_column:
+    if not self.is_ancestor:
       return None
     return f'std::move(in_{self.name})'
 
   def row_initializer(self) -> Optional[str]:
-    if self.col._is_auto_added_id or self.col._is_auto_added_type:
+    if self.is_implicit_id or self.is_implicit_type:
       return None
-    if not self.col._is_self_column:
+    if self.is_ancestor:
       return None
     return f'{self.name}(std::move(in_{self.name}))'
 
@@ -73,7 +75,7 @@
     }}'''
 
   def row_ref_getter(self) -> Optional[str]:
-    if self.col._is_auto_added_id or self.col._is_auto_added_type:
+    if self.is_implicit_id or self.is_implicit_type:
       return None
     return f'''void set_{self.name}(
         ColumnType::{self.name}::non_optional_type v) {{
@@ -81,9 +83,9 @@
     }}'''
 
   def flag(self) -> Optional[str]:
-    if self.col._is_auto_added_id or self.col._is_auto_added_type:
+    if self.is_implicit_id or self.is_implicit_type:
       return None
-    if not self.col._is_self_column:
+    if self.is_ancestor:
       return None
     default = f'ColumnType::{self.name}::default_flags()'
     if self.flags == ColumnFlag.NONE:
@@ -95,19 +97,19 @@
     '''
 
   def storage_init(self) -> Optional[str]:
-    if self.col._is_auto_added_id or self.col._is_auto_added_type:
+    if self.is_implicit_id or self.is_implicit_type:
       return None
-    if not self.col._is_self_column:
+    if self.is_ancestor:
       return None
 
     storage = f'ColumnStorage<ColumnType::{self.name}::stored_type>'
-    # TODO(lalitm): add support for dense columns.
-    return f'''{self.name}_({storage}::Create<false>())'''
+    dense = str(ColumnFlag.DENSE in self.flags).lower()
+    return f'''{self.name}_({storage}::Create<{dense}>())'''
 
   def column_init(self) -> Optional[str]:
-    if self.col._is_auto_added_id or self.col._is_auto_added_type:
+    if self.is_implicit_id or self.is_implicit_type:
       return None
-    if not self.col._is_self_column:
+    if self.is_ancestor:
       return None
     return f'''
     columns_.emplace_back("{self.name}", &{self.name}_, ColumnFlag::{self.name},
@@ -116,16 +118,16 @@
     '''
 
   def shrink_to_fit(self) -> Optional[str]:
-    if self.col._is_auto_added_id:
+    if self.is_implicit_id:
       return None
-    if not self.col._is_self_column:
+    if self.is_ancestor:
       return None
     return f'    {self.name}_.ShrinkToFit();'
 
   def append(self) -> Optional[str]:
-    if self.col._is_auto_added_id or self.col._is_auto_added_type:
+    if self.is_implicit_id or self.is_implicit_type:
       return None
-    if not self.col._is_self_column:
+    if self.is_ancestor:
       return None
     return f'    mutable_{self.name}()->Append(std::move(row.{self.name}));'
 
@@ -138,7 +140,7 @@
   '''
 
   def mutable_accessor(self) -> Optional[str]:
-    if self.col._is_auto_added_id or self.col._is_auto_added_type:
+    if self.is_implicit_id or self.is_implicit_type:
       return None
     return f'''
   {self.typed_column_type}* mutable_{self.name}() {{
@@ -148,30 +150,69 @@
   '''
 
   def storage(self) -> Optional[str]:
-    if self.col._is_auto_added_id or self.col._is_auto_added_type:
+    if self.is_implicit_id or self.is_implicit_type:
       return None
-    if not self.col._is_self_column:
+    if self.is_ancestor:
       return None
     name = self.name
     return f'  ColumnStorage<ColumnType::{name}::stored_type> {name}_;'
 
+  def iterator_getter(self) -> Optional[str]:
+    name = self.name
+    return f'''
+    ColumnType::{self.name}::type {name}() const {{
+      const auto& col = table_->{name}();
+      return col.GetAtIdx(its_[col.overlay_index()].index());
+    }}
+    '''
+
+  def iterator_setter(self) -> Optional[str]:
+    if self.is_implicit_id or self.is_implicit_type:
+      return None
+    return f'''
+      void set_{self.name}(ColumnType::{self.name}::non_optional_type v) {{
+        auto* col = mutable_table_->mutable_{self.name}();
+        col->SetAtIdx(its_[col->overlay_index()].index(), v);
+      }}
+    '''
+
+  def static_schema(self) -> Optional[str]:
+    if self.is_implicit_id or self.is_implicit_type:
+      return None
+    return f'''
+      schema.columns.emplace_back(Table::Schema::Column{{
+          "{self.name}", ColumnType::{self.name}::SqlValueType(), false,
+          {str(ColumnFlag.SORTED in self.flags).lower()},
+          {str(ColumnFlag.HIDDEN in self.flags).lower()},
+          {str(ColumnFlag.SET_ID in self.flags).lower()}}});
+    '''
+
+  def row_eq(self) -> Optional[str]:
+    if self.is_implicit_id or self.is_implicit_type:
+      return None
+    return f'ColumnType::{self.name}::Equals({self.name}, other.{self.name})'
+
 
 class TableSerializer(object):
   """Functions for seralizing a single Table into C++."""
 
-  def __init__(self, table: Table):
-    self.table = table
-    self.table_name = table.class_name
+  def __init__(self, parsed: ParsedTable):
+    self.table = parsed.table
+    self.table_name = parsed.table.class_name
     self.column_serializers = []
 
-    if table.parent:
-      self.parent_class_name = table.parent.class_name
+    if parsed.table.parent:
+      self.parent_class_name = parsed.table.parent.class_name
     else:
       self.parent_class_name = 'macros_internal::RootParentTable'
 
-    self.column_serializers = [
-        ColumnSerializer(table, i) for i in range(len(table.columns))
-    ]
+    self.column_serializers = []
+    for c in parsed.columns:
+      # Aliases should be ignored as they are handled in SQL currently.
+      if isinstance(c.column.type, Alias):
+        continue
+      self.column_serializers.append(
+          ColumnSerializer(parsed, c, len(self.column_serializers)))
 
   def foreach_col(self, serialize_fn, delimiter='\n') -> str:
     lines = []
@@ -202,6 +243,7 @@
         ColumnSerializer.parent_row_initializer, delimiter=', ')
     row_init = self.foreach_col(
         ColumnSerializer.row_initializer, delimiter=',\n          ')
+    row_eq = self.foreach_col(ColumnSerializer.row_eq, delimiter=' &&\n       ')
     return f'''
   struct Row : public {self.parent_class_name}::Row {{
     Row({param},
@@ -211,6 +253,10 @@
       type_ = "{self.table.sql_name}";
     }}
     {self.foreach_col(ColumnSerializer.row_field)}
+
+    bool operator==(const {self.table_name}::Row& other) const {{
+      return type() == other.type() && {row_eq};
+    }}
   }};
     '''
 
@@ -288,6 +334,55 @@
     type_.Append(string_pool_->InternString(row.type()));
       '''
 
+  def const_iterator(self) -> str:
+    iterator_getters = self.foreach_col(
+        ColumnSerializer.iterator_getter, delimiter='\n')
+    return f'''
+  class ConstIterator;
+  class ConstIterator : public macros_internal::AbstractConstIterator<
+    ConstIterator, {self.table_name}, RowNumber, ConstRowReference> {{
+   public:
+    {iterator_getters}
+
+   protected:
+    explicit ConstIterator(const {self.table_name}* table,
+                           std::vector<ColumnStorageOverlay> overlays)
+        : AbstractConstIterator(table, std::move(overlays)) {{}}
+
+    uint32_t CurrentRowNumber() const {{
+      return its_.back().index();
+    }}
+
+   private:
+    friend class {self.table_name};
+    friend class AbstractConstIterator;
+  }};
+      '''
+
+  def iterator(self) -> str:
+    iterator_setters = self.foreach_col(
+        ColumnSerializer.iterator_setter, delimiter='\n')
+    return f'''
+  class Iterator : public ConstIterator {{
+    public:
+    {iterator_setters}
+
+    RowReference row_reference() const {{
+      return RowReference(mutable_table_, CurrentRowNumber());
+    }}
+
+    private:
+    friend class {self.table_name};
+
+    explicit Iterator({self.table_name}* table,
+                      std::vector<ColumnStorageOverlay> overlays)
+        : ConstIterator(table, std::move(overlays)),
+          mutable_table_(table) {{}}
+
+    {self.table_name}* mutable_table_ = nullptr;
+  }};
+      '''
+
   def serialize(self) -> str:
     return f'''
 class {self.table_name} : public macros_internal::MacroTable {{
@@ -300,10 +395,6 @@
     {self.foreach_col(ColumnSerializer.coltype_enum)}
   }};
   {self.row_struct().strip()}
-  struct IdAndRow {{
-    uint32_t row;
-    Id id;
-  }};
   struct ColumnFlag {{
     {self.foreach_col(ColumnSerializer.flag)}
   }};
@@ -324,24 +415,62 @@
   {self.const_row_reference_struct().strip()}
   {self.row_reference_struct().strip()}
 
+  {self.const_iterator().strip()}
+  {self.iterator().strip()}
+
+  struct IdAndRow {{
+    Id id;
+    uint32_t row;
+    RowReference row_reference;
+    RowNumber row_number;
+  }};
+
   {self.constructor().strip()}
   ~{self.table_name}() override;
 
   static const char* Name() {{ return "{self.table.sql_name}"; }}
 
+  static Table::Schema ComputeStaticSchema() {{
+    Table::Schema schema;
+    schema.columns.emplace_back(Table::Schema::Column{{
+        "id", SqlValue::Type::kLong, true, true, false, false}});
+    schema.columns.emplace_back(Table::Schema::Column{{
+        "type", SqlValue::Type::kString, false, false, false, false}});
+    {self.foreach_col(ColumnSerializer.static_schema)}
+    return schema;
+  }}
+
+  ConstIterator IterateRows() const {{
+    return ConstIterator(this, CopyOverlays());
+  }}
+
+  Iterator IterateRows() {{ return Iterator(this, CopyOverlays()); }}
+
+  ConstIterator FilterToIterator(
+      const std::vector<Constraint>& cs,
+      RowMap::OptimizeFor opt = RowMap::OptimizeFor::kMemory) const {{
+    return ConstIterator(this, FilterAndApplyToOverlays(cs, opt));
+  }}
+
+  Iterator FilterToIterator(
+      const std::vector<Constraint>& cs,
+      RowMap::OptimizeFor opt = RowMap::OptimizeFor::kMemory) {{
+    return Iterator(this, FilterAndApplyToOverlays(cs, opt));
+  }}
+
   void ShrinkToFit() {{
     {self.foreach_col(ColumnSerializer.shrink_to_fit)}
   }}
 
-  base::Optional<ConstRowReference> FindById(Id find_id) const {{
-    base::Optional<uint32_t> row = id().IndexOf(find_id);
-    return row ? base::make_optional(ConstRowReference(this, *row))
-               : base::nullopt;
+  std::optional<ConstRowReference> FindById(Id find_id) const {{
+    std::optional<uint32_t> row = id().IndexOf(find_id);
+    return row ? std::make_optional(ConstRowReference(this, *row))
+               : std::nullopt;
   }}
 
-  base::Optional<RowReference> FindById(Id find_id) {{
-    base::Optional<uint32_t> row = id().IndexOf(find_id);
-    return row ? base::make_optional(RowReference(this, *row)) : base::nullopt;
+  std::optional<RowReference> FindById(Id find_id) {{
+    std::optional<uint32_t> row = id().IndexOf(find_id);
+    return row ? std::make_optional(RowReference(this, *row)) : std::nullopt;
   }}
 
   IdAndRow Insert(const Row& row) {{
@@ -349,7 +478,8 @@
     {self.insert_common().strip()}
     {self.foreach_col(ColumnSerializer.append)}
     UpdateSelfOverlayAfterInsert();
-    return IdAndRow{{row_number, std::move(id)}};
+    return IdAndRow{{std::move(id), row_number, RowReference(this, row_number),
+                     RowNumber(row_number)}};
   }}
 
   {self.foreach_col(ColumnSerializer.accessor)}
@@ -363,7 +493,7 @@
   '''.strip('\n')
 
 
-def serialize_header(ifdef_guard: str, tables: List[Table],
+def serialize_header(ifdef_guard: str, tables: List[ParsedTable],
                      include_paths: List[str]) -> str:
   """Serializes a table header file containing the given set of tables."""
   include_paths_str = '\n'.join([f'#include "{i}"' for i in include_paths])
@@ -388,3 +518,22 @@
 
 #endif  // {ifdef_guard}
   '''.strip()
+
+
+def to_cpp_flags(raw_flag: ColumnFlag) -> str:
+  """Converts a ColumnFlag to the C++ flags which it represents
+
+  It is not valid to call this function with ColumnFlag.NONE as in this case
+  defaults for that column should be implicitly used."""
+
+  assert raw_flag != ColumnFlag.NONE
+  flags = []
+  if ColumnFlag.SORTED in raw_flag:
+    flags.append('Column::Flag::kSorted')
+  if ColumnFlag.HIDDEN in raw_flag:
+    flags.append('Column::Flag::kHidden')
+  if ColumnFlag.DENSE in raw_flag:
+    flags.append('Column::Flag::kDense')
+  if ColumnFlag.SET_ID in raw_flag:
+    flags.append('Column::Flag::kSetId')
+  return ' | '.join(flags)
diff --git a/python/generators/trace_processor_table/util.py b/python/generators/trace_processor_table/util.py
index 04c4b34..015f02c 100644
--- a/python/generators/trace_processor_table/util.py
+++ b/python/generators/trace_processor_table/util.py
@@ -14,6 +14,7 @@
 
 import dataclasses
 from dataclasses import dataclass
+import runpy
 from typing import Dict
 from typing import List
 from typing import Set
@@ -25,6 +26,7 @@
 from python.generators.trace_processor_table.public import ColumnDoc
 from python.generators.trace_processor_table.public import ColumnFlag
 from python.generators.trace_processor_table.public import CppColumnType
+from python.generators.trace_processor_table.public import CppDouble
 from python.generators.trace_processor_table.public import CppInt32
 from python.generators.trace_processor_table.public import CppInt64
 from python.generators.trace_processor_table.public import CppOptional
@@ -54,155 +56,210 @@
     # directly into vectors using them) and it was decided this behaviour was
     # too expensive in engineering cost to fix given the trivial benefit. For
     # this reason, continue to maintain this illusion.
-    if self.id_table and (self.id_table.class_name == 'ThreadTable' or
-                          self.id_table.class_name == 'ProcessTable'):
+    if self.id_table and self.id_table.class_name in ('ThreadTable',
+                                                      'ProcessTable'):
       cpp_type = 'uint32_t'
     else:
       cpp_type = self.cpp_type
     if self.is_optional:
-      return f'base::Optional<{cpp_type}>'
+      return f'std::optional<{cpp_type}>'
     return cpp_type
 
 
-def public_sql_name_for_table(table: Table) -> str:
+@dataclass(frozen=True)
+class ParsedColumn:
+  """Representation of a column parsed from a Python definition."""
+
+  column: Column
+  doc: Optional[ColumnDoc]
+
+  # Whether this column is the implicit "id" column which is added by while
+  # parsing the tables rather than by the user.
+  is_implicit_id: bool = False
+
+  # Whether this column is the implicit "type" column which is added by while
+  # parsing the tables rather than by the user.
+  is_implicit_type: bool = False
+
+  # Whether this column comes from copying a column from the ancestor. If this
+  # is set to false, the user explicitly specified it for this table.
+  is_ancestor: bool = False
+
+
+@dataclass(frozen=True)
+class ParsedTable:
+  """Representation of a table parsed from a Python definition."""
+
+  table: Table
+  columns: List[ParsedColumn]
+  input_path: str
+
+  def parse_type(self, col_type: CppColumnType) -> ParsedType:
+    """Parses a CppColumnType into its constiuent parts."""
+
+    if isinstance(col_type, CppInt64):
+      return ParsedType('int64_t')
+    if isinstance(col_type, CppInt32):
+      return ParsedType('int32_t')
+    if isinstance(col_type, CppUint32):
+      return ParsedType('uint32_t')
+    if isinstance(col_type, CppDouble):
+      return ParsedType('double')
+    if isinstance(col_type, CppString):
+      return ParsedType('StringPool::Id')
+
+    if isinstance(col_type, Alias):
+      col = next(c for c in self.columns
+                 if c.column.name == col_type.underlying_column)
+      return ParsedType(
+          self.parse_type(col.column.type).cpp_type,
+          is_alias=True,
+          alias_underlying_name=col.column.name)
+
+    if isinstance(col_type, CppTableId):
+      return ParsedType(
+          f'{col_type.table.class_name}::Id', id_table=col_type.table)
+
+    if isinstance(col_type, CppSelfTableId):
+      return ParsedType(
+          f'{self.table.class_name}::Id', is_self_id=True, id_table=self.table)
+
+    if isinstance(col_type, CppOptional):
+      inner = self.parse_type(col_type.inner)
+      assert not inner.is_optional, 'Nested optional not allowed'
+      return dataclasses.replace(inner, is_optional=True)
+
+    raise Exception(f'Unknown type {col_type}')
+
+  def typed_column_type(self, col: ParsedColumn) -> str:
+    """Returns the TypedColumn/IdColumn C++ type for a given column."""
+
+    parsed = self.parse_type(col.column.type)
+    if col.is_implicit_id:
+      return f'IdColumn<{parsed.cpp_type}>'
+    return f'TypedColumn<{parsed.cpp_type_with_optionality()}>'
+
+  def find_table_deps(self) -> Set[str]:
+    """Finds all the other table class names this table depends on.
+
+    By "depends", we mean this table in C++ would need the dependency to be
+    defined (or included) before this table is defined."""
+
+    deps: Set[str] = set()
+    if self.table.parent:
+      deps.add(self.table.parent.class_name)
+    for c in self.table.columns:
+      # Aliases cannot have dependencies so simply ignore them: trying to parse
+      # them before adding implicit columns can cause issues.
+      if isinstance(c.type, Alias):
+        continue
+      id_table = self.parse_type(c.type).id_table
+      if id_table:
+        deps.add(id_table.class_name)
+    return deps
+
+
+def public_sql_name(table: Table) -> str:
   """Extracts SQL name for the table which should be publicised."""
 
   wrapping_view = table.wrapping_sql_view
   return wrapping_view.view_name if wrapping_view else table.sql_name
 
+def _create_implicit_columns_for_root(parsed: ParsedTable
+                                     ) -> List[ParsedColumn]:
+  """Given a root table, returns the implicit id and type columns."""
+  table = parsed.table
+  assert table.parent is None
 
-def parse_type(table: Table, col_type: CppColumnType) -> ParsedType:
-  """Parses a CppColumnType into its constiuient parts."""
-
-  if isinstance(col_type, CppInt64):
-    return ParsedType('int64_t')
-  if isinstance(col_type, CppInt32):
-    return ParsedType('int32_t')
-  if isinstance(col_type, CppUint32):
-    return ParsedType('uint32_t')
-  if isinstance(col_type, CppString):
-    return ParsedType('StringPool::Id')
-
-  if isinstance(col_type, Alias):
-    col = next(c for c in table.columns if c.name == col_type.underlying_column)
-    return ParsedType(
-        parse_type(table, col.type).cpp_type,
-        is_alias=True,
-        alias_underlying_name=col.name)
-
-  if isinstance(col_type, CppTableId):
-    return ParsedType(
-        f'{col_type.table.class_name}::Id', id_table=col_type.table)
-
-  if isinstance(col_type, CppSelfTableId):
-    return ParsedType(
-        f'{table.class_name}::Id', is_self_id=True, id_table=table)
-
-  if isinstance(col_type, CppOptional):
-    inner = parse_type(table, col_type.inner)
-    assert not inner.is_optional, 'Nested optional not allowed'
-    return dataclasses.replace(inner, is_optional=True)
-
-  raise Exception(f'Unknown type {col_type}')
+  sql_name = public_sql_name(table)
+  id_doc = table.tabledoc.columns.get('id') if table.tabledoc else None
+  type_doc = table.tabledoc.columns.get('type') if table.tabledoc else None
+  return [
+      ParsedColumn(
+          Column('id', CppSelfTableId(), ColumnFlag.SORTED),
+          _to_column_doc(id_doc) if id_doc else ColumnDoc(
+              doc=f'Unique idenitifier for this {sql_name}.'),
+          is_implicit_id=True),
+      ParsedColumn(
+          Column('type', CppString(), ColumnFlag.NONE),
+          _to_column_doc(type_doc) if type_doc else ColumnDoc(doc='''
+                The name of the "most-specific" child table containing this
+                row.
+              '''),
+          is_implicit_type=True,
+      )
+  ]
 
 
-def normalize_table_columns(table: Table):
-  """Normalizes the table by doing the following:
-
-  1. Adding any columns from the parent, if this table is not a root.
-  2. Adding auto-defined columns (i.e. id and type), if this table is a root."""
-  if table.parent:
-    auto_cols = []
-    for col in table.parent.columns:
-      auto_cols.append(dataclasses.replace(col, _is_self_column=False))
-    new_cols_doc = table.tabledoc.columns
-  else:
-    auto_cols = [
-        Column(
-            'id', CppSelfTableId(), ColumnFlag.SORTED, _is_auto_added_id=True),
-        Column('type', CppString(), ColumnFlag.NONE, _is_auto_added_type=True),
-    ]
-    public_sql_name = public_sql_name_for_table(table)
-    new_cols_doc: Dict[str, Union[ColumnDoc, str]] = {
-        'id':
-            ColumnDoc(doc=f'Unique idenitifier for this {public_sql_name}.'),
-        'type':
-            ColumnDoc(doc='''
-                  The name of the "most-specific" child table containing this
-                  row.
-                '''),
-    }
-    new_cols_doc.update(table.tabledoc.columns)
-
-  table.columns = auto_cols + table.columns
-  table.tabledoc.columns = new_cols_doc
-
-
-def find_table_deps(table: Table) -> Set[str]:
-  """Finds all the other table class names this table depends on.
-
-  By "depends", we mean this table in C++ would need the dependency to be
-  defined (or included) before this table is defined."""
-  deps: Set[str] = set()
-  if table.parent:
-    deps.add(table.parent.class_name)
-  for c in table.columns:
-    id_table = parse_type(table, c.type).id_table
-    if id_table:
-      deps.add(id_table.class_name)
-  return deps
-
-
-def topological_sort_tables(tables: List[Table]) -> List[Table]:
+def _topological_sort_tables(parsed: List[ParsedTable]) -> List[ParsedTable]:
   """Topologically sorts a list of tables (i.e. dependenices appear earlier).
 
   See [1] for information on a topological sort. We do this to allow
   dependencies to be processed and appear ealier than their dependents.
 
   [1] https://en.wikipedia.org/wiki/Topological_sorting"""
-  tables_by_name: dict[str, Table] = dict((t.class_name, t) for t in tables)
+  table_to_parsed_table = {p.table.class_name: p for p in parsed}
   visited: Set[str] = set()
-  result: List[Table] = []
+  result: List[ParsedTable] = []
 
   # Topological sorting is really just a DFS where we put the nodes in the list
   # after any dependencies.
-  def dfs(table_class_name: str):
-    table = tables_by_name.get(table_class_name)
-    # If the table is not found, that might be because it's not in this list of
-    # tables. Just ignore this as its up to the caller to make sure any external
-    # deps are handled correctly.
-    if not table or table.class_name in visited:
+  def dfs(t: ParsedTable):
+    if t.table.class_name in visited:
       return
-    visited.add(table.class_name)
+    visited.add(t.table.class_name)
 
-    for dep in find_table_deps(table):
-      dfs(dep)
-    result.append(table)
+    for dep in t.find_table_deps():
+      dfs(table_to_parsed_table[dep])
+    result.append(t)
 
-  for table in tables:
-    dfs(table.class_name)
+  for p in parsed:
+    dfs(p)
   return result
 
 
-def to_cpp_flags(raw_flag: ColumnFlag) -> str:
-  """Converts a ColumnFlag to the C++ flags which it represents
+def _to_column_doc(doc: Union[ColumnDoc, str, None]) -> Optional[ColumnDoc]:
+  """Cooerces a user specified ColumnDoc or string into a ColumnDoc."""
 
-  It is not valid to call this function with ColumnFlag.NONE as in this case
-  defaults for that column should be implicitly used."""
-
-  assert raw_flag != ColumnFlag.NONE
-  flags = []
-  if ColumnFlag.SORTED in raw_flag:
-    flags.append('Column::Flag::kSorted')
-  if ColumnFlag.SET_ID in raw_flag:
-    flags.append('Column::Flag::kSetId')
-  return ' | '.join(flags)
+  if doc is None or isinstance(doc, ColumnDoc):
+    return doc
+  return ColumnDoc(doc=doc)
 
 
-def typed_column_type(table: Table, col: Column) -> str:
-  """Returns the TypedColumn/IdColumn C++ type for a given column."""
+def parse_tables_from_files(input_paths: List[str]) -> List[ParsedTable]:
+  """Creates a list of tables with the associated paths."""
 
-  parsed = parse_type(table, col.type)
-  if col._is_auto_added_id:
-    return f'IdColumn<{parsed.cpp_type}>'
-  return f'TypedColumn<{parsed.cpp_type_with_optionality()}>'
+  # Create a mapping from the table to a "parsed" version of the table.
+  parsed_tables: Dict[str, ParsedTable] = {}
+  for in_path in input_paths:
+    tables: List[Table] = runpy.run_path(in_path)['ALL_TABLES']
+    for table in tables:
+      existing_table = parsed_tables.get(table.class_name)
+      assert not existing_table or existing_table.table == table
+      parsed_tables[table.class_name] = ParsedTable(table, [], in_path)
+
+  # Sort all the tables to be in order.
+  sorted_tables = _topological_sort_tables(list(parsed_tables.values()))
+
+  # Create the list of parsed columns
+  for i, parsed in enumerate(sorted_tables):
+    parsed_columns: List[ParsedColumn]
+    table = parsed.table
+
+    if table.parent:
+      parsed_parent = parsed_tables[table.parent.class_name]
+      parsed_columns = [
+          dataclasses.replace(c, is_ancestor=True)
+          for c in parsed_parent.columns
+      ]
+    else:
+      parsed_columns = _create_implicit_columns_for_root(parsed)
+
+    for c in table.columns:
+      doc = table.tabledoc.columns.get(c.name) if table.tabledoc else None
+      parsed_columns.append(ParsedColumn(c, _to_column_doc(doc)))
+
+    sorted_tables[i] = dataclasses.replace(parsed, columns=parsed_columns)
+    parsed_tables[parsed.table.class_name] = sorted_tables[i]
+
+  return sorted_tables
diff --git a/python/tools/update_permalink.py b/python/tools/update_permalink.py
index a6e8fab..56250fe 100755
--- a/python/tools/update_permalink.py
+++ b/python/tools/update_permalink.py
@@ -14,6 +14,65 @@
 CURRENT_STATE_VERSION = 28
 
 
+def upgrade_15(old):
+  new = copy.deepcopy(old)
+  new["version"] = 16
+  new["flamegraphModalDismissed"] = False
+  return new
+
+
+def upgrade_16(old):
+  new = copy.deepcopy(old)
+  new["version"] = 17
+  new["nextId"] = max(old["nextId"], old["nextNoteId"], old["nextAreaId"])
+  engines = old["engines"]
+  if len(engines) > 0:
+    new["currentEngineId"] = list(engines.values())[0]['id']
+  return new
+
+
+def upgrade_17(old):
+  new = copy.deepcopy(old)
+  new["version"] = 18
+  # TODO(hjd): Update
+  return new
+
+
+def upgrade_18(old):
+  new = copy.deepcopy(old)
+  new["version"] = 19
+  # TODO(hjd): Update
+  return new
+
+
+def upgrade_19(old):
+  new = copy.deepcopy(old)
+  new["version"] = 20
+  # TODO(hjd): Update
+  return new
+
+
+def upgrade_20(old):
+  new = copy.deepcopy(old)
+  new["version"] = 21
+  # TODO(hjd): Update
+  return new
+
+
+def upgrade_20(old):
+  new = copy.deepcopy(old)
+  new["version"] = 22
+  # TODO(hjd): Update
+  return new
+
+
+def upgrade_21(old):
+  new = copy.deepcopy(old)
+  new["version"] = 22
+  # TODO(hjd): Update
+  return new
+
+
 def upgrade_22(old):
   new = copy.deepcopy(old)
   new["version"] = 23
@@ -121,6 +180,8 @@
       "--target-version",
       help=f"Target state version (default: {CURRENT_STATE_VERSION})",
       default=CURRENT_STATE_VERSION)
+  parser.add_argument(
+      "--verbose", help=f"Show debug information", action="store_true")
   args = parser.parse_args()
 
   permalink_url = args.permalink
@@ -132,7 +193,16 @@
   old_state_version = old_json["version"]
   new_state_version = args.target_version
 
+  print(json.dumps(old_json, sort_keys=True, indent=4))
+
   UPGRADE = {
+      15: upgrade_15,
+      16: upgrade_16,
+      17: upgrade_17,
+      18: upgrade_18,
+      19: upgrade_19,
+      20: upgrade_20,
+      21: upgrade_21,
       22: upgrade_22,
       23: upgrade_23,
       24: upgrade_24,
diff --git a/src/android_internal/statsd.h b/src/android_internal/statsd.h
index 8afa9f0..f114aa2 100644
--- a/src/android_internal/statsd.h
+++ b/src/android_internal/statsd.h
@@ -17,6 +17,7 @@
 #ifndef SRC_ANDROID_INTERNAL_STATSD_H_
 #define SRC_ANDROID_INTERNAL_STATSD_H_
 
+#include <stddef.h>
 #include <stdint.h>
 
 // This header declares proxy functions defined in
diff --git a/src/android_stats/perfetto_atoms.h b/src/android_stats/perfetto_atoms.h
index 5a5eef0..e9ef08e 100644
--- a/src/android_stats/perfetto_atoms.h
+++ b/src/android_stats/perfetto_atoms.h
@@ -70,6 +70,7 @@
   kTracedStartTracingInvalidSessionState = 36,
   kTracedEnableTracingInvalidFilter = 47,
   kTracedEnableTracingOobTargetBuffer = 48,
+  kTracedEnableTracingInvalidTriggerMode = 52,
 
   // Checkpoints inside perfetto_cmd after tracing has finished.
   kOnTracingDisabled = 4,
diff --git a/src/base/BUILD.gn b/src/base/BUILD.gn
index 6a58f0b..8d48bf0 100644
--- a/src/base/BUILD.gn
+++ b/src/base/BUILD.gn
@@ -194,7 +194,6 @@
     "hash_unittest.cc",
     "logging_unittest.cc",
     "no_destructor_unittest.cc",
-    "optional_unittest.cc",
     "paged_memory_unittest.cc",
     "periodic_task_unittest.cc",
     "scoped_file_unittest.cc",
diff --git a/src/base/base64.cc b/src/base/base64.cc
index bb2e3c4..6b2236b 100644
--- a/src/base/base64.cc
+++ b/src/base/base64.cc
@@ -136,17 +136,17 @@
   return static_cast<ssize_t>(wr_size);
 }
 
-Optional<std::string> Base64Decode(const char* src, size_t src_size) {
+std::optional<std::string> Base64Decode(const char* src, size_t src_size) {
   std::string dst;
   dst.resize(Base64DecSize(src_size));
   auto res = Base64Decode(src, src_size, reinterpret_cast<uint8_t*>(&dst[0]),
                           dst.size());
   if (res < 0)
-    return nullopt;  // Decoding error.
+    return std::nullopt;  // Decoding error.
 
   PERFETTO_CHECK(res <= static_cast<ssize_t>(dst.size()));
   dst.resize(static_cast<size_t>(res));
-  return base::make_optional(dst);
+  return std::make_optional(dst);
 }
 
 }  // namespace base
diff --git a/src/base/base64_unittest.cc b/src/base/base64_unittest.cc
index fb131d9..f01b13c 100644
--- a/src/base/base64_unittest.cc
+++ b/src/base/base64_unittest.cc
@@ -341,14 +341,14 @@
 
   for (size_t i = 0; i < ArraySize(kPatterns); ++i) {
     const auto& p = kPatterns[i];
-    Optional<std::string> dec = Base64Decode(StringView(p.encoded));
+    std::optional<std::string> dec = Base64Decode(StringView(p.encoded));
     EXPECT_TRUE(dec.has_value());
     EXPECT_EQ(dec.value(), StringView(p.decoded, p.decoded_len).ToStdString());
   }
 
   // Error cases:
-  EXPECT_EQ(Base64Decode("Z"), nullopt);
-  EXPECT_EQ(Base64Decode("Zm9vY"), nullopt);
+  EXPECT_EQ(Base64Decode("Z"), std::nullopt);
+  EXPECT_EQ(Base64Decode("Zm9vY"), std::nullopt);
 
   uint8_t buf[4];
   EXPECT_EQ(Base64Decode("", 0, buf, 2), 0);       // Valid, 0 len.
diff --git a/src/base/file_utils.cc b/src/base/file_utils.cc
index 9f70ad7..e7d4c94 100644
--- a/src/base/file_utils.cc
+++ b/src/base/file_utils.cc
@@ -21,6 +21,7 @@
 
 #include <algorithm>
 #include <deque>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -28,7 +29,6 @@
 #include "perfetto/base/logging.h"
 #include "perfetto/base/platform_handle.h"
 #include "perfetto/base/status.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/platform.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/utils.h"
@@ -54,11 +54,11 @@
   return FindClose(h) ? 0 : -1;
 }
 
-Optional<std::wstring> ToUtf16(const std::string str) {
+std::optional<std::wstring> ToUtf16(const std::string str) {
   int len = MultiByteToWideChar(CP_UTF8, 0, str.data(),
                                 static_cast<int>(str.size()), nullptr, 0);
   if (len < 0) {
-    return base::nullopt;
+    return std::nullopt;
   }
   std::vector<wchar_t> tmp;
   tmp.resize(static_cast<std::vector<wchar_t>::size_type>(len));
@@ -66,7 +66,7 @@
       MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.size()),
                           tmp.data(), static_cast<int>(tmp.size()));
   if (len < 0) {
-    return base::nullopt;
+    return std::nullopt;
   }
   PERFETTO_CHECK(static_cast<std::vector<wchar_t>::size_type>(len) ==
                  tmp.size());
diff --git a/src/base/http/http_server.cc b/src/base/http/http_server.cc
index 3db6ae2..2efe9f7 100644
--- a/src/base/http/http_server.cc
+++ b/src/base/http/http_server.cc
@@ -565,12 +565,12 @@
 
 HttpServerConnection::~HttpServerConnection() = default;
 
-Optional<StringView> HttpRequest::GetHeader(StringView name) const {
+std::optional<StringView> HttpRequest::GetHeader(StringView name) const {
   for (size_t i = 0; i < num_headers; i++) {
     if (headers[i].name.CaseInsensitiveEq(name))
       return headers[i].value;
   }
-  return nullopt;
+  return std::nullopt;
 }
 
 HttpRequestHandler::~HttpRequestHandler() = default;
diff --git a/src/base/optional_unittest.cc b/src/base/optional_unittest.cc
deleted file mode 100644
index 285db51..0000000
--- a/src/base/optional_unittest.cc
+++ /dev/null
@@ -1,2211 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Comparisions of floats is used extensively in this file. Ignore warnings
-// as we want to stay close to Chromium.
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wfloat-equal"
-#endif
-
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "perfetto/ext/base/optional.h"
-#include "perfetto/ext/base/utils.h"
-#include "test/gtest_and_gmock.h"
-
-using ::testing::ElementsAre;
-
-namespace perfetto {
-namespace base {
-
-namespace {
-
-// Object used to test complex object with Optional<T> in addition of the move
-// semantics.
-class TestObject {
- public:
-  enum class State {
-    DEFAULT_CONSTRUCTED,
-    VALUE_CONSTRUCTED,
-    COPY_CONSTRUCTED,
-    MOVE_CONSTRUCTED,
-    MOVED_FROM,
-    COPY_ASSIGNED,
-    MOVE_ASSIGNED,
-    SWAPPED,
-  };
-
-  TestObject() : foo_(0), bar_(0.0), state_(State::DEFAULT_CONSTRUCTED) {}
-
-  TestObject(int foo, double bar)
-      : foo_(foo), bar_(bar), state_(State::VALUE_CONSTRUCTED) {}
-
-  TestObject(const TestObject& other)
-      : foo_(other.foo_),
-        bar_(other.bar_),
-        state_(State::COPY_CONSTRUCTED),
-        move_ctors_count_(other.move_ctors_count_) {}
-
-  TestObject(TestObject&& other)
-      : foo_(std::move(other.foo_)),
-        bar_(std::move(other.bar_)),
-        state_(State::MOVE_CONSTRUCTED),
-        move_ctors_count_(other.move_ctors_count_ + 1) {
-    other.state_ = State::MOVED_FROM;
-  }
-
-  TestObject& operator=(const TestObject& other) {
-    foo_ = other.foo_;
-    bar_ = other.bar_;
-    state_ = State::COPY_ASSIGNED;
-    move_ctors_count_ = other.move_ctors_count_;
-    return *this;
-  }
-
-  TestObject& operator=(TestObject&& other) {
-    foo_ = other.foo_;
-    bar_ = other.bar_;
-    state_ = State::MOVE_ASSIGNED;
-    move_ctors_count_ = other.move_ctors_count_;
-    other.state_ = State::MOVED_FROM;
-    return *this;
-  }
-
-  void Swap(TestObject* other) {
-    using std::swap;
-    swap(foo_, other->foo_);
-    swap(bar_, other->bar_);
-    swap(move_ctors_count_, other->move_ctors_count_);
-    state_ = State::SWAPPED;
-    other->state_ = State::SWAPPED;
-  }
-
-  bool operator==(const TestObject& other) const {
-    return std::tie(foo_, bar_) == std::tie(other.foo_, other.bar_);
-  }
-
-  bool operator!=(const TestObject& other) const { return !(*this == other); }
-
-  int foo() const { return foo_; }
-  State state() const { return state_; }
-  int move_ctors_count() const { return move_ctors_count_; }
-
- private:
-  int foo_;
-  double bar_;
-  State state_;
-  int move_ctors_count_ = 0;
-};
-
-// Implementing Swappable concept.
-void swap(TestObject& lhs, TestObject& rhs) {
-  lhs.Swap(&rhs);
-}
-
-class NonTriviallyDestructible {
-  ~NonTriviallyDestructible() {}
-};
-
-class DeletedDefaultConstructor {
- public:
-  DeletedDefaultConstructor() = delete;
-  DeletedDefaultConstructor(int foo) : foo_(foo) {}
-
-  int foo() const { return foo_; }
-
- private:
-  int foo_;
-};
-
-class DeletedCopy {
- public:
-  explicit DeletedCopy(int foo) : foo_(foo) {}
-  DeletedCopy(const DeletedCopy&) = delete;
-  DeletedCopy(DeletedCopy&&) = default;
-
-  DeletedCopy& operator=(const DeletedCopy&) = delete;
-  DeletedCopy& operator=(DeletedCopy&&) = default;
-
-  int foo() const { return foo_; }
-
- private:
-  int foo_;
-};
-
-class DeletedMove {
- public:
-  explicit DeletedMove(int foo) : foo_(foo) {}
-  DeletedMove(const DeletedMove&) = default;
-  DeletedMove(DeletedMove&&) = delete;
-
-  DeletedMove& operator=(const DeletedMove&) = default;
-  DeletedMove& operator=(DeletedMove&&) = delete;
-
-  int foo() const { return foo_; }
-
- private:
-  int foo_;
-};
-
-class NonTriviallyDestructibleDeletedCopyConstructor {
- public:
-  explicit NonTriviallyDestructibleDeletedCopyConstructor(int foo)
-      : foo_(foo) {}
-  NonTriviallyDestructibleDeletedCopyConstructor(
-      const NonTriviallyDestructibleDeletedCopyConstructor&) = delete;
-  NonTriviallyDestructibleDeletedCopyConstructor(
-      NonTriviallyDestructibleDeletedCopyConstructor&&) = default;
-
-  ~NonTriviallyDestructibleDeletedCopyConstructor() {}
-
-  int foo() const { return foo_; }
-
- private:
-  int foo_;
-};
-
-class DeleteNewOperators {
- public:
-  void* operator new(size_t) = delete;
-  void* operator new(size_t, void*) = delete;
-  void* operator new[](size_t) = delete;
-  void* operator new[](size_t, void*) = delete;
-};
-
-}  // anonymous namespace
-
-static_assert(std::is_trivially_destructible<Optional<int>>::value,
-              "OptionalIsTriviallyDestructible");
-
-static_assert(
-    !std::is_trivially_destructible<Optional<NonTriviallyDestructible>>::value,
-    "OptionalIsTriviallyDestructible");
-
-static_assert(sizeof(Optional<int>) == sizeof(internal::OptionalBase<int>),
-              "internal::{Copy,Move}{Constructible,Assignable} structs "
-              "should be 0-sized");
-
-TEST(OptionalTest, DefaultConstructor) {
-  {
-    constexpr Optional<float> o;
-    EXPECT_FALSE(o);
-  }
-
-  {
-    Optional<std::string> o;
-    EXPECT_FALSE(o);
-  }
-
-  {
-    Optional<TestObject> o;
-    EXPECT_FALSE(o);
-  }
-}
-
-TEST(OptionalTest, CopyConstructor) {
-  {
-    constexpr Optional<float> first(0.1f);
-    constexpr Optional<float> other(first);
-
-    EXPECT_TRUE(other);
-    EXPECT_EQ(other.value(), 0.1f);
-    EXPECT_EQ(first, other);
-  }
-
-  {
-    Optional<std::string> first("foo");
-    Optional<std::string> other(first);
-
-    EXPECT_TRUE(other);
-    EXPECT_EQ(other.value(), "foo");
-    EXPECT_EQ(first, other);
-  }
-
-  {
-    const Optional<std::string> first("foo");
-    Optional<std::string> other(first);
-
-    EXPECT_TRUE(other);
-    EXPECT_EQ(other.value(), "foo");
-    EXPECT_EQ(first, other);
-  }
-
-  {
-    Optional<TestObject> first(TestObject(3, 0.1));
-    Optional<TestObject> other(first);
-
-    EXPECT_TRUE(!!other);
-    EXPECT_TRUE(other.value() == TestObject(3, 0.1));
-    EXPECT_TRUE(first == other);
-  }
-}
-
-TEST(OptionalTest, ValueConstructor) {
-  {
-    constexpr float value = 0.1f;
-    constexpr Optional<float> o(value);
-
-    EXPECT_TRUE(o);
-    EXPECT_EQ(value, o.value());
-  }
-
-  {
-    std::string value("foo");
-    Optional<std::string> o(value);
-
-    EXPECT_TRUE(o);
-    EXPECT_EQ(value, o.value());
-  }
-
-  {
-    TestObject value(3, 0.1);
-    Optional<TestObject> o(value);
-
-    EXPECT_TRUE(o);
-    EXPECT_EQ(TestObject::State::COPY_CONSTRUCTED, o->state());
-    EXPECT_EQ(value, o.value());
-  }
-}
-
-TEST(OptionalTest, MoveConstructor) {
-  {
-    constexpr Optional<float> first(0.1f);
-    constexpr Optional<float> second(std::move(first));
-
-    EXPECT_TRUE(second.has_value());
-    EXPECT_EQ(second.value(), 0.1f);
-
-    EXPECT_TRUE(first.has_value());
-  }
-
-  {
-    Optional<std::string> first("foo");
-    Optional<std::string> second(std::move(first));
-
-    EXPECT_TRUE(second.has_value());
-    EXPECT_EQ("foo", second.value());
-
-    EXPECT_TRUE(first.has_value());
-  }
-
-  {
-    Optional<TestObject> first(TestObject(3, 0.1));
-    Optional<TestObject> second(std::move(first));
-
-    EXPECT_TRUE(second.has_value());
-    EXPECT_EQ(TestObject::State::MOVE_CONSTRUCTED, second->state());
-    EXPECT_TRUE(TestObject(3, 0.1) == second.value());
-
-    EXPECT_TRUE(first.has_value());
-    EXPECT_EQ(TestObject::State::MOVED_FROM, first->state());
-  }
-
-  // Even if copy constructor is deleted, move constructor needs to work.
-  // Note that it couldn't be constexpr.
-  {
-    Optional<DeletedCopy> first(in_place, 42);
-    Optional<DeletedCopy> second(std::move(first));
-
-    EXPECT_TRUE(second.has_value());
-    EXPECT_EQ(42, second->foo());
-
-    EXPECT_TRUE(first.has_value());
-  }
-
-  {
-    Optional<DeletedMove> first(in_place, 42);
-    Optional<DeletedMove> second(std::move(first));
-
-    EXPECT_TRUE(second.has_value());
-    EXPECT_EQ(42, second->foo());
-
-    EXPECT_TRUE(first.has_value());
-  }
-
-  {
-    Optional<NonTriviallyDestructibleDeletedCopyConstructor> first(in_place,
-                                                                   42);
-    Optional<NonTriviallyDestructibleDeletedCopyConstructor> second(
-        std::move(first));
-
-    EXPECT_TRUE(second.has_value());
-    EXPECT_EQ(42, second->foo());
-
-    EXPECT_TRUE(first.has_value());
-  }
-}
-
-TEST(OptionalTest, MoveValueConstructor) {
-  {
-    constexpr float value = 0.1f;
-    constexpr Optional<float> o(std::move(value));
-
-    EXPECT_TRUE(o);
-    EXPECT_EQ(0.1f, o.value());
-  }
-
-  {
-    float value = 0.1f;
-    Optional<float> o(std::move(value));
-
-    EXPECT_TRUE(o);
-    EXPECT_EQ(0.1f, o.value());
-  }
-
-  {
-    std::string value("foo");
-    Optional<std::string> o(std::move(value));
-
-    EXPECT_TRUE(o);
-    EXPECT_EQ("foo", o.value());
-  }
-
-  {
-    TestObject value(3, 0.1);
-    Optional<TestObject> o(std::move(value));
-
-    EXPECT_TRUE(o);
-    EXPECT_EQ(TestObject::State::MOVE_CONSTRUCTED, o->state());
-    EXPECT_EQ(TestObject(3, 0.1), o.value());
-  }
-}
-
-TEST(OptionalTest, ConvertingCopyConstructor) {
-  {
-    Optional<int> first(1);
-    Optional<double> second(first);
-    EXPECT_TRUE(second.has_value());
-    EXPECT_EQ(1.0, second.value());
-  }
-
-  // Make sure explicit is not marked for convertible case.
-  {
-    Optional<int> o(1);
-    ignore_result<Optional<double>>(o);
-  }
-}
-
-TEST(OptionalTest, ConvertingMoveConstructor) {
-  {
-    Optional<int> first(1);
-    Optional<double> second(std::move(first));
-    EXPECT_TRUE(second.has_value());
-    EXPECT_EQ(1.0, second.value());
-  }
-
-  // Make sure explicit is not marked for convertible case.
-  {
-    Optional<int> o(1);
-    ignore_result<Optional<double>>(std::move(o));
-  }
-
-  {
-    class Test1 {
-     public:
-      explicit Test1(int foo) : foo_(foo) {}
-
-      int foo() const { return foo_; }
-
-     private:
-      int foo_;
-    };
-
-    // Not copyable but convertible from Test1.
-    class Test2 {
-     public:
-      Test2(const Test2&) = delete;
-      explicit Test2(Test1&& other) : bar_(other.foo()) {}
-
-      double bar() const { return bar_; }
-
-     private:
-      double bar_;
-    };
-
-    Optional<Test1> first(in_place, 42);
-    Optional<Test2> second(std::move(first));
-    EXPECT_TRUE(second.has_value());
-    EXPECT_EQ(42.0, second->bar());
-  }
-}
-
-TEST(OptionalTest, ConstructorForwardArguments) {
-  {
-    constexpr Optional<float> a(base::in_place, 0.1f);
-    EXPECT_TRUE(a);
-    EXPECT_EQ(0.1f, a.value());
-  }
-
-  {
-    Optional<float> a(base::in_place, 0.1f);
-    EXPECT_TRUE(a);
-    EXPECT_EQ(0.1f, a.value());
-  }
-
-  {
-    Optional<std::string> a(base::in_place, "foo");
-    EXPECT_TRUE(a);
-    EXPECT_EQ("foo", a.value());
-  }
-
-  {
-    Optional<TestObject> a(base::in_place, 0, 0.1);
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(TestObject(0, 0.1) == a.value());
-  }
-}
-
-TEST(OptionalTest, ConstructorForwardInitListAndArguments) {
-  {
-    Optional<std::vector<int>> opt(in_place, {3, 1});
-    EXPECT_TRUE(opt);
-    EXPECT_THAT(*opt, ElementsAre(3, 1));
-    EXPECT_EQ(2u, opt->size());
-  }
-
-  {
-    Optional<std::vector<int>> opt(in_place, {3, 1}, std::allocator<int>());
-    EXPECT_TRUE(opt);
-    EXPECT_THAT(*opt, ElementsAre(3, 1));
-    EXPECT_EQ(2u, opt->size());
-  }
-}
-
-TEST(OptionalTest, ForwardConstructor) {
-  {
-    Optional<double> a(1);
-    EXPECT_TRUE(a.has_value());
-    EXPECT_EQ(1.0, a.value());
-  }
-
-  // Test that default type of 'U' is value_type.
-  {
-    struct TestData {
-      int a;
-      double b;
-      bool c;
-    };
-
-    Optional<TestData> a({1, 2.0, true});
-    EXPECT_TRUE(a.has_value());
-    EXPECT_EQ(1, a->a);
-    EXPECT_EQ(2.0, a->b);
-    EXPECT_TRUE(a->c);
-  }
-
-  // If T has a constructor with a param Optional<U>, and another ctor with a
-  // param U, then T(Optional<U>) should be used for Optional<T>(Optional<U>)
-  // constructor.
-  {
-    enum class ParamType {
-      DEFAULT_CONSTRUCTED,
-      COPY_CONSTRUCTED,
-      MOVE_CONSTRUCTED,
-      INT,
-      IN_PLACE,
-      OPTIONAL_INT,
-    };
-    struct Test {
-      Test() : param_type(ParamType::DEFAULT_CONSTRUCTED) {}
-      Test(const Test&) : param_type(ParamType::COPY_CONSTRUCTED) {}
-      Test(Test&&) : param_type(ParamType::MOVE_CONSTRUCTED) {}
-      explicit Test(int) : param_type(ParamType::INT) {}
-      explicit Test(in_place_t) : param_type(ParamType::IN_PLACE) {}
-      explicit Test(Optional<int>) : param_type(ParamType::OPTIONAL_INT) {}
-
-      ParamType param_type;
-    };
-
-    // Overload resolution with copy-conversion constructor.
-    {
-      const Optional<int> arg(in_place, 1);
-      Optional<Test> testee(arg);
-      EXPECT_EQ(ParamType::OPTIONAL_INT, testee->param_type);
-    }
-
-    // Overload resolution with move conversion constructor.
-    {
-      Optional<Test> testee(Optional<int>(in_place, 1));
-      EXPECT_EQ(ParamType::OPTIONAL_INT, testee->param_type);
-    }
-
-    // Default constructor should be used.
-    {
-      Optional<Test> testee(in_place);
-      EXPECT_EQ(ParamType::DEFAULT_CONSTRUCTED, testee->param_type);
-    }
-  }
-
-  {
-    struct Test {
-      Test(int) {}  // NOLINT(runtime/explicit)
-    };
-    // If T is convertible from U, it is not marked as explicit.
-    static_assert(std::is_convertible<int, Test>::value,
-                  "Int should be convertible to Test.");
-    ([](Optional<Test>) {})(1);
-  }
-}
-
-TEST(OptionalTest, NulloptConstructor) {
-  constexpr Optional<int> a(base::nullopt);
-  EXPECT_FALSE(a);
-}
-
-TEST(OptionalTest, AssignValue) {
-  {
-    Optional<float> a;
-    EXPECT_FALSE(a);
-    a = 0.1f;
-    EXPECT_TRUE(a);
-
-    Optional<float> b(0.1f);
-    EXPECT_TRUE(a == b);
-  }
-
-  {
-    Optional<std::string> a;
-    EXPECT_FALSE(a);
-    a = std::string("foo");
-    EXPECT_TRUE(a);
-
-    Optional<std::string> b(std::string("foo"));
-    EXPECT_EQ(a, b);
-  }
-
-  {
-    Optional<TestObject> a;
-    EXPECT_FALSE(!!a);
-    a = TestObject(3, 0.1);
-    EXPECT_TRUE(!!a);
-
-    Optional<TestObject> b(TestObject(3, 0.1));
-    EXPECT_TRUE(a == b);
-  }
-
-  {
-    Optional<TestObject> a = TestObject(4, 1.0);
-    EXPECT_TRUE(!!a);
-    a = TestObject(3, 0.1);
-    EXPECT_TRUE(!!a);
-
-    Optional<TestObject> b(TestObject(3, 0.1));
-    EXPECT_TRUE(a == b);
-  }
-}
-
-TEST(OptionalTest, AssignObject) {
-  {
-    Optional<float> a;
-    Optional<float> b(0.1f);
-    a = b;
-
-    EXPECT_TRUE(a);
-    EXPECT_EQ(a.value(), 0.1f);
-    EXPECT_EQ(a, b);
-  }
-
-  {
-    Optional<std::string> a;
-    Optional<std::string> b("foo");
-    a = b;
-
-    EXPECT_TRUE(a);
-    EXPECT_EQ(a.value(), "foo");
-    EXPECT_EQ(a, b);
-  }
-
-  {
-    Optional<TestObject> a;
-    Optional<TestObject> b(TestObject(3, 0.1));
-    a = b;
-
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(a.value() == TestObject(3, 0.1));
-    EXPECT_TRUE(a == b);
-  }
-
-  {
-    Optional<TestObject> a(TestObject(4, 1.0));
-    Optional<TestObject> b(TestObject(3, 0.1));
-    a = b;
-
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(a.value() == TestObject(3, 0.1));
-    EXPECT_TRUE(a == b);
-  }
-
-  {
-    Optional<DeletedMove> a(in_place, 42);
-    Optional<DeletedMove> b;
-    b = a;
-
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(a->foo(), b->foo());
-  }
-
-  {
-    Optional<DeletedMove> a(in_place, 42);
-    Optional<DeletedMove> b(in_place, 1);
-    b = a;
-
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(a->foo(), b->foo());
-  }
-
-  // Converting assignment.
-  {
-    Optional<int> a(in_place, 1);
-    Optional<double> b;
-    b = a;
-
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(1, a.value());
-    EXPECT_EQ(1.0, b.value());
-  }
-
-  {
-    Optional<int> a(in_place, 42);
-    Optional<double> b(in_place, 1);
-    b = a;
-
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(42, a.value());
-    EXPECT_EQ(42.0, b.value());
-  }
-
-  {
-    Optional<int> a;
-    Optional<double> b(in_place, 1);
-    b = a;
-    EXPECT_FALSE(!!a);
-    EXPECT_FALSE(!!b);
-  }
-}
-
-TEST(OptionalTest, AssignObject_rvalue) {
-  {
-    Optional<float> a;
-    Optional<float> b(0.1f);
-    a = std::move(b);
-
-    EXPECT_TRUE(a);
-    EXPECT_TRUE(b);
-    EXPECT_EQ(0.1f, a.value());
-  }
-
-  {
-    Optional<std::string> a;
-    Optional<std::string> b("foo");
-    a = std::move(b);
-
-    EXPECT_TRUE(a);
-    EXPECT_TRUE(b);
-    EXPECT_EQ("foo", a.value());
-  }
-
-  {
-    Optional<TestObject> a;
-    Optional<TestObject> b(TestObject(3, 0.1));
-    a = std::move(b);
-
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_TRUE(TestObject(3, 0.1) == a.value());
-
-    EXPECT_EQ(TestObject::State::MOVE_CONSTRUCTED, a->state());
-    EXPECT_EQ(TestObject::State::MOVED_FROM, b->state());
-  }
-
-  {
-    Optional<TestObject> a(TestObject(4, 1.0));
-    Optional<TestObject> b(TestObject(3, 0.1));
-    a = std::move(b);
-
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_TRUE(TestObject(3, 0.1) == a.value());
-
-    EXPECT_EQ(TestObject::State::MOVE_ASSIGNED, a->state());
-    EXPECT_EQ(TestObject::State::MOVED_FROM, b->state());
-  }
-
-  {
-    Optional<DeletedMove> a(in_place, 42);
-    Optional<DeletedMove> b;
-    b = std::move(a);
-
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(42, b->foo());
-  }
-
-  {
-    Optional<DeletedMove> a(in_place, 42);
-    Optional<DeletedMove> b(in_place, 1);
-    b = std::move(a);
-
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(42, b->foo());
-  }
-
-  // Converting assignment.
-  {
-    Optional<int> a(in_place, 1);
-    Optional<double> b;
-    b = std::move(a);
-
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(1.0, b.value());
-  }
-
-  {
-    Optional<int> a(in_place, 42);
-    Optional<double> b(in_place, 1);
-    b = std::move(a);
-
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(42.0, b.value());
-  }
-
-  {
-    Optional<int> a;
-    Optional<double> b(in_place, 1);
-    b = std::move(a);
-
-    EXPECT_FALSE(!!a);
-    EXPECT_FALSE(!!b);
-  }
-}
-
-TEST(OptionalTest, AssignNull) {
-  {
-    Optional<float> a(0.1f);
-    Optional<float> b(0.2f);
-    a = base::nullopt;
-    b = base::nullopt;
-    EXPECT_EQ(a, b);
-  }
-
-  {
-    Optional<std::string> a("foo");
-    Optional<std::string> b("bar");
-    a = base::nullopt;
-    b = base::nullopt;
-    EXPECT_EQ(a, b);
-  }
-
-  {
-    Optional<TestObject> a(TestObject(3, 0.1));
-    Optional<TestObject> b(TestObject(4, 1.0));
-    a = base::nullopt;
-    b = base::nullopt;
-    EXPECT_TRUE(a == b);
-  }
-}
-
-TEST(OptionalTest, AssignOverload) {
-  struct Test1 {
-    enum class State {
-      CONSTRUCTED,
-      MOVED,
-    };
-    State state = State::CONSTRUCTED;
-  };
-
-  // Here, Optional<Test2> can be assigned from Optioanl<Test1>.
-  // In case of move, marks MOVED to Test1 instance.
-  struct Test2 {
-    enum class State {
-      DEFAULT_CONSTRUCTED,
-      COPY_CONSTRUCTED_FROM_TEST1,
-      MOVE_CONSTRUCTED_FROM_TEST1,
-      COPY_ASSIGNED_FROM_TEST1,
-      MOVE_ASSIGNED_FROM_TEST1,
-    };
-
-    Test2() = default;
-    explicit Test2(const Test1&) : state(State::COPY_CONSTRUCTED_FROM_TEST1) {}
-    explicit Test2(Test1&& test1) : state(State::MOVE_CONSTRUCTED_FROM_TEST1) {
-      test1.state = Test1::State::MOVED;
-    }
-    Test2& operator=(const Test1&) {
-      state = State::COPY_ASSIGNED_FROM_TEST1;
-      return *this;
-    }
-    Test2& operator=(Test1&& test1) {
-      state = State::MOVE_ASSIGNED_FROM_TEST1;
-      test1.state = Test1::State::MOVED;
-      return *this;
-    }
-
-    State state = State::DEFAULT_CONSTRUCTED;
-  };
-
-  {
-    Optional<Test1> a(in_place);
-    Optional<Test2> b;
-
-    b = a;
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(Test1::State::CONSTRUCTED, a->state);
-    EXPECT_EQ(Test2::State::COPY_CONSTRUCTED_FROM_TEST1, b->state);
-  }
-
-  {
-    Optional<Test1> a(in_place);
-    Optional<Test2> b(in_place);
-
-    b = a;
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(Test1::State::CONSTRUCTED, a->state);
-    EXPECT_EQ(Test2::State::COPY_ASSIGNED_FROM_TEST1, b->state);
-  }
-
-  {
-    Optional<Test1> a(in_place);
-    Optional<Test2> b;
-
-    b = std::move(a);
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(Test1::State::MOVED, a->state);
-    EXPECT_EQ(Test2::State::MOVE_CONSTRUCTED_FROM_TEST1, b->state);
-  }
-
-  {
-    Optional<Test1> a(in_place);
-    Optional<Test2> b(in_place);
-
-    b = std::move(a);
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(Test1::State::MOVED, a->state);
-    EXPECT_EQ(Test2::State::MOVE_ASSIGNED_FROM_TEST1, b->state);
-  }
-
-  // Similar to Test2, but Test3 also has copy/move ctor and assign operators
-  // from Optional<Test1>, too. In this case, for a = b where a is
-  // Optional<Test3> and b is Optional<Test1>,
-  // Optional<T>::operator=(U&&) where U is Optional<Test1> should be used
-  // rather than Optional<T>::operator=(Optional<U>&&) where U is Test1.
-  struct Test3 {
-    enum class State {
-      DEFAULT_CONSTRUCTED,
-      COPY_CONSTRUCTED_FROM_TEST1,
-      MOVE_CONSTRUCTED_FROM_TEST1,
-      COPY_CONSTRUCTED_FROM_OPTIONAL_TEST1,
-      MOVE_CONSTRUCTED_FROM_OPTIONAL_TEST1,
-      COPY_ASSIGNED_FROM_TEST1,
-      MOVE_ASSIGNED_FROM_TEST1,
-      COPY_ASSIGNED_FROM_OPTIONAL_TEST1,
-      MOVE_ASSIGNED_FROM_OPTIONAL_TEST1,
-    };
-
-    Test3() = default;
-    explicit Test3(const Test1&) : state(State::COPY_CONSTRUCTED_FROM_TEST1) {}
-    explicit Test3(Test1&& test1) : state(State::MOVE_CONSTRUCTED_FROM_TEST1) {
-      test1.state = Test1::State::MOVED;
-    }
-    explicit Test3(const Optional<Test1>&)
-        : state(State::COPY_CONSTRUCTED_FROM_OPTIONAL_TEST1) {}
-    explicit Test3(Optional<Test1>&& test1)
-        : state(State::MOVE_CONSTRUCTED_FROM_OPTIONAL_TEST1) {
-      // In the following senarios, given |test1| should always have value.
-      PERFETTO_DCHECK(test1.has_value());
-      test1->state = Test1::State::MOVED;
-    }
-    Test3& operator=(const Test1&) {
-      state = State::COPY_ASSIGNED_FROM_TEST1;
-      return *this;
-    }
-    Test3& operator=(Test1&& test1) {
-      state = State::MOVE_ASSIGNED_FROM_TEST1;
-      test1.state = Test1::State::MOVED;
-      return *this;
-    }
-    Test3& operator=(const Optional<Test1>&) {
-      state = State::COPY_ASSIGNED_FROM_OPTIONAL_TEST1;
-      return *this;
-    }
-    Test3& operator=(Optional<Test1>&& test1) {
-      state = State::MOVE_ASSIGNED_FROM_OPTIONAL_TEST1;
-      // In the following senarios, given |test1| should always have value.
-      PERFETTO_DCHECK(test1.has_value());
-      test1->state = Test1::State::MOVED;
-      return *this;
-    }
-
-    State state = State::DEFAULT_CONSTRUCTED;
-  };
-
-  {
-    Optional<Test1> a(in_place);
-    Optional<Test3> b;
-
-    b = a;
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(Test1::State::CONSTRUCTED, a->state);
-    EXPECT_EQ(Test3::State::COPY_CONSTRUCTED_FROM_OPTIONAL_TEST1, b->state);
-  }
-
-  {
-    Optional<Test1> a(in_place);
-    Optional<Test3> b(in_place);
-
-    b = a;
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(Test1::State::CONSTRUCTED, a->state);
-    EXPECT_EQ(Test3::State::COPY_ASSIGNED_FROM_OPTIONAL_TEST1, b->state);
-  }
-
-  {
-    Optional<Test1> a(in_place);
-    Optional<Test3> b;
-
-    b = std::move(a);
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(Test1::State::MOVED, a->state);
-    EXPECT_EQ(Test3::State::MOVE_CONSTRUCTED_FROM_OPTIONAL_TEST1, b->state);
-  }
-
-  {
-    Optional<Test1> a(in_place);
-    Optional<Test3> b(in_place);
-
-    b = std::move(a);
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(!!b);
-    EXPECT_EQ(Test1::State::MOVED, a->state);
-    EXPECT_EQ(Test3::State::MOVE_ASSIGNED_FROM_OPTIONAL_TEST1, b->state);
-  }
-}
-
-TEST(OptionalTest, OperatorStar) {
-  {
-    Optional<float> a(0.1f);
-    EXPECT_EQ(a.value(), *a);
-  }
-
-  {
-    Optional<std::string> a("foo");
-    EXPECT_EQ(a.value(), *a);
-  }
-
-  {
-    Optional<TestObject> a(TestObject(3, 0.1));
-    EXPECT_EQ(a.value(), *a);
-  }
-}
-
-TEST(OptionalTest, OperatorStar_rvalue) {
-  EXPECT_EQ(0.1f, *Optional<float>(0.1f));
-  EXPECT_EQ(std::string("foo"), *Optional<std::string>("foo"));
-  EXPECT_TRUE(TestObject(3, 0.1) == *Optional<TestObject>(TestObject(3, 0.1)));
-}
-
-TEST(OptionalTest, OperatorArrow) {
-  Optional<TestObject> a(TestObject(3, 0.1));
-  EXPECT_EQ(a->foo(), 3);
-}
-
-TEST(OptionalTest, Value_rvalue) {
-  EXPECT_EQ(0.1f, Optional<float>(0.1f).value());
-  EXPECT_EQ(std::string("foo"), Optional<std::string>("foo").value());
-  EXPECT_TRUE(TestObject(3, 0.1) ==
-              Optional<TestObject>(TestObject(3, 0.1)).value());
-}
-
-TEST(OptionalTest, ValueOr) {
-  {
-    Optional<float> a;
-    EXPECT_EQ(0.0f, a.value_or(0.0f));
-
-    a = 0.1f;
-    EXPECT_EQ(0.1f, a.value_or(0.0f));
-
-    a = base::nullopt;
-    EXPECT_EQ(0.0f, a.value_or(0.0f));
-  }
-
-  // value_or() can be constexpr.
-  {
-    constexpr Optional<int> a(in_place, 1);
-    constexpr int value = a.value_or(10);
-    EXPECT_EQ(1, value);
-  }
-  {
-    constexpr Optional<int> a;
-    constexpr int value = a.value_or(10);
-    EXPECT_EQ(10, value);
-  }
-
-  {
-    Optional<std::string> a;
-    EXPECT_EQ("bar", a.value_or("bar"));
-
-    a = std::string("foo");
-    EXPECT_EQ(std::string("foo"), a.value_or("bar"));
-
-    a = base::nullopt;
-    EXPECT_EQ(std::string("bar"), a.value_or("bar"));
-  }
-
-  {
-    Optional<TestObject> a;
-    EXPECT_TRUE(a.value_or(TestObject(1, 0.3)) == TestObject(1, 0.3));
-
-    a = TestObject(3, 0.1);
-    EXPECT_TRUE(a.value_or(TestObject(1, 0.3)) == TestObject(3, 0.1));
-
-    a = base::nullopt;
-    EXPECT_TRUE(a.value_or(TestObject(1, 0.3)) == TestObject(1, 0.3));
-  }
-}
-
-TEST(OptionalTest, Swap_bothNoValue) {
-  Optional<TestObject> a, b;
-  a.swap(b);
-
-  EXPECT_FALSE(a);
-  EXPECT_FALSE(b);
-  EXPECT_TRUE(TestObject(42, 0.42) == a.value_or(TestObject(42, 0.42)));
-  EXPECT_TRUE(TestObject(42, 0.42) == b.value_or(TestObject(42, 0.42)));
-}
-
-TEST(OptionalTest, Swap_inHasValue) {
-  Optional<TestObject> a(TestObject(1, 0.3));
-  Optional<TestObject> b;
-  a.swap(b);
-
-  EXPECT_FALSE(a);
-
-  EXPECT_TRUE(!!b);
-  EXPECT_TRUE(TestObject(42, 0.42) == a.value_or(TestObject(42, 0.42)));
-  EXPECT_TRUE(TestObject(1, 0.3) == b.value_or(TestObject(42, 0.42)));
-}
-
-TEST(OptionalTest, Swap_outHasValue) {
-  Optional<TestObject> a;
-  Optional<TestObject> b(TestObject(1, 0.3));
-  a.swap(b);
-
-  EXPECT_TRUE(!!a);
-  EXPECT_FALSE(!!b);
-  EXPECT_TRUE(TestObject(1, 0.3) == a.value_or(TestObject(42, 0.42)));
-  EXPECT_TRUE(TestObject(42, 0.42) == b.value_or(TestObject(42, 0.42)));
-}
-
-TEST(OptionalTest, Swap_bothValue) {
-  Optional<TestObject> a(TestObject(0, 0.1));
-  Optional<TestObject> b(TestObject(1, 0.3));
-  a.swap(b);
-
-  EXPECT_TRUE(!!a);
-  EXPECT_TRUE(!!b);
-  EXPECT_TRUE(TestObject(1, 0.3) == a.value_or(TestObject(42, 0.42)));
-  EXPECT_TRUE(TestObject(0, 0.1) == b.value_or(TestObject(42, 0.42)));
-  EXPECT_EQ(TestObject::State::SWAPPED, a->state());
-  EXPECT_EQ(TestObject::State::SWAPPED, b->state());
-}
-
-TEST(OptionalTest, Emplace) {
-  {
-    Optional<float> a(0.1f);
-    EXPECT_EQ(0.3f, a.emplace(0.3f));
-
-    EXPECT_TRUE(a);
-    EXPECT_EQ(0.3f, a.value());
-  }
-
-  {
-    Optional<std::string> a("foo");
-    EXPECT_EQ("bar", a.emplace("bar"));
-
-    EXPECT_TRUE(a);
-    EXPECT_EQ("bar", a.value());
-  }
-
-  {
-    Optional<TestObject> a(TestObject(0, 0.1));
-    EXPECT_EQ(TestObject(1, 0.2), a.emplace(TestObject(1, 0.2)));
-
-    EXPECT_TRUE(!!a);
-    EXPECT_TRUE(TestObject(1, 0.2) == a.value());
-  }
-
-  {
-    Optional<std::vector<int>> a;
-    auto& ref = a.emplace({2, 3});
-    static_assert(std::is_same<std::vector<int>&, decltype(ref)>::value, "");
-    EXPECT_TRUE(a);
-    EXPECT_THAT(*a, ElementsAre(2, 3));
-    EXPECT_EQ(&ref, &*a);
-  }
-
-  {
-    Optional<std::vector<int>> a;
-    auto& ref = a.emplace({4, 5}, std::allocator<int>());
-    static_assert(std::is_same<std::vector<int>&, decltype(ref)>::value, "");
-    EXPECT_TRUE(a);
-    EXPECT_THAT(*a, ElementsAre(4, 5));
-    EXPECT_EQ(&ref, &*a);
-  }
-}
-
-TEST(OptionalTest, Equals_TwoEmpty) {
-  Optional<int> a;
-  Optional<int> b;
-
-  EXPECT_TRUE(a == b);
-}
-
-TEST(OptionalTest, Equals_TwoEquals) {
-  Optional<int> a(1);
-  Optional<int> b(1);
-
-  EXPECT_TRUE(a == b);
-}
-
-TEST(OptionalTest, Equals_OneEmpty) {
-  Optional<int> a;
-  Optional<int> b(1);
-
-  EXPECT_FALSE(a == b);
-}
-
-TEST(OptionalTest, Equals_TwoDifferent) {
-  Optional<int> a(0);
-  Optional<int> b(1);
-
-  EXPECT_FALSE(a == b);
-}
-
-TEST(OptionalTest, Equals_DifferentType) {
-  Optional<int> a(0);
-  Optional<double> b(0);
-
-  EXPECT_TRUE(a == b);
-}
-
-TEST(OptionalTest, NotEquals_TwoEmpty) {
-  Optional<int> a;
-  Optional<int> b;
-
-  EXPECT_FALSE(a != b);
-}
-
-TEST(OptionalTest, NotEquals_TwoEquals) {
-  Optional<int> a(1);
-  Optional<int> b(1);
-
-  EXPECT_FALSE(a != b);
-}
-
-TEST(OptionalTest, NotEquals_OneEmpty) {
-  Optional<int> a;
-  Optional<int> b(1);
-
-  EXPECT_TRUE(a != b);
-}
-
-TEST(OptionalTest, NotEquals_TwoDifferent) {
-  Optional<int> a(0);
-  Optional<int> b(1);
-
-  EXPECT_TRUE(a != b);
-}
-
-TEST(OptionalTest, NotEquals_DifferentType) {
-  Optional<int> a(0);
-  Optional<double> b(0.0);
-
-  EXPECT_FALSE(a != b);
-}
-
-TEST(OptionalTest, Less_LeftEmpty) {
-  Optional<int> l;
-  Optional<int> r(1);
-
-  EXPECT_TRUE(l < r);
-}
-
-TEST(OptionalTest, Less_RightEmpty) {
-  Optional<int> l(1);
-  Optional<int> r;
-
-  EXPECT_FALSE(l < r);
-}
-
-TEST(OptionalTest, Less_BothEmpty) {
-  Optional<int> l;
-  Optional<int> r;
-
-  EXPECT_FALSE(l < r);
-}
-
-TEST(OptionalTest, Less_BothValues) {
-  {
-    Optional<int> l(1);
-    Optional<int> r(2);
-
-    EXPECT_TRUE(l < r);
-  }
-  {
-    Optional<int> l(2);
-    Optional<int> r(1);
-
-    EXPECT_FALSE(l < r);
-  }
-  {
-    Optional<int> l(1);
-    Optional<int> r(1);
-
-    EXPECT_FALSE(l < r);
-  }
-}
-
-TEST(OptionalTest, Less_DifferentType) {
-  Optional<int> l(1);
-  Optional<double> r(2.0);
-
-  EXPECT_TRUE(l < r);
-}
-
-TEST(OptionalTest, LessEq_LeftEmpty) {
-  Optional<int> l;
-  Optional<int> r(1);
-
-  EXPECT_TRUE(l <= r);
-}
-
-TEST(OptionalTest, LessEq_RightEmpty) {
-  Optional<int> l(1);
-  Optional<int> r;
-
-  EXPECT_FALSE(l <= r);
-}
-
-TEST(OptionalTest, LessEq_BothEmpty) {
-  Optional<int> l;
-  Optional<int> r;
-
-  EXPECT_TRUE(l <= r);
-}
-
-TEST(OptionalTest, LessEq_BothValues) {
-  {
-    Optional<int> l(1);
-    Optional<int> r(2);
-
-    EXPECT_TRUE(l <= r);
-  }
-  {
-    Optional<int> l(2);
-    Optional<int> r(1);
-
-    EXPECT_FALSE(l <= r);
-  }
-  {
-    Optional<int> l(1);
-    Optional<int> r(1);
-
-    EXPECT_TRUE(l <= r);
-  }
-}
-
-TEST(OptionalTest, LessEq_DifferentType) {
-  Optional<int> l(1);
-  Optional<double> r(2.0);
-
-  EXPECT_TRUE(l <= r);
-}
-
-TEST(OptionalTest, Greater_BothEmpty) {
-  Optional<int> l;
-  Optional<int> r;
-
-  EXPECT_FALSE(l > r);
-}
-
-TEST(OptionalTest, Greater_LeftEmpty) {
-  Optional<int> l;
-  Optional<int> r(1);
-
-  EXPECT_FALSE(l > r);
-}
-
-TEST(OptionalTest, Greater_RightEmpty) {
-  Optional<int> l(1);
-  Optional<int> r;
-
-  EXPECT_TRUE(l > r);
-}
-
-TEST(OptionalTest, Greater_BothValue) {
-  {
-    Optional<int> l(1);
-    Optional<int> r(2);
-
-    EXPECT_FALSE(l > r);
-  }
-  {
-    Optional<int> l(2);
-    Optional<int> r(1);
-
-    EXPECT_TRUE(l > r);
-  }
-  {
-    Optional<int> l(1);
-    Optional<int> r(1);
-
-    EXPECT_FALSE(l > r);
-  }
-}
-
-TEST(OptionalTest, Greater_DifferentType) {
-  Optional<int> l(1);
-  Optional<double> r(2.0);
-
-  EXPECT_FALSE(l > r);
-}
-
-TEST(OptionalTest, GreaterEq_BothEmpty) {
-  Optional<int> l;
-  Optional<int> r;
-
-  EXPECT_TRUE(l >= r);
-}
-
-TEST(OptionalTest, GreaterEq_LeftEmpty) {
-  Optional<int> l;
-  Optional<int> r(1);
-
-  EXPECT_FALSE(l >= r);
-}
-
-TEST(OptionalTest, GreaterEq_RightEmpty) {
-  Optional<int> l(1);
-  Optional<int> r;
-
-  EXPECT_TRUE(l >= r);
-}
-
-TEST(OptionalTest, GreaterEq_BothValue) {
-  {
-    Optional<int> l(1);
-    Optional<int> r(2);
-
-    EXPECT_FALSE(l >= r);
-  }
-  {
-    Optional<int> l(2);
-    Optional<int> r(1);
-
-    EXPECT_TRUE(l >= r);
-  }
-  {
-    Optional<int> l(1);
-    Optional<int> r(1);
-
-    EXPECT_TRUE(l >= r);
-  }
-}
-
-TEST(OptionalTest, GreaterEq_DifferentType) {
-  Optional<int> l(1);
-  Optional<double> r(2.0);
-
-  EXPECT_FALSE(l >= r);
-}
-
-TEST(OptionalTest, OptNullEq) {
-  {
-    Optional<int> opt;
-    EXPECT_TRUE(opt == base::nullopt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_FALSE(opt == base::nullopt);
-  }
-}
-
-TEST(OptionalTest, NullOptEq) {
-  {
-    Optional<int> opt;
-    EXPECT_TRUE(base::nullopt == opt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_FALSE(base::nullopt == opt);
-  }
-}
-
-TEST(OptionalTest, OptNullNotEq) {
-  {
-    Optional<int> opt;
-    EXPECT_FALSE(opt != base::nullopt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_TRUE(opt != base::nullopt);
-  }
-}
-
-TEST(OptionalTest, NullOptNotEq) {
-  {
-    Optional<int> opt;
-    EXPECT_FALSE(base::nullopt != opt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_TRUE(base::nullopt != opt);
-  }
-}
-
-TEST(OptionalTest, OptNullLower) {
-  {
-    Optional<int> opt;
-    EXPECT_FALSE(opt < base::nullopt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_FALSE(opt < base::nullopt);
-  }
-}
-
-TEST(OptionalTest, NullOptLower) {
-  {
-    Optional<int> opt;
-    EXPECT_FALSE(base::nullopt < opt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_TRUE(base::nullopt < opt);
-  }
-}
-
-TEST(OptionalTest, OptNullLowerEq) {
-  {
-    Optional<int> opt;
-    EXPECT_TRUE(opt <= base::nullopt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_FALSE(opt <= base::nullopt);
-  }
-}
-
-TEST(OptionalTest, NullOptLowerEq) {
-  {
-    Optional<int> opt;
-    EXPECT_TRUE(base::nullopt <= opt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_TRUE(base::nullopt <= opt);
-  }
-}
-
-TEST(OptionalTest, OptNullGreater) {
-  {
-    Optional<int> opt;
-    EXPECT_FALSE(opt > base::nullopt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_TRUE(opt > base::nullopt);
-  }
-}
-
-TEST(OptionalTest, NullOptGreater) {
-  {
-    Optional<int> opt;
-    EXPECT_FALSE(base::nullopt > opt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_FALSE(base::nullopt > opt);
-  }
-}
-
-TEST(OptionalTest, OptNullGreaterEq) {
-  {
-    Optional<int> opt;
-    EXPECT_TRUE(opt >= base::nullopt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_TRUE(opt >= base::nullopt);
-  }
-}
-
-TEST(OptionalTest, NullOptGreaterEq) {
-  {
-    Optional<int> opt;
-    EXPECT_TRUE(base::nullopt >= opt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_FALSE(base::nullopt >= opt);
-  }
-}
-
-TEST(OptionalTest, ValueEq_Empty) {
-  Optional<int> opt;
-  EXPECT_FALSE(opt == 1);
-}
-
-TEST(OptionalTest, ValueEq_NotEmpty) {
-  {
-    Optional<int> opt(0);
-    EXPECT_FALSE(opt == 1);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_TRUE(opt == 1);
-  }
-}
-
-TEST(OptionalTest, ValueEq_DifferentType) {
-  Optional<int> opt(0);
-  EXPECT_TRUE(opt == 0.0);
-}
-
-TEST(OptionalTest, EqValue_Empty) {
-  Optional<int> opt;
-  EXPECT_FALSE(1 == opt);
-}
-
-TEST(OptionalTest, EqValue_NotEmpty) {
-  {
-    Optional<int> opt(0);
-    EXPECT_FALSE(1 == opt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_TRUE(1 == opt);
-  }
-}
-
-TEST(OptionalTest, EqValue_DifferentType) {
-  Optional<int> opt(0);
-  EXPECT_TRUE(0.0 == opt);
-}
-
-TEST(OptionalTest, ValueNotEq_Empty) {
-  Optional<int> opt;
-  EXPECT_TRUE(opt != 1);
-}
-
-TEST(OptionalTest, ValueNotEq_NotEmpty) {
-  {
-    Optional<int> opt(0);
-    EXPECT_TRUE(opt != 1);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_FALSE(opt != 1);
-  }
-}
-
-TEST(OPtionalTest, ValueNotEq_DifferentType) {
-  Optional<int> opt(0);
-  EXPECT_FALSE(opt != 0.0);
-}
-
-TEST(OptionalTest, NotEqValue_Empty) {
-  Optional<int> opt;
-  EXPECT_TRUE(1 != opt);
-}
-
-TEST(OptionalTest, NotEqValue_NotEmpty) {
-  {
-    Optional<int> opt(0);
-    EXPECT_TRUE(1 != opt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_FALSE(1 != opt);
-  }
-}
-
-TEST(OptionalTest, NotEqValue_DifferentType) {
-  Optional<int> opt(0);
-  EXPECT_FALSE(0.0 != opt);
-}
-
-TEST(OptionalTest, ValueLess_Empty) {
-  Optional<int> opt;
-  EXPECT_TRUE(opt < 1);
-}
-
-TEST(OptionalTest, ValueLess_NotEmpty) {
-  {
-    Optional<int> opt(0);
-    EXPECT_TRUE(opt < 1);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_FALSE(opt < 1);
-  }
-  {
-    Optional<int> opt(2);
-    EXPECT_FALSE(opt < 1);
-  }
-}
-
-TEST(OPtionalTest, ValueLess_DifferentType) {
-  Optional<int> opt(0);
-  EXPECT_TRUE(opt < 1.0);
-}
-
-TEST(OptionalTest, LessValue_Empty) {
-  Optional<int> opt;
-  EXPECT_FALSE(1 < opt);
-}
-
-TEST(OptionalTest, LessValue_NotEmpty) {
-  {
-    Optional<int> opt(0);
-    EXPECT_FALSE(1 < opt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_FALSE(1 < opt);
-  }
-  {
-    Optional<int> opt(2);
-    EXPECT_TRUE(1 < opt);
-  }
-}
-
-TEST(OptionalTest, LessValue_DifferentType) {
-  Optional<int> opt(0);
-  EXPECT_FALSE(0.0 < opt);
-}
-
-TEST(OptionalTest, ValueLessEq_Empty) {
-  Optional<int> opt;
-  EXPECT_TRUE(opt <= 1);
-}
-
-TEST(OptionalTest, ValueLessEq_NotEmpty) {
-  {
-    Optional<int> opt(0);
-    EXPECT_TRUE(opt <= 1);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_TRUE(opt <= 1);
-  }
-  {
-    Optional<int> opt(2);
-    EXPECT_FALSE(opt <= 1);
-  }
-}
-
-TEST(OptionalTest, ValueLessEq_DifferentType) {
-  Optional<int> opt(0);
-  EXPECT_TRUE(opt <= 0.0);
-}
-
-TEST(OptionalTest, LessEqValue_Empty) {
-  Optional<int> opt;
-  EXPECT_FALSE(1 <= opt);
-}
-
-TEST(OptionalTest, LessEqValue_NotEmpty) {
-  {
-    Optional<int> opt(0);
-    EXPECT_FALSE(1 <= opt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_TRUE(1 <= opt);
-  }
-  {
-    Optional<int> opt(2);
-    EXPECT_TRUE(1 <= opt);
-  }
-}
-
-TEST(OptionalTest, LessEqValue_DifferentType) {
-  Optional<int> opt(0);
-  EXPECT_TRUE(0.0 <= opt);
-}
-
-TEST(OptionalTest, ValueGreater_Empty) {
-  Optional<int> opt;
-  EXPECT_FALSE(opt > 1);
-}
-
-TEST(OptionalTest, ValueGreater_NotEmpty) {
-  {
-    Optional<int> opt(0);
-    EXPECT_FALSE(opt > 1);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_FALSE(opt > 1);
-  }
-  {
-    Optional<int> opt(2);
-    EXPECT_TRUE(opt > 1);
-  }
-}
-
-TEST(OptionalTest, ValueGreater_DifferentType) {
-  Optional<int> opt(0);
-  EXPECT_FALSE(opt > 0.0);
-}
-
-TEST(OptionalTest, GreaterValue_Empty) {
-  Optional<int> opt;
-  EXPECT_TRUE(1 > opt);
-}
-
-TEST(OptionalTest, GreaterValue_NotEmpty) {
-  {
-    Optional<int> opt(0);
-    EXPECT_TRUE(1 > opt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_FALSE(1 > opt);
-  }
-  {
-    Optional<int> opt(2);
-    EXPECT_FALSE(1 > opt);
-  }
-}
-
-TEST(OptionalTest, GreaterValue_DifferentType) {
-  Optional<int> opt(0);
-  EXPECT_FALSE(0.0 > opt);
-}
-
-TEST(OptionalTest, ValueGreaterEq_Empty) {
-  Optional<int> opt;
-  EXPECT_FALSE(opt >= 1);
-}
-
-TEST(OptionalTest, ValueGreaterEq_NotEmpty) {
-  {
-    Optional<int> opt(0);
-    EXPECT_FALSE(opt >= 1);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_TRUE(opt >= 1);
-  }
-  {
-    Optional<int> opt(2);
-    EXPECT_TRUE(opt >= 1);
-  }
-}
-
-TEST(OptionalTest, ValueGreaterEq_DifferentType) {
-  Optional<int> opt(0);
-  EXPECT_TRUE(opt <= 0.0);
-}
-
-TEST(OptionalTest, GreaterEqValue_Empty) {
-  Optional<int> opt;
-  EXPECT_TRUE(1 >= opt);
-}
-
-TEST(OptionalTest, GreaterEqValue_NotEmpty) {
-  {
-    Optional<int> opt(0);
-    EXPECT_TRUE(1 >= opt);
-  }
-  {
-    Optional<int> opt(1);
-    EXPECT_TRUE(1 >= opt);
-  }
-  {
-    Optional<int> opt(2);
-    EXPECT_FALSE(1 >= opt);
-  }
-}
-
-TEST(OptionalTest, GreaterEqValue_DifferentType) {
-  Optional<int> opt(0);
-  EXPECT_TRUE(0.0 >= opt);
-}
-
-TEST(OptionalTest, NotEquals) {
-  {
-    Optional<float> a(0.1f);
-    Optional<float> b(0.2f);
-    EXPECT_NE(a, b);
-  }
-
-  {
-    Optional<std::string> a("foo");
-    Optional<std::string> b("bar");
-    EXPECT_NE(a, b);
-  }
-
-  {
-    Optional<int> a(1);
-    Optional<double> b(2);
-    EXPECT_NE(a, b);
-  }
-
-  {
-    Optional<TestObject> a(TestObject(3, 0.1));
-    Optional<TestObject> b(TestObject(4, 1.0));
-    EXPECT_TRUE(a != b);
-  }
-}
-
-TEST(OptionalTest, NotEqualsNull) {
-  {
-    Optional<float> a(0.1f);
-    Optional<float> b(0.1f);
-    b = base::nullopt;
-    EXPECT_NE(a, b);
-  }
-
-  {
-    Optional<std::string> a("foo");
-    Optional<std::string> b("foo");
-    b = base::nullopt;
-    EXPECT_NE(a, b);
-  }
-
-  {
-    Optional<TestObject> a(TestObject(3, 0.1));
-    Optional<TestObject> b(TestObject(3, 0.1));
-    b = base::nullopt;
-    EXPECT_TRUE(a != b);
-  }
-}
-
-TEST(OptionalTest, MakeOptional) {
-  {
-    // Use qualified base::make_optional here and elsewhere to avoid the name
-    // confliction to std::make_optional.
-    // The name conflict happens only for types in std namespace, such as
-    // std::string. The other qualified base::make_optional usages are just for
-    // consistency.
-    Optional<float> o = base::make_optional(32.f);
-    EXPECT_TRUE(o);
-    EXPECT_EQ(32.f, *o);
-
-    float value = 3.f;
-    o = base::make_optional(std::move(value));
-    EXPECT_TRUE(o);
-    EXPECT_EQ(3.f, *o);
-  }
-
-  {
-    Optional<std::string> o = base::make_optional(std::string("foo"));
-    EXPECT_TRUE(o);
-    EXPECT_EQ("foo", *o);
-
-    std::string value = "bar";
-    o = base::make_optional(std::move(value));
-    EXPECT_TRUE(o);
-    EXPECT_EQ(std::string("bar"), *o);
-  }
-
-  {
-    Optional<TestObject> o = base::make_optional(TestObject(3, 0.1));
-    EXPECT_TRUE(!!o);
-    EXPECT_TRUE(TestObject(3, 0.1) == *o);
-
-    TestObject value = TestObject(0, 0.42);
-    o = base::make_optional(std::move(value));
-    EXPECT_TRUE(!!o);
-    EXPECT_TRUE(TestObject(0, 0.42) == *o);
-    EXPECT_EQ(TestObject::State::MOVED_FROM, value.state());
-    EXPECT_EQ(TestObject::State::MOVE_ASSIGNED, o->state());
-
-    EXPECT_EQ(TestObject::State::MOVE_CONSTRUCTED,
-              base::make_optional(std::move(value))->state());
-  }
-
-  {
-    struct Test {
-      Test(int x, double y, bool z) : a(x), b(y), c(z) {}
-
-      int a;
-      double b;
-      bool c;
-    };
-
-    Optional<Test> o = base::make_optional<Test>(1, 2.0, true);
-    EXPECT_TRUE(!!o);
-    EXPECT_EQ(1, o->a);
-    EXPECT_EQ(2.0, o->b);
-    EXPECT_TRUE(o->c);
-  }
-
-  {
-    auto str1 = base::make_optional<std::string>({'1', '2', '3'});
-    EXPECT_EQ("123", *str1);
-
-    auto str2 = base::make_optional<std::string>({'a', 'b', 'c'},
-                                                 std::allocator<char>());
-    EXPECT_EQ("abc", *str2);
-  }
-}
-
-TEST(OptionalTest, NonMemberSwap_bothNoValue) {
-  Optional<TestObject> a, b;
-  base::swap(a, b);
-
-  EXPECT_FALSE(!!a);
-  EXPECT_FALSE(!!b);
-  EXPECT_TRUE(TestObject(42, 0.42) == a.value_or(TestObject(42, 0.42)));
-  EXPECT_TRUE(TestObject(42, 0.42) == b.value_or(TestObject(42, 0.42)));
-}
-
-TEST(OptionalTest, NonMemberSwap_inHasValue) {
-  Optional<TestObject> a(TestObject(1, 0.3));
-  Optional<TestObject> b;
-  base::swap(a, b);
-
-  EXPECT_FALSE(!!a);
-  EXPECT_TRUE(!!b);
-  EXPECT_TRUE(TestObject(42, 0.42) == a.value_or(TestObject(42, 0.42)));
-  EXPECT_TRUE(TestObject(1, 0.3) == b.value_or(TestObject(42, 0.42)));
-}
-
-TEST(OptionalTest, NonMemberSwap_outHasValue) {
-  Optional<TestObject> a;
-  Optional<TestObject> b(TestObject(1, 0.3));
-  base::swap(a, b);
-
-  EXPECT_TRUE(!!a);
-  EXPECT_FALSE(!!b);
-  EXPECT_TRUE(TestObject(1, 0.3) == a.value_or(TestObject(42, 0.42)));
-  EXPECT_TRUE(TestObject(42, 0.42) == b.value_or(TestObject(42, 0.42)));
-}
-
-TEST(OptionalTest, NonMemberSwap_bothValue) {
-  Optional<TestObject> a(TestObject(0, 0.1));
-  Optional<TestObject> b(TestObject(1, 0.3));
-  base::swap(a, b);
-
-  EXPECT_TRUE(!!a);
-  EXPECT_TRUE(!!b);
-  EXPECT_TRUE(TestObject(1, 0.3) == a.value_or(TestObject(42, 0.42)));
-  EXPECT_TRUE(TestObject(0, 0.1) == b.value_or(TestObject(42, 0.42)));
-  EXPECT_EQ(TestObject::State::SWAPPED, a->state());
-  EXPECT_EQ(TestObject::State::SWAPPED, b->state());
-}
-
-TEST(OptionalTest, Hash_OptionalReflectsInternal) {
-  {
-    std::hash<int> int_hash;
-    std::hash<Optional<int>> opt_int_hash;
-
-    EXPECT_EQ(int_hash(1), opt_int_hash(Optional<int>(1)));
-  }
-
-  {
-    std::hash<std::string> str_hash;
-    std::hash<Optional<std::string>> opt_str_hash;
-
-    EXPECT_EQ(str_hash(std::string("foobar")),
-              opt_str_hash(Optional<std::string>(std::string("foobar"))));
-  }
-}
-
-TEST(OptionalTest, Hash_NullOptEqualsNullOpt) {
-  std::hash<Optional<int>> opt_int_hash;
-  std::hash<Optional<std::string>> opt_str_hash;
-
-  EXPECT_EQ(opt_str_hash(Optional<std::string>()),
-            opt_int_hash(Optional<int>()));
-}
-
-TEST(OptionalTest, Hash_UseInSet) {
-  std::set<Optional<int>> setOptInt;
-
-  EXPECT_EQ(setOptInt.end(), setOptInt.find(42));
-
-  setOptInt.insert(Optional<int>(3));
-  EXPECT_EQ(setOptInt.end(), setOptInt.find(42));
-  EXPECT_NE(setOptInt.end(), setOptInt.find(3));
-}
-
-TEST(OptionalTest, HasValue) {
-  Optional<int> a;
-  EXPECT_FALSE(a.has_value());
-
-  a = 42;
-  EXPECT_TRUE(a.has_value());
-
-  a = nullopt;
-  EXPECT_FALSE(a.has_value());
-
-  a = 0;
-  EXPECT_TRUE(a.has_value());
-
-  a = Optional<int>();
-  EXPECT_FALSE(a.has_value());
-}
-
-TEST(OptionalTest, Reset_int) {
-  Optional<int> a(0);
-  EXPECT_TRUE(a.has_value());
-  EXPECT_EQ(0, a.value());
-
-  a.reset();
-  EXPECT_FALSE(a.has_value());
-  EXPECT_EQ(-1, a.value_or(-1));
-}
-
-TEST(OptionalTest, Reset_Object) {
-  Optional<TestObject> a(TestObject(0, 0.1));
-  EXPECT_TRUE(a.has_value());
-  EXPECT_EQ(TestObject(0, 0.1), a.value());
-
-  a.reset();
-  EXPECT_FALSE(a.has_value());
-  EXPECT_EQ(TestObject(42, 0.0), a.value_or(TestObject(42, 0.0)));
-}
-
-TEST(OptionalTest, Reset_NoOp) {
-  Optional<int> a;
-  EXPECT_FALSE(a.has_value());
-
-  a.reset();
-  EXPECT_FALSE(a.has_value());
-}
-
-TEST(OptionalTest, AssignFromRValue) {
-  Optional<TestObject> a;
-  EXPECT_FALSE(a.has_value());
-
-  TestObject obj;
-  a = std::move(obj);
-  EXPECT_TRUE(a.has_value());
-  EXPECT_EQ(1, a->move_ctors_count());
-}
-
-TEST(OptionalTest, DontCallDefaultCtor) {
-  Optional<DeletedDefaultConstructor> a;
-  EXPECT_FALSE(a.has_value());
-
-  a = base::make_optional<DeletedDefaultConstructor>(42);
-  EXPECT_TRUE(a.has_value());
-  EXPECT_EQ(42, a->foo());
-}
-
-TEST(OptionalTest, DontCallNewMemberFunction) {
-  Optional<DeleteNewOperators> a;
-  EXPECT_FALSE(a.has_value());
-
-  a = DeleteNewOperators();
-  EXPECT_TRUE(a.has_value());
-}
-
-TEST(OptionalTest, Noexcept) {
-  // Trivial copy ctor, non-trivial move ctor, nothrow move assign.
-  struct Test1 {
-    Test1(const Test1&) = default;
-    Test1(Test1&&) {}
-    Test1& operator=(Test1&&) = default;
-  };
-  // Non-trivial copy ctor, trivial move ctor, throw move assign.
-  struct Test2 {
-    Test2(const Test2&) {}
-    Test2(Test2&&) = default;
-    Test2& operator=(Test2&&) { return *this; }
-  };
-  // Trivial copy ctor, non-trivial nothrow move ctor.
-  struct Test3 {
-    Test3(const Test3&) = default;
-    Test3(Test3&&) noexcept {}
-  };
-  // Non-trivial copy ctor, non-trivial nothrow move ctor.
-  struct Test4 {
-    Test4(const Test4&) {}
-    Test4(Test4&&) noexcept {}
-  };
-  // Non-trivial copy ctor, non-trivial move ctor.
-  struct Test5 {
-    Test5(const Test5&) {}
-    Test5(Test5&&) {}
-  };
-
-  static_assert(
-      noexcept(Optional<int>(std::declval<Optional<int>>())),
-      "move constructor for noexcept move-constructible T must be noexcept "
-      "(trivial copy, trivial move)");
-  static_assert(
-      !noexcept(Optional<Test1>(std::declval<Optional<Test1>>())),
-      "move constructor for non-noexcept move-constructible T must not be "
-      "noexcept (trivial copy)");
-  static_assert(
-      noexcept(Optional<Test2>(std::declval<Optional<Test2>>())),
-      "move constructor for noexcept move-constructible T must be noexcept "
-      "(non-trivial copy, trivial move)");
-  static_assert(
-      noexcept(Optional<Test3>(std::declval<Optional<Test3>>())),
-      "move constructor for noexcept move-constructible T must be noexcept "
-      "(trivial copy, non-trivial move)");
-  static_assert(
-      noexcept(Optional<Test4>(std::declval<Optional<Test4>>())),
-      "move constructor for noexcept move-constructible T must be noexcept "
-      "(non-trivial copy, non-trivial move)");
-  static_assert(
-      !noexcept(Optional<Test5>(std::declval<Optional<Test5>>())),
-      "move constructor for non-noexcept move-constructible T must not be "
-      "noexcept (non-trivial copy)");
-
-  static_assert(
-      noexcept(std::declval<Optional<int>>() = std::declval<Optional<int>>()),
-      "move assign for noexcept move-constructible/move-assignable T "
-      "must be noexcept");
-  static_assert(
-      !noexcept(std::declval<Optional<Test1>>() =
-                    std::declval<Optional<Test1>>()),
-      "move assign for non-noexcept move-constructible T must not be noexcept");
-  static_assert(
-      !noexcept(std::declval<Optional<Test2>>() =
-                    std::declval<Optional<Test2>>()),
-      "move assign for non-noexcept move-assignable T must not be noexcept");
-}
-
-}  // namespace base
-}  // namespace perfetto
-
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
diff --git a/src/base/string_utils.cc b/src/base/string_utils.cc
index 851b60c..ba6e52b 100644
--- a/src/base/string_utils.cc
+++ b/src/base/string_utils.cc
@@ -245,8 +245,8 @@
   return res;
 }
 
-base::Optional<LineWithOffset> FindLineWithOffset(base::StringView str,
-                                                  uint32_t offset) {
+std::optional<LineWithOffset> FindLineWithOffset(base::StringView str,
+                                                 uint32_t offset) {
   static constexpr char kNewLine = '\n';
   uint32_t line_offset = 0;
   uint32_t line_count = 1;
@@ -265,7 +265,7 @@
       return LineWithOffset{line, offset - line_offset, line_count};
     }
   }
-  return base::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace base
diff --git a/src/base/string_utils_unittest.cc b/src/base/string_utils_unittest.cc
index 2cc4b06..f65da9f 100644
--- a/src/base/string_utils_unittest.cc
+++ b/src/base/string_utils_unittest.cc
@@ -16,10 +16,9 @@
 
 #include "perfetto/ext/base/string_utils.h"
 
+#include <optional>
 #include "test/gtest_and_gmock.h"
 
-#include "perfetto/ext/base/optional.h"
-
 namespace perfetto {
 namespace base {
 namespace {
@@ -50,23 +49,23 @@
 }
 
 TEST(StringUtilsTest, CStringToUInt32) {
-  EXPECT_EQ(CStringToUInt32("0"), make_optional<uint32_t>(0U));
-  EXPECT_EQ(CStringToUInt32("1"), make_optional<uint32_t>(1U));
-  EXPECT_EQ(CStringToUInt32("42"), make_optional<uint32_t>(42U));
-  EXPECT_EQ(CStringToUInt32(""), nullopt);
-  EXPECT_EQ(CStringToUInt32("!?"), nullopt);
-  EXPECT_EQ(CStringToUInt32("abc"), nullopt);
-  EXPECT_EQ(CStringToUInt32("123 abc"), nullopt);
+  EXPECT_EQ(CStringToUInt32("0"), std::make_optional<uint32_t>(0U));
+  EXPECT_EQ(CStringToUInt32("1"), std::make_optional<uint32_t>(1U));
+  EXPECT_EQ(CStringToUInt32("42"), std::make_optional<uint32_t>(42U));
+  EXPECT_EQ(CStringToUInt32(""), std::nullopt);
+  EXPECT_EQ(CStringToUInt32("!?"), std::nullopt);
+  EXPECT_EQ(CStringToUInt32("abc"), std::nullopt);
+  EXPECT_EQ(CStringToUInt32("123 abc"), std::nullopt);
 }
 
 TEST(StringUtilsTest, CStringToInt32) {
-  EXPECT_EQ(CStringToInt32("0"), make_optional<int32_t>(0));
-  EXPECT_EQ(CStringToInt32("1"), make_optional<int32_t>(1));
-  EXPECT_EQ(CStringToInt32("-42"), make_optional<int32_t>(-42));
-  EXPECT_EQ(CStringToInt32(""), nullopt);
-  EXPECT_EQ(CStringToInt32("!?"), nullopt);
-  EXPECT_EQ(CStringToInt32("abc"), nullopt);
-  EXPECT_EQ(CStringToInt32("123 abc"), nullopt);
+  EXPECT_EQ(CStringToInt32("0"), std::make_optional<int32_t>(0));
+  EXPECT_EQ(CStringToInt32("1"), std::make_optional<int32_t>(1));
+  EXPECT_EQ(CStringToInt32("-42"), std::make_optional<int32_t>(-42));
+  EXPECT_EQ(CStringToInt32(""), std::nullopt);
+  EXPECT_EQ(CStringToInt32("!?"), std::nullopt);
+  EXPECT_EQ(CStringToInt32("abc"), std::nullopt);
+  EXPECT_EQ(CStringToInt32("123 abc"), std::nullopt);
 }
 
 TEST(StringUtilsTest, CStringToDouble) {
@@ -74,66 +73,68 @@
   EXPECT_DOUBLE_EQ(CStringToDouble("1").value(), 1l);
   EXPECT_DOUBLE_EQ(CStringToDouble("-42").value(), -42l);
   EXPECT_DOUBLE_EQ(CStringToDouble("-42.5").value(), -42.5l);
-  EXPECT_EQ(CStringToDouble(""), nullopt);
-  EXPECT_EQ(CStringToDouble("!?"), nullopt);
-  EXPECT_EQ(CStringToDouble("abc"), nullopt);
-  EXPECT_EQ(CStringToDouble("123 abc"), nullopt);
+  EXPECT_EQ(CStringToDouble(""), std::nullopt);
+  EXPECT_EQ(CStringToDouble("!?"), std::nullopt);
+  EXPECT_EQ(CStringToDouble("abc"), std::nullopt);
+  EXPECT_EQ(CStringToDouble("123 abc"), std::nullopt);
 }
 
 TEST(StringUtilsTest, StringToUInt32) {
-  EXPECT_EQ(StringToUInt32("0"), make_optional<uint32_t>(0U));
-  EXPECT_EQ(StringToUInt32("1"), make_optional<uint32_t>(1U));
-  EXPECT_EQ(StringToUInt32("42"), make_optional<uint32_t>(42U));
-  EXPECT_EQ(StringToUInt32("a", 16), make_optional<uint32_t>(10U));
+  EXPECT_EQ(StringToUInt32("0"), std::make_optional<uint32_t>(0U));
+  EXPECT_EQ(StringToUInt32("1"), std::make_optional<uint32_t>(1U));
+  EXPECT_EQ(StringToUInt32("42"), std::make_optional<uint32_t>(42U));
+  EXPECT_EQ(StringToUInt32("a", 16), std::make_optional<uint32_t>(10U));
   EXPECT_EQ(StringToUInt32("fffffff0", 16),
-            make_optional<uint32_t>(0xfffffff0));
-  EXPECT_EQ(StringToUInt32(""), nullopt);
-  EXPECT_EQ(StringToUInt32("!?"), nullopt);
-  EXPECT_EQ(StringToUInt32("abc"), nullopt);
-  EXPECT_EQ(StringToUInt32("123 abc"), nullopt);
-  EXPECT_EQ(StringToUInt32("beefz", 16), nullopt);
+            std::make_optional<uint32_t>(0xfffffff0));
+  EXPECT_EQ(StringToUInt32(""), std::nullopt);
+  EXPECT_EQ(StringToUInt32("!?"), std::nullopt);
+  EXPECT_EQ(StringToUInt32("abc"), std::nullopt);
+  EXPECT_EQ(StringToUInt32("123 abc"), std::nullopt);
+  EXPECT_EQ(StringToUInt32("beefz", 16), std::nullopt);
 }
 
 TEST(StringUtilsTest, StringToInt32) {
-  EXPECT_EQ(StringToInt32("0"), make_optional<int32_t>(0));
-  EXPECT_EQ(StringToInt32("1"), make_optional<int32_t>(1));
-  EXPECT_EQ(StringToInt32("-42"), make_optional<int32_t>(-42));
-  EXPECT_EQ(StringToInt32("42", 16), make_optional<int32_t>(0x42));
-  EXPECT_EQ(StringToInt32("7ffffffe", 16), make_optional<int32_t>(0x7ffffffe));
-  EXPECT_EQ(StringToInt32(""), nullopt);
-  EXPECT_EQ(StringToInt32("!?"), nullopt);
-  EXPECT_EQ(StringToInt32("abc"), nullopt);
-  EXPECT_EQ(StringToInt32("123 abc"), nullopt);
-  EXPECT_EQ(StringToInt32("beefz", 16), nullopt);
+  EXPECT_EQ(StringToInt32("0"), std::make_optional<int32_t>(0));
+  EXPECT_EQ(StringToInt32("1"), std::make_optional<int32_t>(1));
+  EXPECT_EQ(StringToInt32("-42"), std::make_optional<int32_t>(-42));
+  EXPECT_EQ(StringToInt32("42", 16), std::make_optional<int32_t>(0x42));
+  EXPECT_EQ(StringToInt32("7ffffffe", 16),
+            std::make_optional<int32_t>(0x7ffffffe));
+  EXPECT_EQ(StringToInt32(""), std::nullopt);
+  EXPECT_EQ(StringToInt32("!?"), std::nullopt);
+  EXPECT_EQ(StringToInt32("abc"), std::nullopt);
+  EXPECT_EQ(StringToInt32("123 abc"), std::nullopt);
+  EXPECT_EQ(StringToInt32("beefz", 16), std::nullopt);
 }
 
 TEST(StringUtilsTest, StringToUInt64) {
-  EXPECT_EQ(StringToUInt64("0"), make_optional<uint64_t>(0u));
-  EXPECT_EQ(StringToUInt64("1"), make_optional<uint64_t>(1u));
+  EXPECT_EQ(StringToUInt64("0"), std::make_optional<uint64_t>(0u));
+  EXPECT_EQ(StringToUInt64("1"), std::make_optional<uint64_t>(1u));
   EXPECT_EQ(StringToUInt64("5000000000"),
-            make_optional<uint64_t>(5000000000ULL));
+            std::make_optional<uint64_t>(5000000000ULL));
   EXPECT_EQ(StringToUInt64("7ffffffffffffffe", 16),
-            make_optional<uint64_t>(0x7ffffffffffffffeULL));
+            std::make_optional<uint64_t>(0x7ffffffffffffffeULL));
   EXPECT_EQ(StringToUInt64("9ffffffffffffffe", 16),
-            make_optional<uint64_t>(0x9ffffffffffffffeULL));
-  EXPECT_EQ(StringToUInt64(""), nullopt);
-  EXPECT_EQ(StringToUInt64("abc"), nullopt);
-  EXPECT_EQ(StringToUInt64("beefz", 16), nullopt);
+            std::make_optional<uint64_t>(0x9ffffffffffffffeULL));
+  EXPECT_EQ(StringToUInt64(""), std::nullopt);
+  EXPECT_EQ(StringToUInt64("abc"), std::nullopt);
+  EXPECT_EQ(StringToUInt64("beefz", 16), std::nullopt);
 }
 
 TEST(StringUtilsTest, StringToInt64) {
-  EXPECT_EQ(StringToInt64("0"), make_optional<int64_t>(0));
-  EXPECT_EQ(StringToInt64("1"), make_optional<int64_t>(1));
+  EXPECT_EQ(StringToInt64("0"), std::make_optional<int64_t>(0));
+  EXPECT_EQ(StringToInt64("1"), std::make_optional<int64_t>(1));
   EXPECT_EQ(StringToInt64("-5000000000"),
-            make_optional<int64_t>(-5000000000LL));
-  EXPECT_EQ(StringToInt64("5000000000"), make_optional<int64_t>(5000000000LL));
+            std::make_optional<int64_t>(-5000000000LL));
+  EXPECT_EQ(StringToInt64("5000000000"),
+            std::make_optional<int64_t>(5000000000LL));
   EXPECT_EQ(StringToInt64("7ffffffffffffffe", 16),
-            make_optional<int64_t>(0x7ffffffffffffffeLL));
+            std::make_optional<int64_t>(0x7ffffffffffffffeLL));
   EXPECT_EQ(StringToInt64("9ffffffe", 16),
-            make_optional<int64_t>(0x9ffffffeLL));
-  EXPECT_EQ(StringToInt64(""), nullopt);
-  EXPECT_EQ(StringToInt64("abc"), nullopt);
-  EXPECT_EQ(StringToInt64("beefz", 16), nullopt);
+            std::make_optional<int64_t>(0x9ffffffeLL));
+  EXPECT_EQ(StringToInt64(""), std::nullopt);
+  EXPECT_EQ(StringToInt64("abc"), std::nullopt);
+  EXPECT_EQ(StringToInt64("beefz", 16), std::nullopt);
 }
 
 TEST(StringUtilsTest, StringToDouble) {
@@ -143,13 +144,13 @@
   EXPECT_DOUBLE_EQ(StringToDouble("-42.5").value(), -42.5l);
   EXPECT_DOUBLE_EQ(StringToDouble("0.5").value(), .5l);
   EXPECT_DOUBLE_EQ(StringToDouble(".5").value(), .5l);
-  EXPECT_EQ(StringToDouble(""), nullopt);
-  EXPECT_EQ(StringToDouble("!?"), nullopt);
-  EXPECT_EQ(StringToDouble("abc"), nullopt);
-  EXPECT_EQ(StringToDouble("123 abc"), nullopt);
-  EXPECT_EQ(StringToDouble("124,456"), nullopt);
-  EXPECT_EQ(StringToDouble("4 2"), nullopt);
-  EXPECT_EQ(StringToDouble(" - 42"), nullopt);
+  EXPECT_EQ(StringToDouble(""), std::nullopt);
+  EXPECT_EQ(StringToDouble("!?"), std::nullopt);
+  EXPECT_EQ(StringToDouble("abc"), std::nullopt);
+  EXPECT_EQ(StringToDouble("123 abc"), std::nullopt);
+  EXPECT_EQ(StringToDouble("124,456"), std::nullopt);
+  EXPECT_EQ(StringToDouble("4 2"), std::nullopt);
+  EXPECT_EQ(StringToDouble(" - 42"), std::nullopt);
 }
 
 TEST(StringUtilsTest, StartsWith) {
diff --git a/src/base/threading/BUILD.gn b/src/base/threading/BUILD.gn
index 3a31723..23343bc 100644
--- a/src/base/threading/BUILD.gn
+++ b/src/base/threading/BUILD.gn
@@ -15,9 +15,13 @@
 import("../../../gn/test.gni")
 
 source_set("threading") {
-  deps = [ "../../../gn:default_deps" ]
+  deps = [
+    "..:base",
+    "../../../gn:default_deps",
+  ]
   public_deps = [ "../../../include/perfetto/ext/base/threading" ]
   sources = [
+    "spawn.cc",
     "stream_combinators.cc",
     "thread_pool.cc",
   ]
@@ -28,12 +32,14 @@
   deps = [
     ":threading",
     "..:base",
+    "..:test_support",
     "../../../gn:default_deps",
     "../../../gn:gtest_and_gmock",
   ]
   sources = [
     "channel_unittest.cc",
     "future_unittest.cc",
+    "spawn_unittest.cc",
     "stream_unittest.cc",
     "thread_pool_unittest.cc",
     "util_unittest.cc",
diff --git a/src/base/threading/channel_unittest.cc b/src/base/threading/channel_unittest.cc
index 7acb355..2c5e45e 100644
--- a/src/base/threading/channel_unittest.cc
+++ b/src/base/threading/channel_unittest.cc
@@ -15,12 +15,13 @@
  */
 
 #include "perfetto/ext/base/threading/channel.h"
+
 #include <array>
 #include <memory>
+#include <optional>
 
 #include "perfetto/base/platform_handle.h"
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/utils.h"
 #include "test/gtest_and_gmock.h"
 
@@ -71,7 +72,7 @@
   ASSERT_TRUE(IsReady(channel.read_fd()));
 
   ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(100, false));
-  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(base::nullopt, false));
+  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(std::nullopt, false));
 
   ASSERT_TRUE(IsReady(channel.write_fd()));
   ASSERT_FALSE(IsReady(channel.read_fd()));
@@ -98,7 +99,7 @@
   ASSERT_TRUE(IsReady(channel.write_fd()));
   ASSERT_FALSE(IsReady(channel.read_fd()));
 
-  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(base::nullopt, false));
+  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(std::nullopt, false));
   ASSERT_TRUE(IsReady(channel.write_fd()));
   ASSERT_FALSE(IsReady(channel.read_fd()));
 }
@@ -106,13 +107,13 @@
 TEST(ChannelUnittest, CloseEmptyChannel) {
   Channel<int> channel(1);
 
-  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(base::nullopt, false));
+  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(std::nullopt, false));
   ASSERT_FALSE(IsReady(channel.read_fd()));
 
   channel.Close();
 
-  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(base::nullopt, true));
-  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(base::nullopt, true));
+  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(std::nullopt, true));
+  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(std::nullopt, true));
 
   ASSERT_TRUE(IsReady(channel.read_fd()));
   ASSERT_TRUE(IsReady(channel.read_fd()));
@@ -139,12 +140,12 @@
 
 TEST(ChannelUnittest, ReadAfterClose) {
   Channel<int> channel(1);
-  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(base::nullopt, false));
+  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(std::nullopt, false));
   ASSERT_EQ(channel.WriteNonBlocking(100), WriteResult(true, false));
   channel.Close();
 
   ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(100, true));
-  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(base::nullopt, true));
+  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(std::nullopt, true));
 }
 
 TEST(ChannelUnittest, WriteAfterClose) {
@@ -164,7 +165,7 @@
   channel.Close();
   ASSERT_TRUE(IsReady(channel.write_fd()));
   ASSERT_TRUE(IsReady(channel.write_fd()));
-  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(base::nullopt, true));
+  ASSERT_EQ(channel.ReadNonBlocking(), ReadResult(std::nullopt, true));
   ASSERT_TRUE(IsReady(channel.write_fd()));
   ASSERT_TRUE(IsReady(channel.read_fd()));
 }
diff --git a/src/base/threading/spawn.cc b/src/base/threading/spawn.cc
new file mode 100644
index 0000000..e727f84
--- /dev/null
+++ b/src/base/threading/spawn.cc
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/ext/base/threading/spawn.h"
+
+#include <optional>
+
+#include "perfetto/base/task_runner.h"
+#include "perfetto/ext/base/thread_checker.h"
+#include "perfetto/ext/base/threading/future.h"
+#include "perfetto/ext/base/threading/poll.h"
+#include "perfetto/ext/base/threading/stream.h"
+
+namespace perfetto {
+namespace base {
+
+// Represents a future which is being polled to completion. Owned by
+// SpawnHandle.
+class PolledFuture {
+ public:
+  explicit PolledFuture(TaskRunner* task_runner, Future<FVoid> future)
+      : task_runner_(task_runner), future_(std::move(future)) {
+    PERFETTO_DCHECK(task_runner_->RunsTasksOnCurrentThread());
+    PollUntilFinish();
+  }
+
+  ~PolledFuture() {
+    PERFETTO_DCHECK_THREAD(thread_checker);
+    ClearFutureAndWatches(interested_);
+  }
+
+ private:
+  PolledFuture(PolledFuture&&) = delete;
+  PolledFuture& operator=(PolledFuture&&) = delete;
+
+  void PollUntilFinish() {
+    PERFETTO_DCHECK(task_runner_->RunsTasksOnCurrentThread());
+
+    auto pre_poll_interested = std::move(interested_);
+    interested_.clear();
+
+    FuturePollResult<FVoid> res = future_->Poll(&context_);
+    if (!res.IsPending()) {
+      ClearFutureAndWatches(pre_poll_interested);
+      return;
+    }
+
+    for (PlatformHandle fd : SetDifference(pre_poll_interested, interested_)) {
+      task_runner_->RemoveFileDescriptorWatch(fd);
+    }
+
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    for (PlatformHandle fd : SetDifference(interested_, pre_poll_interested)) {
+      task_runner_->AddFileDescriptorWatch(fd, [weak_this, fd]() {
+        if (!weak_this) {
+          return;
+        }
+        weak_this->ready_ = {fd};
+        weak_this->PollUntilFinish();
+      });
+    }
+  }
+
+  void ClearFutureAndWatches(FlatSet<PlatformHandle> interested) {
+    future_ = std::nullopt;
+    for (PlatformHandle fd : interested) {
+      task_runner_->RemoveFileDescriptorWatch(fd);
+    }
+    interested_.clear();
+    ready_.clear();
+  }
+
+  static std::vector<PlatformHandle> SetDifference(
+      const FlatSet<PlatformHandle>& f,
+      const FlatSet<PlatformHandle>& s) {
+    std::vector<PlatformHandle> out(f.size());
+    auto it = std::set_difference(f.begin(), f.end(), s.begin(), s.end(),
+                                  out.begin());
+    out.resize(static_cast<size_t>(std::distance(out.begin(), it)));
+    return out;
+  }
+
+  TaskRunner* const task_runner_ = nullptr;
+
+  std::optional<Future<FVoid>> future_;
+  FlatSet<PlatformHandle> interested_;
+  FlatSet<PlatformHandle> ready_;
+  PollContext context_{&interested_, &ready_};
+
+  PERFETTO_THREAD_CHECKER(thread_checker)
+
+  // Keep this last.
+  WeakPtrFactory<PolledFuture> weak_ptr_factory_{this};
+};
+
+SpawnHandle::SpawnHandle(TaskRunner* task_runner,
+                         std::function<Future<FVoid>()> fn)
+    : task_runner_(task_runner),
+      polled_future_(std::make_shared<std::unique_ptr<PolledFuture>>()) {
+  task_runner->PostTask(
+      [t = task_runner, fn = std::move(fn), p = polled_future_]() mutable {
+        p->reset(new PolledFuture(t, fn()));
+      });
+}
+
+SpawnHandle::~SpawnHandle() {
+  task_runner_->PostTask(
+      [f = std::move(polled_future_)]() mutable { f.reset(); });
+}
+
+}  // namespace base
+}  // namespace perfetto
diff --git a/src/base/threading/spawn_unittest.cc b/src/base/threading/spawn_unittest.cc
new file mode 100644
index 0000000..a62ae83
--- /dev/null
+++ b/src/base/threading/spawn_unittest.cc
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/ext/base/threading/spawn.h"
+
+#include <optional>
+
+#include "perfetto/ext/base/event_fd.h"
+#include "perfetto/ext/base/thread_task_runner.h"
+#include "perfetto/ext/base/threading/future.h"
+#include "perfetto/ext/base/threading/poll.h"
+#include "perfetto/ext/base/threading/util.h"
+#include "perfetto/ext/base/unix_task_runner.h"
+#include "src/base/test/test_task_runner.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace base {
+namespace {
+
+using ::testing::_;
+using ::testing::Return;
+
+template <typename T>
+class MockFuturePollable : public FuturePollable<T> {
+ public:
+  MOCK_METHOD1(Poll, FuturePollResult<T>(PollContext*));
+};
+
+template <typename T>
+class MockStreamPollable : public StreamPollable<T> {
+ public:
+  MOCK_METHOD1(PollNext, StreamPollResult<T>(PollContext*));
+};
+
+TEST(SpawnUnittest, SpawnFuture) {
+  base::TestTaskRunner task_runner;
+
+  base::EventFd fd;
+  auto pollable = std::make_unique<MockFuturePollable<int>>();
+  EXPECT_CALL(*pollable, Poll(_))
+      .WillOnce([&fd](PollContext* ctx) {
+        fd.Clear();
+        ctx->RegisterInterested(fd.fd());
+        return PendingPollResult();
+      })
+      .WillOnce(Return(FuturePollResult<int>(1024)));
+  auto res = SpawnResultFuture<int>(
+      &task_runner,
+      [pollable = std::make_shared<std::unique_ptr<MockFuturePollable<int>>>(
+           std::move(pollable))]() mutable {
+        return base::Future<int>(std::move(*pollable));
+      });
+
+  task_runner.RunUntilIdle();
+  ASSERT_EQ(res.channel()->ReadNonBlocking().item, std::nullopt);
+
+  task_runner.RunUntilIdle();
+  ASSERT_EQ(res.channel()->ReadNonBlocking().item, std::nullopt);
+
+  fd.Notify();
+  task_runner.RunUntilIdle();
+
+  auto read = res.channel()->ReadNonBlocking();
+  ASSERT_EQ(read.item, 1024);
+  ASSERT_TRUE(read.is_closed);
+
+  read = res.channel()->ReadNonBlocking();
+  ASSERT_TRUE(read.is_closed);
+}
+
+TEST(SpawnUnittest, SpawnStream) {
+  base::TestTaskRunner task_runner;
+
+  base::EventFd fd;
+  auto pollable = std::make_unique<MockStreamPollable<int>>();
+  EXPECT_CALL(*pollable, PollNext(_))
+      .WillOnce([&fd](PollContext* ctx) {
+        fd.Clear();
+        ctx->RegisterInterested(fd.fd());
+        return PendingPollResult();
+      })
+      .WillOnce(Return(StreamPollResult<int>(1024)))
+      .WillOnce([&fd](PollContext* ctx) {
+        fd.Clear();
+        ctx->RegisterInterested(fd.fd());
+        return PendingPollResult();
+      })
+      .WillOnce(Return(StreamPollResult<int>(2048)))
+      .WillOnce(Return(DonePollResult()));
+  auto res = SpawnResultStream<int>(
+      &task_runner,
+      [pollable = std::make_shared<std::unique_ptr<MockStreamPollable<int>>>(
+           std::move(pollable))]() mutable {
+        return base::Stream<int>(std::move(*pollable));
+      });
+
+  task_runner.RunUntilIdle();
+  ASSERT_EQ(res.channel()->ReadNonBlocking().item, std::nullopt);
+
+  fd.Notify();
+  task_runner.RunUntilIdle();
+
+  auto read = res.channel()->ReadNonBlocking();
+  ASSERT_EQ(read.item, 1024);
+  ASSERT_FALSE(read.is_closed);
+
+  task_runner.RunUntilIdle();
+  ASSERT_EQ(res.channel()->ReadNonBlocking().item, std::nullopt);
+
+  fd.Notify();
+  task_runner.RunUntilIdle();
+
+  read = res.channel()->ReadNonBlocking();
+  ASSERT_EQ(read.item, 2048);
+  ASSERT_TRUE(read.is_closed);
+}
+
+}  // namespace
+}  // namespace base
+}  // namespace perfetto
diff --git a/src/base/threading/util_unittest.cc b/src/base/threading/util_unittest.cc
index 887802c..504435b 100644
--- a/src/base/threading/util_unittest.cc
+++ b/src/base/threading/util_unittest.cc
@@ -16,11 +16,12 @@
 
 #include "perfetto/ext/base/threading/util.h"
 
+#include <optional>
+
 #include "perfetto/base/flat_set.h"
 #include "perfetto/base/platform_handle.h"
 #include "perfetto/base/time.h"
 #include "perfetto/ext/base/event_fd.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/threading/channel.h"
 #include "perfetto/ext/base/threading/poll.h"
 #include "perfetto/ext/base/threading/stream.h"
@@ -45,7 +46,7 @@
   return res.item();
 }
 
-base::Optional<int> WaitForStreamReady(
+std::optional<int> WaitForStreamReady(
     base::Stream<int>& stream,
     base::FlatSet<base::PlatformHandle>& interested,
     PollContext& ctx) {
@@ -55,7 +56,7 @@
     base::BlockUntilReadableFd(*interested.begin());
     interested = {};
   }
-  return res.IsDone() ? base::nullopt : base::make_optional(res.item());
+  return res.IsDone() ? std::nullopt : std::make_optional(res.item());
 }
 
 TEST(UtilUnittest, BlockUntilReadableFd) {
@@ -113,7 +114,7 @@
   interested = {};
 
   ASSERT_EQ(channel.ReadNonBlocking().item, 1);
-  ASSERT_EQ(channel.ReadNonBlocking().item, base::nullopt);
+  ASSERT_EQ(channel.ReadNonBlocking().item, std::nullopt);
 
   ASSERT_FALSE(future.Poll(&ctx).IsPending());
   ASSERT_EQ(channel.ReadNonBlocking().item, 3);
@@ -127,11 +128,11 @@
   base::ThreadPool pool(1);
   base::Stream<int> stream =
       base::RunOnThreadPool<int>(&pool, [counter = 0]() mutable {
-        return counter == 2 ? base::nullopt : base::make_optional(counter++);
+        return counter == 2 ? std::nullopt : std::make_optional(counter++);
       });
   ASSERT_EQ(WaitForStreamReady(stream, interested, ctx), 0);
   ASSERT_EQ(WaitForStreamReady(stream, interested, ctx), 1);
-  ASSERT_EQ(WaitForStreamReady(stream, interested, ctx), base::nullopt);
+  ASSERT_EQ(WaitForStreamReady(stream, interested, ctx), std::nullopt);
 }
 
 TEST(UtilUnittest, RunOnceOnThreadPool) {
diff --git a/src/base/uuid_unittest.cc b/src/base/uuid_unittest.cc
index 9f5e52f..6cd22c9 100644
--- a/src/base/uuid_unittest.cc
+++ b/src/base/uuid_unittest.cc
@@ -16,9 +16,9 @@
 
 #include "perfetto/ext/base/uuid.h"
 
-#include "test/gtest_and_gmock.h"
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
+#include "test/gtest_and_gmock.h"
 
 namespace perfetto {
 namespace base {
diff --git a/src/kernel_utils/syscall_table.cc b/src/kernel_utils/syscall_table.cc
index ee7cccd..d5a6e23 100644
--- a/src/kernel_utils/syscall_table.cc
+++ b/src/kernel_utils/syscall_table.cc
@@ -98,13 +98,13 @@
   return SyscallTable(arch);
 }
 
-base::Optional<size_t> SyscallTable::GetByName(const std::string& name) const {
+std::optional<size_t> SyscallTable::GetByName(const std::string& name) const {
   for (size_t i = 0; i < syscall_count_; i++) {
     if (name == syscall_table_[i]) {
       return i;
     }
   }
-  return base::nullopt;
+  return std::nullopt;
 }
 
 const char* SyscallTable::GetById(size_t id) const {
diff --git a/src/kernel_utils/syscall_table.h b/src/kernel_utils/syscall_table.h
index 3e88e0a..c2ec4a5 100644
--- a/src/kernel_utils/syscall_table.h
+++ b/src/kernel_utils/syscall_table.h
@@ -18,9 +18,9 @@
 #define SRC_KERNEL_UTILS_SYSCALL_TABLE_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 
 namespace perfetto {
@@ -52,8 +52,8 @@
   static SyscallTable FromCurrentArch();
 
   // Returns the syscall id for the syscall with the given name. If the syscall
-  // is not found, returns nullopt.
-  base::Optional<size_t> GetByName(const std::string& name) const;
+  // is not found, returns std::nullopt.
+  std::optional<size_t> GetByName(const std::string& name) const;
 
   // Returns the syscall name for the syscall with the given id. If the syscall
   // is not found, returns nullptr.
diff --git a/src/perfetto_cmd/BUILD.gn b/src/perfetto_cmd/BUILD.gn
index 70c47fc..51486c0 100644
--- a/src/perfetto_cmd/BUILD.gn
+++ b/src/perfetto_cmd/BUILD.gn
@@ -49,6 +49,7 @@
     "../../include/perfetto/ext/traced",
   ]
   deps = [
+    ":bugreport_path",
     ":gen_cc_config_descriptor",
     ":trigger_producer",
     "../../gn:default_deps",
@@ -83,6 +84,15 @@
   }
 }
 
+source_set("bugreport_path") {
+  sources = [ "bugreport_path.h" ]
+  deps = [ "../../gn:default_deps" ]
+  public_deps = [
+    "../../include/perfetto/base",
+    "../../include/perfetto/ext/base",
+  ]
+}
+
 perfetto_cc_proto_descriptor("gen_cc_config_descriptor") {
   descriptor_name = "config.descriptor"
   descriptor_target = "../../protos/perfetto/config:descriptor"
diff --git a/src/perfetto_cmd/bugreport_path.h b/src/perfetto_cmd/bugreport_path.h
new file mode 100644
index 0000000..5bc7602
--- /dev/null
+++ b/src/perfetto_cmd/bugreport_path.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PERFETTO_CMD_BUGREPORT_PATH_H_
+#define SRC_PERFETTO_CMD_BUGREPORT_PATH_H_
+
+#include <string>
+
+#include "perfetto/base/build_config.h"
+#include "perfetto/ext/base/temp_file.h"
+
+namespace perfetto {
+
+// Expose for testing
+inline std::string GetBugreportTracePath() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+  return "/data/misc/perfetto-traces/bugreport/systrace.pftrace";
+#else
+  // Only for tests, SaveTraceForBugreport is not used on other OSes.
+  return base::GetSysTempDir() + "/bugreport.pftrace";
+#endif
+}
+
+}  // namespace perfetto
+
+#endif  // SRC_PERFETTO_CMD_BUGREPORT_PATH_H_
diff --git a/src/perfetto_cmd/pbtxt_to_pb.cc b/src/perfetto_cmd/pbtxt_to_pb.cc
index 1904725..1f11a21 100644
--- a/src/perfetto_cmd/pbtxt_to_pb.cc
+++ b/src/perfetto_cmd/pbtxt_to_pb.cc
@@ -14,19 +14,18 @@
  * limitations under the License.
  */
 
-#include <ctype.h>
+#include "src/perfetto_cmd/pbtxt_to_pb.h"
 
+#include <ctype.h>
 #include <limits>
 #include <map>
+#include <optional>
 #include <set>
 #include <stack>
 #include <string>
 
-#include "src/perfetto_cmd/pbtxt_to_pb.h"
-
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/ext/base/utils.h"
@@ -442,7 +441,7 @@
   template <typename T>
   void FixedFloatField(const FieldDescriptorProto* field, Token t) {
     uint32_t field_id = static_cast<uint32_t>(field->number());
-    base::Optional<double> opt_n = base::StringToDouble(t.ToStdString());
+    std::optional<double> opt_n = base::StringToDouble(t.ToStdString());
     msg()->AppendFixed<T>(field_id, static_cast<T>(opt_n.value_or(0l)));
   }
 
diff --git a/src/perfetto_cmd/perfetto_cmd.cc b/src/perfetto_cmd/perfetto_cmd.cc
index 5818c59..4a2b081 100644
--- a/src/perfetto_cmd/perfetto_cmd.cc
+++ b/src/perfetto_cmd/perfetto_cmd.cc
@@ -51,6 +51,7 @@
 #include "perfetto/ext/base/getopt.h"
 #include "perfetto/ext/base/pipe.h"
 #include "perfetto/ext/base/string_view.h"
+#include "perfetto/ext/base/temp_file.h"
 #include "perfetto/ext/base/thread_utils.h"
 #include "perfetto/ext/base/utils.h"
 #include "perfetto/ext/base/uuid.h"
@@ -64,9 +65,11 @@
 #include "perfetto/tracing/core/trace_config.h"
 #include "perfetto/tracing/core/tracing_service_state.h"
 #include "src/android_stats/statsd_logging_helper.h"
+#include "src/perfetto_cmd/bugreport_path.h"
 #include "src/perfetto_cmd/config.h"
 #include "src/perfetto_cmd/packet_writer.h"
 #include "src/perfetto_cmd/pbtxt_to_pb.h"
+#include "src/perfetto_cmd/rate_limiter.h"
 #include "src/perfetto_cmd/trigger_producer.h"
 
 #include "protos/perfetto/common/ftrace_descriptor.gen.h"
@@ -78,7 +81,8 @@
 
 perfetto::PerfettoCmd* g_perfetto_cmd;
 
-uint32_t kOnTraceDataTimeoutMs = 3000;
+const uint32_t kOnTraceDataTimeoutMs = 3000;
+const uint32_t kCloneTimeoutMs = 10000;
 
 class LoggingErrorReporter : public ErrorReporter {
  public:
@@ -151,7 +155,7 @@
 #endif  // PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
 }
 
-base::Optional<PerfettoStatsdAtom> ConvertRateLimiterResponseToAtom(
+std::optional<PerfettoStatsdAtom> ConvertRateLimiterResponseToAtom(
     RateLimiter::ShouldTraceResponse resp) {
   switch (resp) {
     case RateLimiter::kNotAllowedOnUserBuild:
@@ -163,7 +167,7 @@
     case RateLimiter::kHitUploadLimit:
       return PerfettoStatsdAtom::kCmdHitUploadLimit;
     case RateLimiter::kOkToTrace:
-      return base::nullopt;
+      return std::nullopt;
   }
   PERFETTO_FATAL("For GCC");
 }
@@ -266,8 +270,8 @@
           argv0);
 }
 
-base::Optional<int> PerfettoCmd::ParseCmdlineAndMaybeDaemonize(int argc,
-                                                               char** argv) {
+std::optional<int> PerfettoCmd::ParseCmdlineAndMaybeDaemonize(int argc,
+                                                              char** argv) {
 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
   umask(0000);  // make sure that file creation is not affected by umask.
 #endif
@@ -552,6 +556,13 @@
     return 1;
   }
 
+  // --save-for-bugreport is the equivalent of:
+  // --clone kBugreportSessionId -o /data/misc/perfetto-traces/bugreport/...
+  if (bugreport_ && trace_out_path_.empty()) {
+    clone_tsid_ = kBugreportSessionId;
+    trace_out_path_ = GetBugreportTracePath();
+  }
+
   // Parse the trace config. It can be either:
   // 1) A proto-encoded file/stdin (-c ...).
   // 2) A proto-text file/stdin (-c ... --txt).
@@ -561,8 +572,7 @@
   trace_config_.reset(new TraceConfig());
 
   bool parsed = false;
-  const bool will_trace_or_trigger =
-      !is_attach() && !query_service_ && !bugreport_;
+  const bool will_trace_or_trigger = !is_attach() && !query_service_;
   if (!will_trace_or_trigger || clone_tsid_) {
     if ((!trace_config_raw.empty() || has_config_options)) {
       PERFETTO_ELOG("Cannot specify a trace config with this option");
@@ -821,8 +831,8 @@
     background_wait_pipe_.rd.reset();
   }
 
-  return base::nullopt;  // Continues in ConnectToServiceRunAndMaybeNotify()
-                         // below.
+  return std::nullopt;  // Continues in ConnectToServiceRunAndMaybeNotify()
+                        // below.
 }
 
 void PerfettoCmd::NotifyBgProcessPipe(BgProcessStatus status) {
@@ -904,12 +914,12 @@
     return finished_with_success ? 0 : 1;
   }  // if (triggers_to_activate_)
 
-  if (query_service_ || bugreport_) {
+  if (query_service_) {
     consumer_endpoint_ =
         ConsumerIPCClient::Connect(GetConsumerSocket(), this, &task_runner_);
     task_runner_.Run();
     return 1;  // We can legitimately get here if the service disconnects.
-  }            // if (query_service || bugreport_)
+  }
 
   RateLimiter::Args args{};
   args.is_user_build = IsUserBuild();
@@ -997,25 +1007,14 @@
     return;
   }
 
-  if (bugreport_) {
-    consumer_endpoint_->SaveTraceForBugreport(
-        [](bool success, const std::string& msg) {
-          if (success) {
-            PERFETTO_ILOG("Trace saved into %s", msg.c_str());
-            exit(0);
-          }
-          PERFETTO_ELOG("%s", msg.c_str());
-          exit(1);
-        });
-    return;
-  }
-
   if (is_attach()) {
     consumer_endpoint_->Attach(attach_key_);
     return;
   }
 
   if (clone_tsid_.has_value()) {
+    task_runner_.PostDelayedTask(std::bind(&PerfettoCmd::OnTimeout, this),
+                                 kCloneTimeoutMs);
     consumer_endpoint_->CloneSession(*clone_tsid_);
     return;
   }
diff --git a/src/perfetto_cmd/perfetto_cmd.h b/src/perfetto_cmd/perfetto_cmd.h
index 842ddcc..9504ca5 100644
--- a/src/perfetto_cmd/perfetto_cmd.h
+++ b/src/perfetto_cmd/perfetto_cmd.h
@@ -22,10 +22,10 @@
 #include <vector>
 
 #include <time.h>
+#include <optional>
 
 #include "perfetto/base/build_config.h"
 #include "perfetto/ext/base/event_fd.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/pipe.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/unix_task_runner.h"
@@ -33,7 +33,6 @@
 #include "perfetto/ext/tracing/core/consumer.h"
 #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
 #include "src/android_stats/perfetto_atoms.h"
-#include "src/perfetto_cmd/rate_limiter.h"
 
 namespace perfetto {
 
@@ -53,10 +52,10 @@
   // with traced. This is to allow tools like tracebox to avoid spawning the
   // service for no reason if the cmdline parsing fails.
   // Return value:
-  //   nullopt: no error, the caller should call
+  //   std::nullopt: no error, the caller should call
   //   ConnectToServiceRunAndMaybeNotify.
   //   0-N: the caller should exit() with the given exit code.
-  base::Optional<int> ParseCmdlineAndMaybeDaemonize(int argc, char** argv);
+  std::optional<int> ParseCmdlineAndMaybeDaemonize(int argc, char** argv);
   int ConnectToServiceRunAndMaybeNotify();
 
   // perfetto::Consumer implementation.
@@ -158,7 +157,7 @@
   bool upload_flag_ = false;
   bool connected_ = false;
   std::string uuid_;
-  base::Optional<TracingSessionID> clone_tsid_{};
+  std::optional<TracingSessionID> clone_tsid_{};
 
   // How long we expect to trace for or 0 if the trace is indefinite.
   uint32_t expected_duration_ms_ = 0;
diff --git a/src/profiling/common/proc_cmdline.cc b/src/profiling/common/proc_cmdline.cc
index a6f7d93..d76ebfb 100644
--- a/src/profiling/common/proc_cmdline.cc
+++ b/src/profiling/common/proc_cmdline.cc
@@ -49,7 +49,7 @@
 // Keep them as STL-free as possible to allow for both implementations to be
 // close to verbatim copies.
 
-// TODO(rsavitski): consider changing to Optional<> return type.
+// TODO(rsavitski): consider changing to std::optional<> return type.
 bool ReadProcCmdlineForPID(pid_t pid, std::string* cmdline_out) {
   std::string filename = "/proc/" + std::to_string(pid) + "/cmdline";
   base::ScopedFile fd(base::OpenFile(filename, O_RDONLY));
diff --git a/src/profiling/common/proc_utils.cc b/src/profiling/common/proc_utils.cc
index 4188b2a..83fbb4a 100644
--- a/src/profiling/common/proc_utils.cc
+++ b/src/profiling/common/proc_utils.cc
@@ -20,9 +20,9 @@
 #include <unistd.h>
 
 #include <cinttypes>
+#include <optional>
 
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "src/profiling/common/proc_cmdline.h"
 
@@ -30,8 +30,8 @@
 namespace profiling {
 namespace {
 
-base::Optional<uint32_t> ParseProcStatusSize(const std::string& status,
-                                             const std::string& key) {
+std::optional<uint32_t> ParseProcStatusSize(const std::string& status,
+                                            const std::string& key) {
   auto entry_idx = status.find(key);
   if (entry_idx == std::string::npos)
     return {};
@@ -47,32 +47,32 @@
 }
 }  // namespace
 
-base::Optional<std::string> ReadStatus(pid_t pid) {
+std::optional<std::string> ReadStatus(pid_t pid) {
   std::string path = "/proc/" + std::to_string(pid) + "/status";
   std::string status;
   bool read_proc = base::ReadFile(path, &status);
   if (!read_proc) {
     PERFETTO_ELOG("Failed to read %s", path.c_str());
-    return base::nullopt;
+    return std::nullopt;
   }
-  return base::Optional<std::string>(status);
+  return std::optional<std::string>(status);
 }
 
-base::Optional<uint32_t> GetRssAnonAndSwap(const std::string& status) {
+std::optional<uint32_t> GetRssAnonAndSwap(const std::string& status) {
   auto anon_rss = ParseProcStatusSize(status, "RssAnon:");
   auto swap = ParseProcStatusSize(status, "VmSwap:");
   if (anon_rss.has_value() && swap.has_value()) {
     return *anon_rss + *swap;
   }
-  return base::nullopt;
+  return std::nullopt;
 }
 
 void RemoveUnderAnonThreshold(uint32_t min_size_kb, std::set<pid_t>* pids) {
   for (auto it = pids->begin(); it != pids->end();) {
     const pid_t pid = *it;
 
-    base::Optional<std::string> status = ReadStatus(pid);
-    base::Optional<uint32_t> rss_and_swap;
+    std::optional<std::string> status = ReadStatus(pid);
+    std::optional<uint32_t> rss_and_swap;
     if (status)
       rss_and_swap = GetRssAnonAndSwap(*status);
 
@@ -87,10 +87,10 @@
   }
 }
 
-base::Optional<Uids> GetUids(const std::string& status) {
+std::optional<Uids> GetUids(const std::string& status) {
   auto entry_idx = status.find("Uid:");
   if (entry_idx == std::string::npos)
-    return base::nullopt;
+    return std::nullopt;
 
   Uids uids;
   const char* str = &status[entry_idx + 4];
@@ -98,22 +98,22 @@
 
   uids.real = strtoull(str, &endptr, 10);
   if (*endptr != ' ' && *endptr != '\t')
-    return base::nullopt;
+    return std::nullopt;
 
   str = endptr;
   uids.effective = strtoull(str, &endptr, 10);
   if (*endptr != ' ' && *endptr != '\t')
-    return base::nullopt;
+    return std::nullopt;
 
   str = endptr;
   uids.saved_set = strtoull(str, &endptr, 10);
   if (*endptr != ' ' && *endptr != '\t')
-    return base::nullopt;
+    return std::nullopt;
 
   str = endptr;
   uids.filesystem = strtoull(str, &endptr, 10);
   if (*endptr != '\n' && *endptr != '\0')
-    return base::nullopt;
+    return std::nullopt;
   return uids;
 }
 
@@ -146,7 +146,7 @@
   return first_arg - start;
 }
 
-base::Optional<std::vector<std::string>> NormalizeCmdlines(
+std::optional<std::vector<std::string>> NormalizeCmdlines(
     const std::vector<std::string>& cmdlines) {
   std::vector<std::string> normalized_cmdlines;
   normalized_cmdlines.reserve(cmdlines.size());
@@ -160,11 +160,11 @@
     if (size == -1) {
       PERFETTO_PLOG("Failed to normalize cmdline %s. Stopping the parse.",
                     cmdlines[i].c_str());
-      return base::nullopt;
+      return std::nullopt;
     }
     normalized_cmdlines.emplace_back(cmdline_cstr, static_cast<size_t>(size));
   }
-  return base::make_optional(normalized_cmdlines);
+  return std::make_optional(normalized_cmdlines);
 }
 
 // This is mostly the same as GetHeapprofdProgramProperty in
diff --git a/src/profiling/common/proc_utils.h b/src/profiling/common/proc_utils.h
index ccbf633..4792feb 100644
--- a/src/profiling/common/proc_utils.h
+++ b/src/profiling/common/proc_utils.h
@@ -20,10 +20,10 @@
 #include <sys/types.h>
 
 #include <cinttypes>
+#include <optional>
 #include <set>
 #include <vector>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 
 namespace perfetto {
@@ -53,13 +53,13 @@
   }
 }
 
-base::Optional<std::string> ReadStatus(pid_t pid);
-base::Optional<uint32_t> GetRssAnonAndSwap(const std::string&);
+std::optional<std::string> ReadStatus(pid_t pid);
+std::optional<uint32_t> GetRssAnonAndSwap(const std::string&);
 // Filters the list of pids (in-place), keeping only the
 // entries satisfying the minimum size criteria for anonymous memory.
 void RemoveUnderAnonThreshold(uint32_t min_size_kb, std::set<pid_t>* pids);
 
-base::Optional<Uids> GetUids(const std::string&);
+std::optional<Uids> GetUids(const std::string&);
 
 void FindAllProfilablePids(std::set<pid_t>* pids);
 
@@ -68,7 +68,7 @@
 // implementations are placed in the "glob_aware" namespace here, until we
 // migrate to one implementation for all profilers.
 ssize_t NormalizeCmdLine(char** cmdline_ptr, size_t size);
-base::Optional<std::vector<std::string>> NormalizeCmdlines(
+std::optional<std::vector<std::string>> NormalizeCmdlines(
     const std::vector<std::string>& cmdlines);
 void FindPidsForCmdlines(const std::vector<std::string>& cmdlines,
                          std::set<pid_t>* pids);
diff --git a/src/profiling/common/proc_utils_unittest.cc b/src/profiling/common/proc_utils_unittest.cc
index 36a7720..8ce34e4 100644
--- a/src/profiling/common/proc_utils_unittest.cc
+++ b/src/profiling/common/proc_utils_unittest.cc
@@ -15,7 +15,8 @@
  */
 
 #include "src/profiling/common/proc_utils.h"
-#include "perfetto/ext/base/optional.h"
+
+#include <optional>
 
 #include "perfetto/ext/base/utils.h"
 #include "test/gtest_and_gmock.h"
@@ -131,9 +132,9 @@
 }
 
 TEST(ProcUtilsTest, GetRssAnonAndSwapInvalidInput) {
-  EXPECT_EQ(GetRssAnonAndSwap(""), base::nullopt);
-  EXPECT_EQ(GetRssAnonAndSwap("RssAnon: 10000 kB"), base::nullopt);
-  EXPECT_EQ(GetRssAnonAndSwap("VmSwap: 10000"), base::nullopt);
+  EXPECT_EQ(GetRssAnonAndSwap(""), std::nullopt);
+  EXPECT_EQ(GetRssAnonAndSwap("RssAnon: 10000 kB"), std::nullopt);
+  EXPECT_EQ(GetRssAnonAndSwap("VmSwap: 10000"), std::nullopt);
 }
 
 TEST(ProcUtilsTest, GetUids) {
@@ -141,7 +142,7 @@
       "Name: foo\nRssAnon:  10000 kB\nVmSwap:\t10000 kB\n"
       "Uid: 1 2 3 4\n";
   auto uids = GetUids(status);
-  ASSERT_NE(uids, base::nullopt);
+  ASSERT_NE(uids, std::nullopt);
   EXPECT_EQ(uids->real, 1u);
   EXPECT_EQ(uids->effective, 2u);
   EXPECT_EQ(uids->saved_set, 3u);
@@ -153,7 +154,7 @@
       "Name: foo\nRssAnon:  10000 kB\nVmSwap:\t10000 kB\n"
       "Uid: 1a 2 3 4\n";
   auto uids = GetUids(status);
-  EXPECT_EQ(uids, base::nullopt);
+  EXPECT_EQ(uids, std::nullopt);
 }
 
 TEST(ProcUtilsTest, GetUidsInvalidTooFew) {
@@ -161,7 +162,7 @@
       "Name: foo\nRssAnon:  10000 kB\nVmSwap:\t10000 kB\n"
       "Uid: 1 2 3\n";
   auto uids = GetUids(status);
-  EXPECT_EQ(uids, base::nullopt);
+  EXPECT_EQ(uids, std::nullopt);
 }
 
 }  // namespace
diff --git a/src/profiling/common/producer_support.cc b/src/profiling/common/producer_support.cc
index a160149..5303658 100644
--- a/src/profiling/common/producer_support.cc
+++ b/src/profiling/common/producer_support.cc
@@ -16,9 +16,10 @@
 
 #include "src/profiling/common/producer_support.h"
 
+#include <optional>
+
 #include "perfetto/ext/base/android_utils.h"
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_splitter.h"
 #include "perfetto/tracing/core/data_source_config.h"
 #include "src/traced/probes/packages_list/packages_list_parser.h"
@@ -27,26 +28,26 @@
 namespace profiling {
 
 namespace {
-base::Optional<Package> FindInPackagesList(
+std::optional<Package> FindInPackagesList(
     uint64_t lookup_uid,
     const std::string& packages_list_path) {
   std::string content;
   if (!base::ReadFile(packages_list_path, &content)) {
     PERFETTO_ELOG("Failed to read %s", packages_list_path.c_str());
-    return base::nullopt;
+    return std::nullopt;
   }
   for (base::StringSplitter ss(std::move(content), '\n'); ss.Next();) {
     Package pkg;
     if (!ReadPackagesListLine(ss.cur_token(), &pkg)) {
       PERFETTO_ELOG("Failed to parse packages.list");
-      return base::nullopt;
+      return std::nullopt;
     }
 
     if (pkg.uid == lookup_uid) {
       return std::move(pkg);  // -Wreturn-std-move-in-c++11
     }
   }
-  return base::nullopt;
+  return std::nullopt;
 }
 
 bool AllPackagesProfileableByTrustedInitiator(
@@ -156,7 +157,7 @@
     return false;
   }
 
-  base::Optional<Package> pkg =
+  std::optional<Package> pkg =
       FindInPackagesList(uid_for_lookup, packages_list_path);
 
   if (!pkg)
diff --git a/src/profiling/common/profiler_guardrails.cc b/src/profiling/common/profiler_guardrails.cc
index a7f5dad..38ff6ed 100644
--- a/src/profiling/common/profiler_guardrails.cc
+++ b/src/profiling/common/profiler_guardrails.cc
@@ -17,29 +17,29 @@
 #include "src/profiling/common/profiler_guardrails.h"
 
 #include <unistd.h>
-
 #include <algorithm>
+#include <optional>
+
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/watchdog_posix.h"
 
 namespace perfetto {
 namespace profiling {
 
-base::Optional<uint64_t> GetCputimeSecForCurrentProcess() {
+std::optional<uint64_t> GetCputimeSecForCurrentProcess() {
   return GetCputimeSecForCurrentProcess(
       base::OpenFile("/proc/self/stat", O_RDONLY));
 }
 
-base::Optional<uint64_t> GetCputimeSecForCurrentProcess(
+std::optional<uint64_t> GetCputimeSecForCurrentProcess(
     base::ScopedFile stat_fd) {
   if (!stat_fd)
-    return base::nullopt;
+    return std::nullopt;
   base::ProcStat stat;
   if (!ReadProcStat(stat_fd.get(), &stat)) {
     PERFETTO_ELOG("Failed to read stat file to enforce guardrails.");
-    return base::nullopt;
+    return std::nullopt;
   }
   return (stat.utime + stat.stime) /
          static_cast<unsigned long>(sysconf(_SC_CLK_TCK));
diff --git a/src/profiling/common/profiler_guardrails.h b/src/profiling/common/profiler_guardrails.h
index e9e9d47..4fc723f 100644
--- a/src/profiling/common/profiler_guardrails.h
+++ b/src/profiling/common/profiler_guardrails.h
@@ -21,9 +21,9 @@
 #include <unistd.h>
 
 #include <cinttypes>
+#include <optional>
 
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/tracing/core/basic_types.h"
 #include "src/profiling/common/proc_utils.h"
@@ -31,14 +31,14 @@
 namespace perfetto {
 namespace profiling {
 
-base::Optional<uint64_t> GetCputimeSecForCurrentProcess();
+std::optional<uint64_t> GetCputimeSecForCurrentProcess();
 // For testing.
-base::Optional<uint64_t> GetCputimeSecForCurrentProcess(
+std::optional<uint64_t> GetCputimeSecForCurrentProcess(
     base::ScopedFile stat_fd);
 
 struct GuardrailConfig {
   uint64_t cpu_guardrail_sec = 0;
-  base::Optional<uint64_t> cpu_start_secs;
+  std::optional<uint64_t> cpu_start_secs;
   uint32_t memory_guardrail_kb = 0;
 };
 
@@ -51,7 +51,7 @@
   bool IsOverCpuThreshold(const GuardrailConfig& ds);
 
  private:
-  base::Optional<uint64_t> opt_cputime_sec_;
+  std::optional<uint64_t> opt_cputime_sec_;
 };
 
 class ProfilerMemoryGuardrails {
@@ -63,7 +63,7 @@
   bool IsOverMemoryThreshold(const GuardrailConfig& ds);
 
  private:
-  base::Optional<uint32_t> anon_and_swap_;
+  std::optional<uint32_t> anon_and_swap_;
 };
 
 }  // namespace profiling
diff --git a/src/profiling/common/profiler_guardrails_unittest.cc b/src/profiling/common/profiler_guardrails_unittest.cc
index ca9d1b2..1368cbe 100644
--- a/src/profiling/common/profiler_guardrails_unittest.cc
+++ b/src/profiling/common/profiler_guardrails_unittest.cc
@@ -20,9 +20,9 @@
 
 #include <cinttypes>
 #include <map>
+#include <optional>
 
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/temp_file.h"
 #include "test/gtest_and_gmock.h"
 
diff --git a/src/profiling/deobfuscator.cc b/src/profiling/deobfuscator.cc
index 378677e..fa32706 100644
--- a/src/profiling/deobfuscator.cc
+++ b/src/profiling/deobfuscator.cc
@@ -16,12 +16,12 @@
 
 #include "src/profiling/deobfuscator.h"
 
+#include <optional>
 #include "perfetto/base/status.h"
 #include "perfetto/ext/base/file_utils.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/string_splitter.h"
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/protozero/scattered_heap_buffer.h"
 #include "protos/perfetto/trace/profiling/deobfuscation.pbzero.h"
 #include "protos/perfetto/trace/trace.pbzero.h"
@@ -36,39 +36,39 @@
   std::string deobfuscated_name;
 };
 
-base::Optional<ProguardClass> ParseClass(std::string line) {
+std::optional<ProguardClass> ParseClass(std::string line) {
   base::StringSplitter ss(std::move(line), ' ');
 
   if (!ss.Next()) {
     PERFETTO_ELOG("Missing deobfuscated name.");
-    return base::nullopt;
+    return std::nullopt;
   }
   std::string deobfuscated_name(ss.cur_token(), ss.cur_token_size());
 
   if (!ss.Next() || ss.cur_token_size() != 2 ||
       strncmp("->", ss.cur_token(), 2) != 0) {
     PERFETTO_ELOG("Missing ->");
-    return base::nullopt;
+    return std::nullopt;
   }
 
   if (!ss.Next()) {
     PERFETTO_ELOG("Missing obfuscated name.");
-    return base::nullopt;
+    return std::nullopt;
   }
   std::string obfuscated_name(ss.cur_token(), ss.cur_token_size());
   if (obfuscated_name.empty()) {
     PERFETTO_ELOG("Empty obfuscated name.");
-    return base::nullopt;
+    return std::nullopt;
   }
   if (obfuscated_name.back() != ':') {
     PERFETTO_ELOG("Expected colon.");
-    return base::nullopt;
+    return std::nullopt;
   }
 
   obfuscated_name.resize(obfuscated_name.size() - 1);
   if (ss.Next()) {
     PERFETTO_ELOG("Unexpected data.");
-    return base::nullopt;
+    return std::nullopt;
   }
   return ProguardClass{std::move(obfuscated_name),
                        std::move(deobfuscated_name)};
@@ -85,36 +85,36 @@
   std::string deobfuscated_name;
 };
 
-base::Optional<ProguardMember> ParseMember(std::string line) {
+std::optional<ProguardMember> ParseMember(std::string line) {
   base::StringSplitter ss(std::move(line), ' ');
 
   if (!ss.Next()) {
     PERFETTO_ELOG("Missing type name.");
-    return base::nullopt;
+    return std::nullopt;
   }
   std::string type_name(ss.cur_token(), ss.cur_token_size());
 
   if (!ss.Next()) {
     PERFETTO_ELOG("Missing deobfuscated name.");
-    return base::nullopt;
+    return std::nullopt;
   }
   std::string deobfuscated_name(ss.cur_token(), ss.cur_token_size());
 
   if (!ss.Next() || ss.cur_token_size() != 2 ||
       strncmp("->", ss.cur_token(), 2) != 0) {
     PERFETTO_ELOG("Missing ->");
-    return base::nullopt;
+    return std::nullopt;
   }
 
   if (!ss.Next()) {
     PERFETTO_ELOG("Missing obfuscated name.");
-    return base::nullopt;
+    return std::nullopt;
   }
   std::string obfuscated_name(ss.cur_token(), ss.cur_token_size());
 
   if (ss.Next()) {
     PERFETTO_ELOG("Unexpected data.");
-    return base::nullopt;
+    return std::nullopt;
   }
 
   ProguardMemberType member_type;
diff --git a/src/profiling/memory/BUILD.gn b/src/profiling/memory/BUILD.gn
index 51deba3..817c5b8 100644
--- a/src/profiling/memory/BUILD.gn
+++ b/src/profiling/memory/BUILD.gn
@@ -358,8 +358,12 @@
     "../../base",
     "../../base:test_support",
     "../../trace_processor:lib",
+    "../../tracing/test:test_support",
   ]
-  sources = [ "heapprofd_end_to_end_test.cc" ]
+  sources = [
+    "heapprofd_end_to_end_test.cc",
+    "heapprofd_producer_integrationtest.cc",
+  ]
   if (perfetto_build_with_android) {
     deps += [ ":heapprofd_client_api" ]
   } else {
diff --git a/src/profiling/memory/client.cc b/src/profiling/memory/client.cc
index 79e1a77..478a900 100644
--- a/src/profiling/memory/client.cc
+++ b/src/profiling/memory/client.cc
@@ -140,21 +140,21 @@
 }
 
 // static
-base::Optional<base::UnixSocketRaw> Client::ConnectToHeapprofd(
+std::optional<base::UnixSocketRaw> Client::ConnectToHeapprofd(
     const std::string& sock_name) {
   auto sock = base::UnixSocketRaw::CreateMayFail(base::SockFamily::kUnix,
                                                  base::SockType::kStream);
   if (!sock || !sock.Connect(sock_name)) {
     PERFETTO_PLOG("Failed to connect to %s", sock_name.c_str());
-    return base::nullopt;
+    return std::nullopt;
   }
   if (!sock.SetTxTimeout(kClientSockTimeoutMs)) {
     PERFETTO_PLOG("Failed to set send timeout for %s", sock_name.c_str());
-    return base::nullopt;
+    return std::nullopt;
   }
   if (!sock.SetRxTimeout(kClientSockTimeoutMs)) {
     PERFETTO_PLOG("Failed to set receive timeout for %s", sock_name.c_str());
-    return base::nullopt;
+    return std::nullopt;
   }
   return std::move(sock);
 }
diff --git a/src/profiling/memory/client.h b/src/profiling/memory/client.h
index 8b5f341..0e209fb 100644
--- a/src/profiling/memory/client.h
+++ b/src/profiling/memory/client.h
@@ -74,7 +74,7 @@
       base::UnixSocketRaw sock,
       UnhookedAllocator<Client> unhooked_allocator);
 
-  static base::Optional<base::UnixSocketRaw> ConnectToHeapprofd(
+  static std::optional<base::UnixSocketRaw> ConnectToHeapprofd(
       const std::string& sock_name);
 
   bool RecordMalloc(uint32_t heap_id,
diff --git a/src/profiling/memory/client_api_factory_android.cc b/src/profiling/memory/client_api_factory_android.cc
index 16c3a25..9c7b63c 100644
--- a/src/profiling/memory/client_api_factory_android.cc
+++ b/src/profiling/memory/client_api_factory_android.cc
@@ -23,9 +23,9 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
+#include <optional>
 
 #include "perfetto/base/build_config.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/unix_socket.h"
 #include "src/profiling/memory/client.h"
 
@@ -43,7 +43,7 @@
   PERFETTO_LOG("Constructing client for central daemon.");
   using perfetto::profiling::Client;
 
-  perfetto::base::Optional<perfetto::base::UnixSocketRaw> sock =
+  std::optional<perfetto::base::UnixSocketRaw> sock =
       Client::ConnectToHeapprofd(perfetto::profiling::kHeapprofdSocketFile);
   if (!sock) {
     PERFETTO_ELOG("Failed to connect to %s. This is benign on user builds.",
diff --git a/src/profiling/memory/heapprofd_end_to_end_test.cc b/src/profiling/memory/heapprofd_end_to_end_test.cc
index de9f40e..66acd81 100644
--- a/src/profiling/memory/heapprofd_end_to_end_test.cc
+++ b/src/profiling/memory/heapprofd_end_to_end_test.cc
@@ -25,11 +25,11 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
+#include <optional>
 
 #include "perfetto/base/build_config.h"
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/pipe.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/subprocess.h"
@@ -97,7 +97,7 @@
   int64_t cumulative_alloc_count;
   int64_t alloc_size;
   int64_t cumulative_alloc_size;
-  base::Optional<int64_t> parent_id;
+  std::optional<int64_t> parent_id;
 };
 
 std::vector<FlamegraphNode> GetFlamegraph(trace_processor::TraceProcessor* tp) {
@@ -116,8 +116,8 @@
         it.Get(8).AsLong(),
         it.Get(9).AsLong(),
         it.Get(10).AsLong(),
-        it.Get(11).is_null() ? base::nullopt
-                             : base::Optional<int64_t>(it.Get(11).AsLong()),
+        it.Get(11).is_null() ? std::nullopt
+                             : std::optional<int64_t>(it.Get(11).AsLong()),
     });
   }
   PERFETTO_CHECK(it.Status().ok());
diff --git a/src/profiling/memory/heapprofd_producer.cc b/src/profiling/memory/heapprofd_producer.cc
index 2d35965..7d0cfe8 100644
--- a/src/profiling/memory/heapprofd_producer.cc
+++ b/src/profiling/memory/heapprofd_producer.cc
@@ -24,12 +24,12 @@
 #include <algorithm>
 #include <cinttypes>
 #include <functional>
+#include <optional>
 #include <string>
 
 #include "perfetto/base/compiler.h"
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_splitter.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/thread_task_runner.h"
@@ -390,7 +390,7 @@
     return;
   }
 
-  base::Optional<std::vector<std::string>> normalized_cmdlines =
+  std::optional<std::vector<std::string>> normalized_cmdlines =
       NormalizeCmdlines(heapprofd_config.process_cmdline());
   if (!normalized_cmdlines.has_value()) {
     PERFETTO_ELOG("Rejecting data source due to invalid cmdline in config.");
@@ -416,7 +416,7 @@
     }
   }
 
-  base::Optional<uint64_t> start_cputime_sec;
+  std::optional<uint64_t> start_cputime_sec;
   if (heapprofd_config.max_heapprofd_cpu_secs() > 0) {
     start_cputime_sec = GetCputimeSecForCurrentProcess();
 
diff --git a/src/profiling/memory/heapprofd_producer.h b/src/profiling/memory/heapprofd_producer.h
index 92f830a..ac18b54 100644
--- a/src/profiling/memory/heapprofd_producer.h
+++ b/src/profiling/memory/heapprofd_producer.h
@@ -21,10 +21,10 @@
 #include <cinttypes>
 #include <functional>
 #include <map>
+#include <optional>
 #include <vector>
 
 #include "perfetto/base/task_runner.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/unix_socket.h"
 #include "perfetto/ext/base/unix_task_runner.h"
 #include "perfetto/ext/tracing/core/basic_types.h"
@@ -317,7 +317,7 @@
 
   // Specific to mode_ == kChild
   Process target_process_{base::kInvalidPid, ""};
-  base::Optional<std::function<void()>> data_source_callback_;
+  std::optional<std::function<void()>> data_source_callback_;
 
   SocketDelegate socket_delegate_;
 
diff --git a/src/profiling/memory/heapprofd_producer_integrationtest.cc b/src/profiling/memory/heapprofd_producer_integrationtest.cc
new file mode 100644
index 0000000..d0ea2c4
--- /dev/null
+++ b/src/profiling/memory/heapprofd_producer_integrationtest.cc
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/profiling/memory/heapprofd_producer.h"
+
+#include "perfetto/base/proc_utils.h"
+#include "perfetto/ext/base/thread_task_runner.h"
+#include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
+#include "perfetto/ext/tracing/ipc/service_ipc_host.h"
+#include "protos/perfetto/common/data_source_descriptor.gen.h"
+#include "protos/perfetto/config/trace_config.gen.h"
+#include "src/base/test/test_task_runner.h"
+#include "src/base/test/tmp_dir_tree.h"
+#include "src/profiling/memory/client.h"
+#include "src/profiling/memory/unhooked_allocator.h"
+#include "src/tracing/test/mock_consumer.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace profiling {
+namespace {
+
+using ::testing::NiceMock;
+using ::testing::NotNull;
+
+class TracingServiceThread {
+ public:
+  TracingServiceThread(const std::string& producer_socket,
+                       const std::string& consumer_socket)
+      : runner_(base::ThreadTaskRunner::CreateAndStart("perfetto.svc")),
+        producer_socket_(producer_socket),
+        consumer_socket_(consumer_socket) {
+    runner_.PostTaskAndWaitForTesting([this]() {
+      svc_ = ServiceIPCHost::CreateInstance(&runner_);
+      bool res =
+          svc_->Start(producer_socket_.c_str(), consumer_socket_.c_str());
+      if (!res) {
+        PERFETTO_FATAL("Failed to start service listening on %s and %s",
+                       producer_socket_.c_str(), consumer_socket_.c_str());
+      }
+    });
+  }
+
+  ~TracingServiceThread() {
+    runner_.PostTaskAndWaitForTesting([this]() { svc_.reset(); });
+  }
+
+  const std::string& producer_socket() const { return producer_socket_; }
+  const std::string& consumer_socket() const { return consumer_socket_; }
+
+ private:
+  base::ThreadTaskRunner runner_;
+
+  std::string producer_socket_;
+  std::string consumer_socket_;
+  std::unique_ptr<ServiceIPCHost> svc_;
+};
+
+class HeapprofdThread {
+ public:
+  HeapprofdThread(const std::string& producer_socket,
+                  const std::string& heapprofd_socket)
+      : runner_(base::ThreadTaskRunner::CreateAndStart("heapprofd.svc")),
+        producer_socket_(producer_socket),
+        heapprofd_socket_(heapprofd_socket) {
+    runner_.PostTaskAndWaitForTesting([this]() {
+      heapprofd_.reset(new HeapprofdProducer(HeapprofdMode::kCentral, &runner_,
+                                             /* exit_when_done= */ false));
+
+      heapprofd_->ConnectWithRetries(producer_socket_.c_str());
+      listen_sock_ = base::UnixSocket::Listen(
+          heapprofd_socket_.c_str(), &heapprofd_->socket_delegate(), &runner_,
+          base::SockFamily::kUnix, base::SockType::kStream);
+      EXPECT_THAT(listen_sock_, NotNull());
+    });
+  }
+
+  void Sync() {
+    runner_.PostTaskAndWaitForTesting([]() {});
+  }
+
+  ~HeapprofdThread() {
+    runner_.PostTaskAndWaitForTesting([this]() {
+      listen_sock_.reset();
+      heapprofd_.reset();
+    });
+  }
+
+  const std::string& producer_socket() const { return producer_socket_; }
+  const std::string& heapprofd_socket() const { return heapprofd_socket_; }
+
+ private:
+  base::ThreadTaskRunner runner_;
+
+  std::string producer_socket_;
+  std::string heapprofd_socket_;
+  std::unique_ptr<HeapprofdProducer> heapprofd_;
+  std::unique_ptr<base::UnixSocket> listen_sock_;
+};
+
+TraceConfig MakeTraceConfig() {
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(10 * 1024);
+  trace_config.set_data_source_stop_timeout_ms(10000);
+
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.heapprofd");
+  ds_config->set_target_buffer(0);
+
+  protos::gen::HeapprofdConfig heapprofd_config;
+  heapprofd_config.set_sampling_interval_bytes(1);
+  heapprofd_config.add_pid(static_cast<uint64_t>(base::GetProcessId()));
+  heapprofd_config.set_all_heaps(true);
+  heapprofd_config.set_no_startup(true);
+  heapprofd_config.set_no_running(true);
+  ds_config->set_heapprofd_config_raw(heapprofd_config.SerializeAsString());
+  return trace_config;
+}
+
+bool WaitFor(std::function<bool()> predicate, long long timeout_ms = 40000) {
+  long long deadline_ms = base::GetWallTimeMs().count() + timeout_ms;
+  while (base::GetWallTimeMs().count() < deadline_ms) {
+    if (predicate())
+      return true;
+    base::SleepMicroseconds(100 * 1000);  // 0.1 s.
+  }
+  return false;
+}
+
+bool WaitForDsRegistered(MockConsumer* mock_consumer,
+                         const std::string& ds_name) {
+  return WaitFor([mock_consumer, &ds_name]() {
+    auto dss = mock_consumer->QueryServiceState().data_sources();
+    return std::any_of(dss.begin(), dss.end(),
+                       [&](const TracingServiceState::DataSource& ds) {
+                         return ds.ds_descriptor().name() == ds_name;
+                       });
+  });
+}
+
+// Waits for the heapprofd data source to be registered and starts a trace with
+// it.
+std::unique_ptr<NiceMock<MockConsumer>> StartHeapprofdTrace(
+    const std::string& consumer_socket,
+    base::TestTaskRunner* task_runner) {
+  std::unique_ptr<NiceMock<MockConsumer>> mock_consumer;
+  mock_consumer.reset(new NiceMock<MockConsumer>(task_runner));
+  mock_consumer->Connect(ConsumerIPCClient::Connect(
+      consumer_socket.c_str(), mock_consumer.get(), task_runner));
+
+  if (WaitForDsRegistered(mock_consumer.get(), "android.heapprofd") == false) {
+    ADD_FAILURE();
+    return nullptr;
+  }
+
+  mock_consumer->ObserveEvents(ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
+  mock_consumer->EnableTracing(MakeTraceConfig());
+  mock_consumer->WaitForObservableEvents();
+
+  return mock_consumer;
+}
+
+TEST(HeapprofdProducerIntegrationTest, Restart) {
+  base::TmpDirTree tmpdir_;
+
+  base::TestTaskRunner task_runner;
+
+  tmpdir_.TrackFile("producer.sock");
+  tmpdir_.TrackFile("consumer.sock");
+
+  std::optional<TracingServiceThread> tracing_service;
+  tracing_service.emplace(tmpdir_.AbsolutePath("producer.sock"),
+                          tmpdir_.AbsolutePath("consumer.sock"));
+
+  tmpdir_.TrackFile("heapprofd.sock");
+  HeapprofdThread heapprofd_service(tmpdir_.AbsolutePath("producer.sock"),
+                                    tmpdir_.AbsolutePath("heapprofd.sock"));
+
+  std::unique_ptr<NiceMock<MockConsumer>> consumer =
+      StartHeapprofdTrace(tmpdir_.AbsolutePath("consumer.sock"), &task_runner);
+  ASSERT_THAT(consumer, NotNull());
+
+  std::optional<base::UnixSocketRaw> client_sock =
+      perfetto::profiling::Client::ConnectToHeapprofd(
+          tmpdir_.AbsolutePath("heapprofd.sock"));
+  ASSERT_TRUE(client_sock.has_value());
+
+  std::shared_ptr<Client> client =
+      perfetto::profiling::Client::CreateAndHandshake(
+          std::move(client_sock.value()),
+          UnhookedAllocator<perfetto::profiling::Client>(malloc, free));
+
+  // Shutdown tracing service. This should cause HeapprofdProducer::Restart() to
+  // be executed on the heapprofd thread.
+  tracing_service.reset();
+  // Wait for the effects of the tracing service disconnect to propagate to the
+  // heapprofd thread.
+  heapprofd_service.Sync();
+
+  consumer->ForceDisconnect();
+  consumer.reset();
+
+  task_runner.RunUntilIdle();
+
+  // Start tracing service again. Heapprofd should reconnect.
+  ASSERT_EQ(remove(tmpdir_.AbsolutePath("producer.sock").c_str()), 0);
+  ASSERT_EQ(remove(tmpdir_.AbsolutePath("consumer.sock").c_str()), 0);
+  tracing_service.emplace(tmpdir_.AbsolutePath("producer.sock"),
+                          tmpdir_.AbsolutePath("consumer.sock"));
+
+  consumer =
+      StartHeapprofdTrace(tmpdir_.AbsolutePath("consumer.sock"), &task_runner);
+  ASSERT_THAT(consumer, NotNull());
+
+  consumer->ForceDisconnect();
+  consumer.reset();
+}
+
+}  // namespace
+}  // namespace profiling
+}  // namespace perfetto
diff --git a/src/profiling/memory/java_hprof_producer.cc b/src/profiling/memory/java_hprof_producer.cc
index 81a9c27..01bd01c 100644
--- a/src/profiling/memory/java_hprof_producer.cc
+++ b/src/profiling/memory/java_hprof_producer.cc
@@ -18,8 +18,8 @@
 
 #include <signal.h>
 #include <limits>
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/tracing/core/trace_writer.h"
 #include "src/profiling/common/proc_cmdline.h"
 #include "src/profiling/common/proc_utils.h"
diff --git a/src/profiling/memory/shared_ring_buffer.cc b/src/profiling/memory/shared_ring_buffer.cc
index 3cc02e2..32d9b3c 100644
--- a/src/profiling/memory/shared_ring_buffer.cc
+++ b/src/profiling/memory/shared_ring_buffer.cc
@@ -186,7 +186,7 @@
   PERFETTO_DCHECK(spinlock.locked());
   Buffer result;
 
-  base::Optional<PointerPositions> opt_pos = GetPointerPositions();
+  std::optional<PointerPositions> opt_pos = GetPointerPositions();
   if (!opt_pos) {
     meta_->stats.num_writes_corrupt++;
     errno = EBADF;
@@ -245,7 +245,7 @@
 }
 
 SharedRingBuffer::Buffer SharedRingBuffer::BeginRead() {
-  base::Optional<PointerPositions> opt_pos = GetPointerPositions();
+  std::optional<PointerPositions> opt_pos = GetPointerPositions();
   if (!opt_pos) {
     meta_->stats.num_reads_corrupt++;
     errno = EBADF;
@@ -322,20 +322,20 @@
 }
 
 // static
-base::Optional<SharedRingBuffer> SharedRingBuffer::Create(size_t size) {
+std::optional<SharedRingBuffer> SharedRingBuffer::Create(size_t size) {
   auto buf = SharedRingBuffer(CreateFlag(), size);
   if (!buf.is_valid())
-    return base::nullopt;
-  return base::make_optional(std::move(buf));
+    return std::nullopt;
+  return std::make_optional(std::move(buf));
 }
 
 // static
-base::Optional<SharedRingBuffer> SharedRingBuffer::Attach(
+std::optional<SharedRingBuffer> SharedRingBuffer::Attach(
     base::ScopedFile mem_fd) {
   auto buf = SharedRingBuffer(AttachFlag(), std::move(mem_fd));
   if (!buf.is_valid())
-    return base::nullopt;
-  return base::make_optional(std::move(buf));
+    return std::nullopt;
+  return std::make_optional(std::move(buf));
 }
 
 }  // namespace profiling
diff --git a/src/profiling/memory/shared_ring_buffer.h b/src/profiling/memory/shared_ring_buffer.h
index 5bdb28e..9bc2e26 100644
--- a/src/profiling/memory/shared_ring_buffer.h
+++ b/src/profiling/memory/shared_ring_buffer.h
@@ -16,8 +16,8 @@
 
 #ifndef SRC_PROFILING_MEMORY_SHARED_RING_BUFFER_H_
 #define SRC_PROFILING_MEMORY_SHARED_RING_BUFFER_H_
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/unix_socket.h"
 #include "perfetto/ext/base/utils.h"
 #include "src/profiling/memory/scoped_spinlock.h"
@@ -97,8 +97,8 @@
     PERFETTO_CROSS_ABI_ALIGNED(ErrorState) error_state;
   };
 
-  static base::Optional<SharedRingBuffer> Create(size_t);
-  static base::Optional<SharedRingBuffer> Attach(base::ScopedFile);
+  static std::optional<SharedRingBuffer> Create(size_t);
+  static std::optional<SharedRingBuffer> Attach(base::ScopedFile);
 
   ~SharedRingBuffer();
   SharedRingBuffer() = default;
@@ -228,7 +228,7 @@
   void Initialize(base::ScopedFile mem_fd);
   bool IsCorrupt(const PointerPositions& pos);
 
-  inline base::Optional<PointerPositions> GetPointerPositions() {
+  inline std::optional<PointerPositions> GetPointerPositions() {
     PointerPositions pos;
     // We need to acquire load the write_pos to make sure we observe a
     // consistent ring buffer in BeginRead, otherwise it is possible that we
@@ -239,7 +239,7 @@
     pos.write_pos = meta_->write_pos.load(std::memory_order_acquire);
     pos.read_pos = meta_->read_pos.load(std::memory_order_relaxed);
 
-    base::Optional<PointerPositions> result;
+    std::optional<PointerPositions> result;
     if (IsCorrupt(pos))
       return result;
     result = pos;
diff --git a/src/profiling/memory/shared_ring_buffer_unittest.cc b/src/profiling/memory/shared_ring_buffer_unittest.cc
index 7f58b90..ff533f3 100644
--- a/src/profiling/memory/shared_ring_buffer_unittest.cc
+++ b/src/profiling/memory/shared_ring_buffer_unittest.cc
@@ -18,11 +18,11 @@
 
 #include <array>
 #include <mutex>
+#include <optional>
 #include <random>
 #include <thread>
 #include <unordered_map>
 
-#include "perfetto/ext/base/optional.h"
 #include "test/gtest_and_gmock.h"
 
 namespace perfetto {
@@ -147,18 +147,18 @@
 
 TEST(SharedRingBufferTest, ReadShutdown) {
   constexpr auto kBufSize = base::kPageSize * 4;
-  base::Optional<SharedRingBuffer> wr = SharedRingBuffer::Create(kBufSize);
+  std::optional<SharedRingBuffer> wr = SharedRingBuffer::Create(kBufSize);
   ASSERT_TRUE(wr);
   SharedRingBuffer rd =
       *SharedRingBuffer::Attach(base::ScopedFile(dup(wr->fd())));
   auto buf = rd.BeginRead();
-  wr = base::nullopt;
+  wr = std::nullopt;
   rd.EndRead(std::move(buf));
 }
 
 TEST(SharedRingBufferTest, WriteShutdown) {
   constexpr auto kBufSize = base::kPageSize * 4;
-  base::Optional<SharedRingBuffer> rd = SharedRingBuffer::Create(kBufSize);
+  std::optional<SharedRingBuffer> rd = SharedRingBuffer::Create(kBufSize);
   ASSERT_TRUE(rd);
   SharedRingBuffer wr =
       *SharedRingBuffer::Attach(base::ScopedFile(dup(rd->fd())));
@@ -167,21 +167,21 @@
     auto lock = wr.AcquireLock(ScopedSpinlock::Mode::Blocking);
     buf = wr.BeginWrite(lock, 10);
   }
-  rd = base::nullopt;
+  rd = std::nullopt;
   memset(buf.data, 0, buf.size);
   wr.EndWrite(std::move(buf));
 }
 
 TEST(SharedRingBufferTest, SingleThreadSameInstance) {
   constexpr auto kBufSize = base::kPageSize * 4;
-  base::Optional<SharedRingBuffer> buf = SharedRingBuffer::Create(kBufSize);
+  std::optional<SharedRingBuffer> buf = SharedRingBuffer::Create(kBufSize);
   StructuredTest(&*buf, &*buf);
 }
 
 TEST(SharedRingBufferTest, SingleThreadAttach) {
   constexpr auto kBufSize = base::kPageSize * 4;
-  base::Optional<SharedRingBuffer> buf1 = SharedRingBuffer::Create(kBufSize);
-  base::Optional<SharedRingBuffer> buf2 =
+  std::optional<SharedRingBuffer> buf1 = SharedRingBuffer::Create(kBufSize);
+  std::optional<SharedRingBuffer> buf2 =
       SharedRingBuffer::Attach(base::ScopedFile(dup(buf1->fd())));
   StructuredTest(&*buf1, &*buf2);
 }
@@ -256,13 +256,13 @@
 
 TEST(SharedRingBufferTest, InvalidSize) {
   constexpr auto kBufSize = base::kPageSize * 4 + 1;
-  base::Optional<SharedRingBuffer> wr = SharedRingBuffer::Create(kBufSize);
-  EXPECT_EQ(wr, base::nullopt);
+  std::optional<SharedRingBuffer> wr = SharedRingBuffer::Create(kBufSize);
+  EXPECT_EQ(wr, std::nullopt);
 }
 
 TEST(SharedRingBufferTest, EmptyWrite) {
   constexpr auto kBufSize = base::kPageSize * 4;
-  base::Optional<SharedRingBuffer> wr = SharedRingBuffer::Create(kBufSize);
+  std::optional<SharedRingBuffer> wr = SharedRingBuffer::Create(kBufSize);
   ASSERT_TRUE(wr);
   SharedRingBuffer::Buffer buf;
   {
diff --git a/src/profiling/perf/event_config.cc b/src/profiling/perf/event_config.cc
index a89d0c9..25b05c3 100644
--- a/src/profiling/perf/event_config.cc
+++ b/src/profiling/perf/event_config.cc
@@ -20,10 +20,10 @@
 #include <time.h>
 
 #include <unwindstack/Regs.h>
+#include <optional>
 #include <vector>
 
 #include "perfetto/base/flat_set.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/utils.h"
 #include "src/profiling/perf/regs_parsing.h"
 
@@ -56,7 +56,7 @@
 }
 
 // If set, the returned id is guaranteed to be non-zero.
-base::Optional<uint32_t> ParseTracepointAndResolveId(
+std::optional<uint32_t> ParseTracepointAndResolveId(
     const protos::gen::PerfEvents::Tracepoint& tracepoint,
     EventConfig::tracepoint_id_fn_t tracepoint_id_lookup) {
   std::string full_name = tracepoint.name();
@@ -68,7 +68,7 @@
         "Invalid tracepoint format: %s. Should be a full path like "
         "sched:sched_switch or sched/sched_switch.",
         full_name.c_str());
-    return base::nullopt;
+    return std::nullopt;
   }
 
   uint32_t tracepoint_id = tracepoint_id_lookup(tp_group, tp_name);
@@ -77,9 +77,9 @@
         "Failed to resolve tracepoint %s to its id. Check that tracefs is "
         "accessible and the event exists.",
         full_name.c_str());
-    return base::nullopt;
+    return std::nullopt;
   }
-  return base::make_optional(tracepoint_id);
+  return std::make_optional(tracepoint_id);
 }
 
 // |T| is either gen::PerfEventConfig or gen::PerfEventConfig::Scope.
@@ -91,7 +91,7 @@
 template <typename T>
 TargetFilter ParseTargetFilter(
     const T& cfg,
-    base::Optional<ProcessSharding> process_sharding) {
+    std::optional<ProcessSharding> process_sharding) {
   TargetFilter filter;
   for (const auto& str : cfg.target_cmdline()) {
     filter.cmdlines.push_back(str);
@@ -114,22 +114,22 @@
   return (v != 0 && ((v & (v - 1)) == 0));
 }
 
-// returns |base::nullopt| if the input is invalid.
-base::Optional<uint32_t> ChooseActualRingBufferPages(uint32_t config_value) {
+// returns |std::nullopt| if the input is invalid.
+std::optional<uint32_t> ChooseActualRingBufferPages(uint32_t config_value) {
   if (!config_value) {
     static_assert(IsPowerOfTwo(kDefaultDataPagesPerRingBuffer), "");
-    return base::make_optional(kDefaultDataPagesPerRingBuffer);
+    return std::make_optional(kDefaultDataPagesPerRingBuffer);
   }
 
   if (!IsPowerOfTwo(config_value)) {
     PERFETTO_ELOG("kernel buffer size must be a power of two pages");
-    return base::nullopt;
+    return std::nullopt;
   }
 
-  return base::make_optional(config_value);
+  return std::make_optional(config_value);
 }
 
-base::Optional<PerfCounter> ToPerfCounter(
+std::optional<PerfCounter> ToPerfCounter(
     std::string name,
     protos::gen::PerfEvents::Counter pb_enum) {
   using protos::gen::PerfEvents;
@@ -218,7 +218,7 @@
     default:
       PERFETTO_ELOG("Unrecognised PerfEvents::Counter enum value: %zu",
                     static_cast<size_t>(pb_enum));
-      return base::nullopt;
+      return std::nullopt;
   }
 }
 
@@ -294,10 +294,10 @@
 }
 
 // static
-base::Optional<EventConfig> EventConfig::Create(
+std::optional<EventConfig> EventConfig::Create(
     const protos::gen::PerfEventConfig& pb_config,
     const DataSourceConfig& raw_ds_config,
-    base::Optional<ProcessSharding> process_sharding,
+    std::optional<ProcessSharding> process_sharding,
     tracepoint_id_fn_t tracepoint_id_lookup) {
   // Timebase: sampling interval.
   uint64_t sampling_frequency = 0;
@@ -321,15 +321,15 @@
     auto maybe_counter =
         ToPerfCounter(timebase_name, pb_config.timebase().counter());
     if (!maybe_counter)
-      return base::nullopt;
+      return std::nullopt;
     timebase_event = *maybe_counter;
 
   } else if (pb_config.timebase().has_tracepoint()) {
     const auto& tracepoint_pb = pb_config.timebase().tracepoint();
-    base::Optional<uint32_t> maybe_id =
+    std::optional<uint32_t> maybe_id =
         ParseTracepointAndResolveId(tracepoint_pb, tracepoint_id_lookup);
     if (!maybe_id)
-      return base::nullopt;
+      return std::nullopt;
     timebase_event = PerfCounter::Tracepoint(
         timebase_name, tracepoint_pb.name(), tracepoint_pb.filter(), *maybe_id);
 
@@ -370,7 +370,7 @@
         // enum value from the future that we don't yet know, refuse the config
         // TODO(rsavitski): double-check that both pbzero and ::gen propagate
         // unknown enum values.
-        return base::nullopt;
+        return std::nullopt;
     }
 
     // Process scoping. Sharding parameter is supplied from outside as it is
@@ -388,10 +388,10 @@
   }
 
   // Ring buffer options.
-  base::Optional<uint32_t> ring_buffer_pages =
+  std::optional<uint32_t> ring_buffer_pages =
       ChooseActualRingBufferPages(pb_config.ring_buffer_pages());
   if (!ring_buffer_pages.has_value())
-    return base::nullopt;
+    return std::nullopt;
 
   uint32_t read_tick_period_ms = pb_config.ring_buffer_read_period_ms()
                                      ? pb_config.ring_buffer_read_period_ms()
@@ -421,7 +421,7 @@
   PERFETTO_DLOG("Capping samples (not records) per tick to [%" PRIu64 "]",
                 samples_per_tick_limit);
   if (samples_per_tick_limit == 0)
-    return base::nullopt;
+    return std::nullopt;
 
   // Optional footprint controls.
   uint64_t max_enqueued_footprint_bytes =
diff --git a/src/profiling/perf/event_config.h b/src/profiling/perf/event_config.h
index 515a102..dd1a7e3 100644
--- a/src/profiling/perf/event_config.h
+++ b/src/profiling/perf/event_config.h
@@ -25,9 +25,9 @@
 #include <linux/perf_event.h>
 #include <stdint.h>
 #include <sys/types.h>
+#include <optional>
 
 #include "perfetto/base/flat_set.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/tracing/core/data_source_config.h"
 
 #include "protos/perfetto/common/perf_events.gen.h"
@@ -56,7 +56,7 @@
   std::vector<std::string> exclude_cmdlines;
   base::FlatSet<pid_t> pids;
   base::FlatSet<pid_t> exclude_pids;
-  base::Optional<ProcessSharding> process_sharding;
+  std::optional<ProcessSharding> process_sharding;
   uint32_t additional_cmdline_count = 0;
 };
 
@@ -118,10 +118,10 @@
   using tracepoint_id_fn_t =
       std::function<uint32_t(const std::string&, const std::string&)>;
 
-  static base::Optional<EventConfig> Create(
+  static std::optional<EventConfig> Create(
       const protos::gen::PerfEventConfig& pb_config,
       const DataSourceConfig& raw_ds_config,
-      base::Optional<ProcessSharding> process_sharding,
+      std::optional<ProcessSharding> process_sharding,
       tracepoint_id_fn_t tracepoint_id_lookup);
 
   uint32_t ring_buffer_pages() const { return ring_buffer_pages_; }
diff --git a/src/profiling/perf/event_config_unittest.cc b/src/profiling/perf/event_config_unittest.cc
index 95c0a9b..35ec628 100644
--- a/src/profiling/perf/event_config_unittest.cc
+++ b/src/profiling/perf/event_config_unittest.cc
@@ -19,9 +19,9 @@
 #include <linux/perf_event.h>
 #include <stdint.h>
 #include <time.h>
+#include <optional>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "test/gtest_and_gmock.h"
 
 #include "protos/perfetto/common/perf_events.gen.h"
@@ -38,20 +38,20 @@
   return (v != 0 && ((v & (v - 1)) == 0));
 }
 
-base::Optional<EventConfig> CreateEventConfig(
+std::optional<EventConfig> CreateEventConfig(
     const protos::gen::PerfEventConfig& perf_cfg,
     EventConfig::tracepoint_id_fn_t tracepoint_id_lookup =
         [](const std::string&, const std::string&) { return 0; }) {
   protos::gen::DataSourceConfig ds_cfg;
   ds_cfg.set_perf_event_config_raw(perf_cfg.SerializeAsString());
   return EventConfig::Create(perf_cfg, ds_cfg,
-                             /*process_sharding=*/base::nullopt,
+                             /*process_sharding=*/std::nullopt,
                              tracepoint_id_lookup);
 }
 
 TEST(EventConfigTest, AttrStructConstructed) {
   protos::gen::PerfEventConfig cfg;
-  base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+  std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
   ASSERT_TRUE(event_config.has_value());
   ASSERT_TRUE(event_config->perf_attr() != nullptr);
@@ -60,7 +60,7 @@
 TEST(EventConfigTest, RingBufferPagesValidated) {
   {  // if unset, a default is used
     protos::gen::PerfEventConfig cfg;
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     ASSERT_GT(event_config->ring_buffer_pages(), 0u);
@@ -70,7 +70,7 @@
     uint32_t num_pages = 128;
     protos::gen::PerfEventConfig cfg;
     cfg.set_ring_buffer_pages(num_pages);
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     ASSERT_EQ(event_config->ring_buffer_pages(), num_pages);
@@ -78,7 +78,7 @@
   {  // entire config rejected if not a power of two of pages
     protos::gen::PerfEventConfig cfg;
     cfg.set_ring_buffer_pages(7);
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_FALSE(event_config.has_value());
   }
@@ -87,7 +87,7 @@
 TEST(EventConfigTest, ReadTickPeriodDefaultedIfUnset) {
   {  // if unset, a default is used
     protos::gen::PerfEventConfig cfg;
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     ASSERT_GT(event_config->read_tick_period_ms(), 0u);
@@ -96,7 +96,7 @@
     uint32_t period_ms = 250;
     protos::gen::PerfEventConfig cfg;
     cfg.set_ring_buffer_read_period_ms(period_ms);
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     ASSERT_EQ(event_config->read_tick_period_ms(), period_ms);
@@ -106,7 +106,7 @@
 TEST(EventConfigTest, RemotePeriodTimeoutDefaultedIfUnset) {
   {  // if unset, a default is used
     protos::gen::PerfEventConfig cfg;
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     ASSERT_GT(event_config->remote_descriptor_timeout_ms(), 0u);
@@ -115,7 +115,7 @@
     uint32_t timeout_ms = 300;
     protos::gen::PerfEventConfig cfg;
     cfg.set_remote_descriptor_timeout_ms(timeout_ms);
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     ASSERT_EQ(event_config->remote_descriptor_timeout_ms(), timeout_ms);
@@ -126,7 +126,7 @@
   {  // period:
     protos::gen::PerfEventConfig cfg;
     cfg.mutable_timebase()->set_period(100);
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_FALSE(event_config->perf_attr()->freq);
@@ -135,7 +135,7 @@
   {  // frequency:
     protos::gen::PerfEventConfig cfg;
     cfg.mutable_timebase()->set_frequency(4000);
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_TRUE(event_config->perf_attr()->freq);
@@ -144,7 +144,7 @@
   {  // legacy frequency field:
     protos::gen::PerfEventConfig cfg;
     cfg.set_sampling_frequency(5000);
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_TRUE(event_config->perf_attr()->freq);
@@ -152,7 +152,7 @@
   }
   {  // default is 10 Hz (implementation-defined)
     protos::gen::PerfEventConfig cfg;
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_TRUE(event_config->perf_attr()->freq);
@@ -171,8 +171,7 @@
         cfg.mutable_timebase()->mutable_tracepoint();
     mutable_tracepoint->set_name("sched:sched_switch");
 
-    base::Optional<EventConfig> event_config =
-        CreateEventConfig(cfg, id_lookup);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg, id_lookup);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_EQ(event_config->perf_attr()->type, PERF_TYPE_TRACEPOINT);
@@ -181,7 +180,7 @@
   {  // default is the CPU timer:
     protos::gen::PerfEventConfig cfg;
     cfg.mutable_timebase()->set_frequency(1000);
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_EQ(event_config->perf_attr()->type, PERF_TYPE_SOFTWARE);
@@ -199,7 +198,7 @@
     mutable_scope->set_additional_cmdline_count(3);
     mutable_scope->add_exclude_cmdline("heapprofd");
 
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     const auto& filter = event_config->filter();
@@ -220,7 +219,7 @@
     cfg.set_additional_cmdline_count(3);
     cfg.add_exclude_cmdline("heapprofd");
 
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     const auto& filter = event_config->filter();
@@ -241,7 +240,7 @@
     mutable_timebase->set_period(500);
     mutable_timebase->set_counter(protos::gen::PerfEvents::HW_CPU_CYCLES);
 
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_EQ(event_config->perf_attr()->type, PERF_TYPE_HARDWARE);
@@ -256,7 +255,7 @@
     mutable_timebase->set_period(500);
     mutable_timebase->set_counter(protos::gen::PerfEvents::SW_PAGE_FAULTS);
 
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_EQ(event_config->perf_attr()->type, PERF_TYPE_SOFTWARE);
@@ -272,7 +271,7 @@
     protos::gen::PerfEventConfig cfg;
     cfg.mutable_callstack_sampling();  // set field
 
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_TRUE(event_config->sample_callstacks());
@@ -292,7 +291,7 @@
     cfg.mutable_callstack_sampling()->set_user_frames(
         protos::gen::PerfEventConfig::UNWIND_SKIP);
 
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_TRUE(event_config->sample_callstacks());
@@ -315,7 +314,7 @@
   {
     protos::gen::PerfEventConfig cfg;
     cfg.mutable_callstack_sampling()->set_kernel_frames(true);
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_TRUE(event_config->kernel_frames());
@@ -324,14 +323,14 @@
     protos::gen::PerfEventConfig cfg;
     cfg.set_all_cpus(true);  // used to detect compat mode
     cfg.set_kernel_frames(true);
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_TRUE(event_config->kernel_frames());
   }
   {  // default is false
     protos::gen::PerfEventConfig cfg;
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_FALSE(event_config->kernel_frames());
@@ -341,7 +340,7 @@
 TEST(EventConfigTest, TimestampClockId) {
   {  // if unset, a default is used
     protos::gen::PerfEventConfig cfg;
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_TRUE(event_config->perf_attr()->use_clockid);
@@ -351,7 +350,7 @@
     protos::gen::PerfEventConfig cfg;
     cfg.mutable_timebase()->set_timestamp_clock(
         protos::gen::PerfEvents::PERF_CLOCK_BOOTTIME);
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_TRUE(event_config->perf_attr()->use_clockid);
@@ -361,7 +360,7 @@
     protos::gen::PerfEventConfig cfg;
     cfg.mutable_timebase()->set_timestamp_clock(
         protos::gen::PerfEvents::PERF_CLOCK_MONOTONIC);
-    base::Optional<EventConfig> event_config = CreateEventConfig(cfg);
+    std::optional<EventConfig> event_config = CreateEventConfig(cfg);
 
     ASSERT_TRUE(event_config.has_value());
     EXPECT_TRUE(event_config->perf_attr()->use_clockid);
diff --git a/src/profiling/perf/event_reader.cc b/src/profiling/perf/event_reader.cc
index 5f52f88..2a40c6c 100644
--- a/src/profiling/perf/event_reader.cc
+++ b/src/profiling/perf/event_reader.cc
@@ -111,9 +111,8 @@
     PERFETTO_PLOG("failed munmap");
 }
 
-base::Optional<PerfRingBuffer> PerfRingBuffer::Allocate(
-    int perf_fd,
-    size_t data_page_count) {
+std::optional<PerfRingBuffer> PerfRingBuffer::Allocate(int perf_fd,
+                                                       size_t data_page_count) {
   // perf_event_open requires the ring buffer to be a power of two in size.
   PERFETTO_DCHECK(IsPowerOfTwo(data_page_count));
 
@@ -128,7 +127,7 @@
                          MAP_SHARED, perf_fd, 0);
   if (mmap_addr == MAP_FAILED) {
     PERFETTO_PLOG("failed mmap");
-    return base::nullopt;
+    return std::nullopt;
   }
 
   // Expected layout is [ metadata page ] [ data pages ... ]
@@ -139,7 +138,7 @@
 
   PERFETTO_DCHECK(IsPowerOfTwo(ret.data_buf_sz_));
 
-  return base::make_optional(std::move(ret));
+  return std::make_optional(std::move(ret));
 }
 
 // See |perf_output_put_handle| for the necessary synchronization between the
@@ -224,41 +223,39 @@
   return *this;
 }
 
-base::Optional<EventReader> EventReader::ConfigureEvents(
+std::optional<EventReader> EventReader::ConfigureEvents(
     uint32_t cpu,
     const EventConfig& event_cfg) {
   auto leader_fd = PerfEventOpen(cpu, event_cfg.perf_attr());
   if (!leader_fd) {
     PERFETTO_PLOG("Failed perf_event_open");
-    return base::nullopt;
+    return std::nullopt;
   }
   if (!MaybeApplyTracepointFilter(leader_fd.get(), event_cfg.timebase_event()))
-    return base::nullopt;
+    return std::nullopt;
 
   auto ring_buffer =
       PerfRingBuffer::Allocate(leader_fd.get(), event_cfg.ring_buffer_pages());
   if (!ring_buffer.has_value()) {
-    return base::nullopt;
+    return std::nullopt;
   }
-
-  return base::make_optional<EventReader>(cpu, *event_cfg.perf_attr(),
-                                          std::move(leader_fd),
-                                          std::move(ring_buffer.value()));
+  return EventReader(cpu, *event_cfg.perf_attr(), std::move(leader_fd),
+                     std::move(ring_buffer.value()));
 }
 
-base::Optional<ParsedSample> EventReader::ReadUntilSample(
+std::optional<ParsedSample> EventReader::ReadUntilSample(
     std::function<void(uint64_t)> records_lost_callback) {
   for (;;) {
     char* event = ring_buffer_.ReadRecordNonconsuming();
     if (!event)
-      return base::nullopt;  // caught up with the writer
+      return std::nullopt;  // caught up with the writer
 
     auto* event_hdr = reinterpret_cast<const perf_event_header*>(event);
 
     if (event_hdr->type == PERF_RECORD_SAMPLE) {
       ParsedSample sample = ParseSampleRecord(cpu_, event);
       ring_buffer_.Consume(event_hdr->size);
-      return base::make_optional(std::move(sample));
+      return std::make_optional(std::move(sample));
     }
 
     if (event_hdr->type == PERF_RECORD_LOST) {
diff --git a/src/profiling/perf/event_reader.h b/src/profiling/perf/event_reader.h
index 9c86fc9..11a63bb 100644
--- a/src/profiling/perf/event_reader.h
+++ b/src/profiling/perf/event_reader.h
@@ -21,8 +21,8 @@
 #include <stdint.h>
 #include <sys/mman.h>
 #include <sys/types.h>
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/tracing/core/basic_types.h"
 #include "src/profiling/perf/common_types.h"
@@ -33,8 +33,8 @@
 
 class PerfRingBuffer {
  public:
-  static base::Optional<PerfRingBuffer> Allocate(int perf_fd,
-                                                 size_t data_page_count);
+  static std::optional<PerfRingBuffer> Allocate(int perf_fd,
+                                                size_t data_page_count);
 
   ~PerfRingBuffer();
 
@@ -71,18 +71,14 @@
 
 class EventReader {
  public:
-  // Allow base::Optional<EventReader> without making the constructor public.
-  template <typename EventReader, bool>
-  friend struct base::internal::OptionalStorageBase;
-
-  static base::Optional<EventReader> ConfigureEvents(
+  static std::optional<EventReader> ConfigureEvents(
       uint32_t cpu,
       const EventConfig& event_cfg);
 
   // Consumes records from the ring buffer until either encountering a sample,
   // or catching up to the writer. The other record of interest
   // (PERF_RECORD_LOST) is handled via the given callback.
-  base::Optional<ParsedSample> ReadUntilSample(
+  std::optional<ParsedSample> ReadUntilSample(
       std::function<void(uint64_t)> lost_events_callback);
 
   void EnableEvents();
diff --git a/src/profiling/perf/perf_producer.cc b/src/profiling/perf/perf_producer.cc
index ee15555..0fb7be3 100644
--- a/src/profiling/perf/perf_producer.cc
+++ b/src/profiling/perf/perf_producer.cc
@@ -379,7 +379,7 @@
   // Unlikely: handle a callstack sampling option that shares a random decision
   // between all data sources within a tracing session. Instead of introducing
   // session-scoped data, we replicate the decision in each per-DS EventConfig.
-  base::Optional<ProcessSharding> process_sharding;
+  std::optional<ProcessSharding> process_sharding;
   uint32_t shard_count =
       event_config_pb.callstack_sampling().scope().process_shard_count();
   if (shard_count > 0) {
@@ -387,7 +387,7 @@
         GetOrChooseCallstackProcessShard(tracing_session_id, shard_count);
   }
 
-  base::Optional<EventConfig> event_config = EventConfig::Create(
+  std::optional<EventConfig> event_config = EventConfig::Create(
       event_config_pb, config, process_sharding, tracepoint_id_lookup);
   if (!event_config.has_value()) {
     PERFETTO_ELOG("PerfEventConfig rejected.");
@@ -397,7 +397,7 @@
   size_t num_cpus = NumberOfCpus();
   std::vector<EventReader> per_cpu_readers;
   for (uint32_t cpu = 0; cpu < num_cpus; cpu++) {
-    base::Optional<EventReader> event_reader =
+    std::optional<EventReader> event_reader =
         EventReader::ConfigureEvents(cpu, event_config.value());
     if (!event_reader.has_value()) {
       PERFETTO_ELOG("Failed to set up perf events for cpu%" PRIu32
@@ -632,7 +632,7 @@
   };
 
   for (uint64_t i = 0; i < max_samples; i++) {
-    base::Optional<ParsedSample> sample =
+    std::optional<ParsedSample> sample =
         reader->ReadUntilSample(records_lost_callback);
     if (!sample) {
       return false;  // caught up to the writer
@@ -1082,7 +1082,7 @@
 // * reuse a choice made previously by a data source within this tracing
 //   session. The config option requires that all data sources within one config
 //   have the same shard count.
-base::Optional<ProcessSharding> PerfProducer::GetOrChooseCallstackProcessShard(
+std::optional<ProcessSharding> PerfProducer::GetOrChooseCallstackProcessShard(
     uint64_t tracing_session_id,
     uint32_t shard_count) {
   for (auto& it : data_sources_) {
diff --git a/src/profiling/perf/perf_producer.h b/src/profiling/perf/perf_producer.h
index 31d5ff5..83174d3 100644
--- a/src/profiling/perf/perf_producer.h
+++ b/src/profiling/perf/perf_producer.h
@@ -17,16 +17,15 @@
 #ifndef SRC_PROFILING_PERF_PERF_PRODUCER_H_
 #define SRC_PROFILING_PERF_PERF_PRODUCER_H_
 
+#include <unistd.h>
 #include <map>
 #include <memory>
-
-#include <unistd.h>
+#include <optional>
 
 #include <unwindstack/Error.h>
 #include <unwindstack/Regs.h>
 
 #include "perfetto/base/task_runner.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/unix_socket.h"
 #include "perfetto/ext/base/weak_ptr.h"
@@ -240,7 +239,7 @@
 
   // Chooses a random parameter for a callstack sampling option. Done at this
   // level as the choice is shared by all data sources within a tracing session.
-  base::Optional<ProcessSharding> GetOrChooseCallstackProcessShard(
+  std::optional<ProcessSharding> GetOrChooseCallstackProcessShard(
       uint64_t tracing_session_id,
       uint32_t shard_count);
 
diff --git a/src/profiling/perf/perf_producer_unittest.cc b/src/profiling/perf/perf_producer_unittest.cc
index 22f4002..76b615a 100644
--- a/src/profiling/perf/perf_producer_unittest.cc
+++ b/src/profiling/perf/perf_producer_unittest.cc
@@ -17,9 +17,9 @@
 #include "src/profiling/perf/perf_producer.h"
 
 #include <stdint.h>
+#include <optional>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "test/gtest_and_gmock.h"
 
 namespace perfetto {
diff --git a/src/profiling/perf/unwinding.h b/src/profiling/perf/unwinding.h
index 08d6e86..8295fb8 100644
--- a/src/profiling/perf/unwinding.h
+++ b/src/profiling/perf/unwinding.h
@@ -17,18 +17,17 @@
 #ifndef SRC_PROFILING_PERF_UNWINDING_H_
 #define SRC_PROFILING_PERF_UNWINDING_H_
 
+#include <stdint.h>
 #include <condition_variable>
 #include <map>
+#include <optional>
 #include <thread>
 
 #include <linux/perf_event.h>
-#include <stdint.h>
-
 #include <unwindstack/Error.h>
 
 #include "perfetto/base/flat_set.h"
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/thread_checker.h"
 #include "perfetto/ext/base/unix_task_runner.h"
 #include "perfetto/ext/tracing/core/basic_types.h"
@@ -137,7 +136,7 @@
 
     Status status = Status::kInitial;
     // Present iff status == kFdsResolved.
-    base::Optional<UnwindingMetadata> unwind_state;
+    std::optional<UnwindingMetadata> unwind_state;
     // Used to distinguish first-time unwinding attempts for a process, for
     // logging purposes.
     bool attempted_unwinding = false;
diff --git a/src/profiling/symbolizer/breakpad_parser.cc b/src/profiling/symbolizer/breakpad_parser.cc
index 5c3c5c0..5e996a7 100644
--- a/src/profiling/symbolizer/breakpad_parser.cc
+++ b/src/profiling/symbolizer/breakpad_parser.cc
@@ -32,18 +32,18 @@
   return i < sym.start_address;
 }
 
-base::Optional<std::string> GetFileContents(const std::string& file_path) {
+std::optional<std::string> GetFileContents(const std::string& file_path) {
   std::string file_contents;
   base::ScopedFile fd = base::OpenFile(file_path, O_RDONLY);
   // Read the contents of the file into |file_contents|.
   if (!fd) {
-    return base::nullopt;
+    return std::nullopt;
   }
   if (!base::ReadFileDescriptor(fd.get(), &file_contents)) {
-    return base::nullopt;
+    return std::nullopt;
   }
 
-  return base::make_optional(std::move(file_contents));
+  return std::make_optional(std::move(file_contents));
 }
 
 // Parses the given string and determines if it begins with the label
@@ -65,7 +65,7 @@
     : file_path_(file_path) {}
 
 bool BreakpadParser::ParseFile() {
-  base::Optional<std::string> file_contents = GetFileContents(file_path_);
+  std::optional<std::string> file_contents = GetFileContents(file_path_);
   if (!file_contents) {
     PERFETTO_ELOG("Could not get file contents of %s.", file_path_.c_str());
     return false;
@@ -111,7 +111,7 @@
   return true;
 }
 
-base::Optional<std::string> BreakpadParser::GetSymbol(uint64_t address) const {
+std::optional<std::string> BreakpadParser::GetSymbol(uint64_t address) const {
   // Returns an iterator pointing to the first element where the symbol's start
   // address is greater than |address|.
   auto it = std::upper_bound(symbols_.begin(), symbols_.end(), address,
@@ -119,7 +119,7 @@
   // If the first symbol's address is greater than |address| then |address| is
   // too low to appear in |symbols_|.
   if (it == symbols_.begin()) {
-    return base::nullopt;
+    return std::nullopt;
   }
   // upper_bound() returns the first symbol who's start address is greater than
   // |address|. Therefore to find the symbol with a range of addresses that
@@ -130,7 +130,7 @@
       address < it->start_address + it->function_size) {
     return it->symbol_name;
   }
-  return base::nullopt;
+  return std::nullopt;
 }
 
 base::Status BreakpadParser::ParseIfFuncRecord(base::StringView current_line) {
@@ -170,7 +170,7 @@
   }
 
   // Get the start address.
-  base::Optional<uint64_t> optional_address =
+  std::optional<uint64_t> optional_address =
       base::CStringToUInt64(words.cur_token(), 16);
   if (!optional_address) {
     return base::Status("Address should be hexadecimal.");
@@ -179,7 +179,7 @@
 
   // Get the function size.
   words.Next();
-  base::Optional<size_t> optional_func_size =
+  std::optional<size_t> optional_func_size =
       base::CStringToUInt32(words.cur_token(), 16);
   if (!optional_func_size) {
     return base::Status("Function size should be hexadecimal.");
diff --git a/src/profiling/symbolizer/breakpad_parser.h b/src/profiling/symbolizer/breakpad_parser.h
index 0377353..8926a94 100644
--- a/src/profiling/symbolizer/breakpad_parser.h
+++ b/src/profiling/symbolizer/breakpad_parser.h
@@ -17,11 +17,11 @@
 #ifndef SRC_PROFILING_SYMBOLIZER_BREAKPAD_PARSER_H_
 #define SRC_PROFILING_SYMBOLIZER_BREAKPAD_PARSER_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "perfetto/base/status.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 
 namespace perfetto {
@@ -64,7 +64,7 @@
   // Returns the function name corresponding to |address| as a string. The
   // search is log(N) on the number of functions in the binary. |address| is the
   // relative offset from the start of the binary.
-  base::Optional<std::string> GetSymbol(uint64_t address) const;
+  std::optional<std::string> GetSymbol(uint64_t address) const;
 
   const std::vector<Symbol>& symbols_for_testing() const { return symbols_; }
 
diff --git a/src/profiling/symbolizer/breakpad_symbolizer.cc b/src/profiling/symbolizer/breakpad_symbolizer.cc
index c7558c7..763d34f 100644
--- a/src/profiling/symbolizer/breakpad_symbolizer.cc
+++ b/src/profiling/symbolizer/breakpad_symbolizer.cc
@@ -16,9 +16,10 @@
 
 #include "src/profiling/symbolizer/breakpad_symbolizer.h"
 
+#include <optional>
+
 #include "perfetto/base/build_config.h"
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/ext/base/string_writer.h"
 #include "src/profiling/symbolizer/breakpad_parser.h"
@@ -83,7 +84,7 @@
   // Add each address's function name to the |result| vector in the same order.
   for (uint64_t addr : address) {
     SymbolizedFrame frame;
-    base::Optional<std::string> opt_func_name = parser.GetSymbol(addr);
+    std::optional<std::string> opt_func_name = parser.GetSymbol(addr);
     if (opt_func_name) {
       frame.function_name = *opt_func_name;
       num_symbolized_frames++;
diff --git a/src/profiling/symbolizer/local_symbolizer.cc b/src/profiling/symbolizer/local_symbolizer.cc
index ce11a40..0382556 100644
--- a/src/profiling/symbolizer/local_symbolizer.cc
+++ b/src/profiling/symbolizer/local_symbolizer.cc
@@ -20,6 +20,7 @@
 
 #include <cinttypes>
 #include <memory>
+#include <optional>
 #include <sstream>
 #include <string>
 #include <vector>
@@ -28,7 +29,6 @@
 #include "perfetto/base/compiler.h"
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "src/profiling/symbolizer/elf.h"
@@ -126,17 +126,17 @@
 }
 
 template <typename E>
-base::Optional<uint64_t> GetLoadBias(void* mem, size_t size) {
+std::optional<uint64_t> GetLoadBias(void* mem, size_t size) {
   const typename E::Ehdr* ehdr = static_cast<typename E::Ehdr*>(mem);
   if (!InRange(mem, size, ehdr, sizeof(typename E::Ehdr))) {
     PERFETTO_ELOG("Corrupted ELF.");
-    return base::nullopt;
+    return std::nullopt;
   }
   for (size_t i = 0; i < ehdr->e_phnum; ++i) {
     typename E::Phdr* phdr = GetPhdr<E>(mem, ehdr, i);
     if (!InRange(mem, size, phdr, sizeof(typename E::Phdr))) {
       PERFETTO_ELOG("Corrupted ELF.");
-      return base::nullopt;
+      return std::nullopt;
     }
     if (phdr->p_type == PT_LOAD && phdr->p_flags & PF_X) {
       return phdr->p_vaddr - phdr->p_offset;
@@ -146,17 +146,17 @@
 }
 
 template <typename E>
-base::Optional<std::string> GetBuildId(void* mem, size_t size) {
+std::optional<std::string> GetBuildId(void* mem, size_t size) {
   const typename E::Ehdr* ehdr = static_cast<typename E::Ehdr*>(mem);
   if (!InRange(mem, size, ehdr, sizeof(typename E::Ehdr))) {
     PERFETTO_ELOG("Corrupted ELF.");
-    return base::nullopt;
+    return std::nullopt;
   }
   for (size_t i = 0; i < ehdr->e_shnum; ++i) {
     typename E::Shdr* shdr = GetShdr<E>(mem, ehdr, i);
     if (!InRange(mem, size, shdr, sizeof(typename E::Shdr))) {
       PERFETTO_ELOG("Corrupted ELF.");
-      return base::nullopt;
+      return std::nullopt;
     }
 
     if (shdr->sh_type != SHT_NOTE)
@@ -169,13 +169,13 @@
 
       if (!InRange(mem, size, nhdr, sizeof(typename E::Nhdr))) {
         PERFETTO_ELOG("Corrupted ELF.");
-        return base::nullopt;
+        return std::nullopt;
       }
       if (nhdr->n_type == NT_GNU_BUILD_ID && nhdr->n_namesz == 4) {
         char* name = reinterpret_cast<char*>(nhdr) + sizeof(*nhdr);
         if (!InRange(mem, size, name, 4)) {
           PERFETTO_ELOG("Corrupted ELF.");
-          return base::nullopt;
+          return std::nullopt;
         }
         if (memcmp(name, "GNU", 3) == 0) {
           const char* value = reinterpret_cast<char*>(nhdr) + sizeof(*nhdr) +
@@ -183,7 +183,7 @@
 
           if (!InRange(mem, size, value, nhdr->n_descsz)) {
             PERFETTO_ELOG("Corrupted ELF.");
-            return base::nullopt;
+            return std::nullopt;
           }
           return std::string(value, nhdr->n_descsz);
         }
@@ -192,7 +192,7 @@
                 base::AlignUp<4>(nhdr->n_descsz);
     }
   }
-  return base::nullopt;
+  return std::nullopt;
 }
 
 std::string SplitBuildID(const std::string& hex_build_id) {
@@ -217,23 +217,23 @@
   uint64_t load_bias;
 };
 
-base::Optional<BuildIdAndLoadBias> GetBuildIdAndLoadBias(const char* fname,
-                                                         size_t size) {
+std::optional<BuildIdAndLoadBias> GetBuildIdAndLoadBias(const char* fname,
+                                                        size_t size) {
   static_assert(EI_CLASS > EI_MAG3, "mem[EI_MAG?] accesses are in range.");
   if (size <= EI_CLASS)
-    return base::nullopt;
+    return std::nullopt;
   ScopedReadMmap map(fname, size);
   if (!map.IsValid()) {
     PERFETTO_PLOG("mmap");
-    return base::nullopt;
+    return std::nullopt;
   }
   char* mem = static_cast<char*>(*map);
 
   if (!IsElf(mem, size))
-    return base::nullopt;
+    return std::nullopt;
 
-  base::Optional<std::string> build_id;
-  base::Optional<uint64_t> load_bias;
+  std::optional<std::string> build_id;
+  std::optional<uint64_t> load_bias;
   switch (mem[EI_CLASS]) {
     case ELFCLASS32:
       build_id = GetBuildId<Elf32>(mem, size);
@@ -244,12 +244,12 @@
       load_bias = GetLoadBias<Elf64>(mem, size);
       break;
     default:
-      return base::nullopt;
+      return std::nullopt;
   }
   if (build_id && load_bias) {
     return BuildIdAndLoadBias{*build_id, *load_bias};
   }
-  return base::nullopt;
+  return std::nullopt;
 }
 
 std::map<std::string, FoundBinary> BuildIdIndex(std::vector<std::string> dirs) {
@@ -274,7 +274,7 @@
         return;
       }
     }
-    base::Optional<BuildIdAndLoadBias> build_id_and_load_bias =
+    std::optional<BuildIdAndLoadBias> build_id_and_load_bias =
         GetBuildIdAndLoadBias(fname, size);
     if (build_id_and_load_bias) {
       result.emplace(build_id_and_load_bias->build_id,
@@ -298,7 +298,7 @@
   *file_name = line.substr(0, row_pos);
   auto line_no_str = line.substr(row_pos + 1, col_pos - row_pos - 1);
 
-  base::Optional<int32_t> opt_parsed_line_no = base::StringToInt32(line_no_str);
+  std::optional<int32_t> opt_parsed_line_no = base::StringToInt32(line_no_str);
   if (!opt_parsed_line_no || *opt_parsed_line_no < 0)
     return false;
   *line_no = static_cast<uint32_t>(*opt_parsed_line_no);
@@ -310,7 +310,7 @@
 LocalBinaryIndexer::LocalBinaryIndexer(std::vector<std::string> roots)
     : buildid_to_file_(BuildIdIndex(std::move(roots))) {}
 
-base::Optional<FoundBinary> LocalBinaryIndexer::FindBinary(
+std::optional<FoundBinary> LocalBinaryIndexer::FindBinary(
     const std::string& abspath,
     const std::string& build_id) {
   auto it = buildid_to_file_.find(build_id);
@@ -318,7 +318,7 @@
     return it->second;
   PERFETTO_ELOG("Could not find Build ID: %s (file %s).",
                 base::ToHex(build_id).c_str(), abspath.c_str());
-  return base::nullopt;
+  return std::nullopt;
 }
 
 LocalBinaryIndexer::~LocalBinaryIndexer() = default;
@@ -326,14 +326,14 @@
 LocalBinaryFinder::LocalBinaryFinder(std::vector<std::string> roots)
     : roots_(std::move(roots)) {}
 
-base::Optional<FoundBinary> LocalBinaryFinder::FindBinary(
+std::optional<FoundBinary> LocalBinaryFinder::FindBinary(
     const std::string& abspath,
     const std::string& build_id) {
-  auto p = cache_.emplace(abspath, base::nullopt);
+  auto p = cache_.emplace(abspath, std::nullopt);
   if (!p.second)
     return p.first->second;
 
-  base::Optional<FoundBinary>& cache_entry = p.first->second;
+  std::optional<FoundBinary>& cache_entry = p.first->second;
 
   for (const std::string& root_str : roots_) {
     cache_entry = FindBinaryInRoot(root_str, abspath, build_id);
@@ -345,30 +345,30 @@
   return cache_entry;
 }
 
-base::Optional<FoundBinary> LocalBinaryFinder::IsCorrectFile(
+std::optional<FoundBinary> LocalBinaryFinder::IsCorrectFile(
     const std::string& symbol_file,
     const std::string& build_id) {
   if (!base::FileExists(symbol_file)) {
-    return base::nullopt;
+    return std::nullopt;
   }
   // Openfile opens the file with an exclusive lock on windows.
   size_t size = GetFileSize(symbol_file);
 
   if (size == 0) {
-    return base::nullopt;
+    return std::nullopt;
   }
 
-  base::Optional<BuildIdAndLoadBias> build_id_and_load_bias =
+  std::optional<BuildIdAndLoadBias> build_id_and_load_bias =
       GetBuildIdAndLoadBias(symbol_file.c_str(), size);
   if (!build_id_and_load_bias)
-    return base::nullopt;
+    return std::nullopt;
   if (build_id_and_load_bias->build_id != build_id) {
-    return base::nullopt;
+    return std::nullopt;
   }
   return FoundBinary{symbol_file, build_id_and_load_bias->load_bias};
 }
 
-base::Optional<FoundBinary> LocalBinaryFinder::FindBinaryInRoot(
+std::optional<FoundBinary> LocalBinaryFinder::FindBinaryInRoot(
     const std::string& root_str,
     const std::string& abspath,
     const std::string& build_id) {
@@ -404,7 +404,7 @@
   // * $ROOT/foo.so
   // * $ROOT/.build-id/ab/cd1234.debug
 
-  base::Optional<FoundBinary> result;
+  std::optional<FoundBinary> result;
 
   std::string symbol_file = root_str + "/" + dirname + "/" + filename;
   result = IsCorrectFile(symbol_file, build_id);
@@ -446,7 +446,7 @@
     }
   }
 
-  return base::nullopt;
+  return std::nullopt;
 }
 
 LocalBinaryFinder::~LocalBinaryFinder() = default;
@@ -507,7 +507,7 @@
     const std::string& build_id,
     uint64_t load_bias,
     const std::vector<uint64_t>& addresses) {
-  base::Optional<FoundBinary> binary =
+  std::optional<FoundBinary> binary =
       finder_->FindBinary(mapping_name, build_id);
   if (!binary)
     return {};
diff --git a/src/profiling/symbolizer/local_symbolizer.h b/src/profiling/symbolizer/local_symbolizer.h
index bb8b0c2..f92c553 100644
--- a/src/profiling/symbolizer/local_symbolizer.h
+++ b/src/profiling/symbolizer/local_symbolizer.h
@@ -17,12 +17,13 @@
 #ifndef SRC_PROFILING_SYMBOLIZER_LOCAL_SYMBOLIZER_H_
 #define SRC_PROFILING_SYMBOLIZER_LOCAL_SYMBOLIZER_H_
 
+#include <functional>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "src/profiling/symbolizer/subprocess.h"
 #include "src/profiling/symbolizer/symbolizer.h"
@@ -44,7 +45,7 @@
 class BinaryFinder {
  public:
   virtual ~BinaryFinder();
-  virtual base::Optional<FoundBinary> FindBinary(
+  virtual std::optional<FoundBinary> FindBinary(
       const std::string& abspath,
       const std::string& build_id) = 0;
 };
@@ -53,8 +54,8 @@
  public:
   explicit LocalBinaryIndexer(std::vector<std::string> roots);
 
-  base::Optional<FoundBinary> FindBinary(const std::string& abspath,
-                                         const std::string& build_id) override;
+  std::optional<FoundBinary> FindBinary(const std::string& abspath,
+                                        const std::string& build_id) override;
   ~LocalBinaryIndexer() override;
 
  private:
@@ -65,22 +66,22 @@
  public:
   explicit LocalBinaryFinder(std::vector<std::string> roots);
 
-  base::Optional<FoundBinary> FindBinary(const std::string& abspath,
-                                         const std::string& build_id) override;
+  std::optional<FoundBinary> FindBinary(const std::string& abspath,
+                                        const std::string& build_id) override;
 
   ~LocalBinaryFinder() override;
 
  private:
-  base::Optional<FoundBinary> IsCorrectFile(const std::string& symbol_file,
-                                            const std::string& build_id);
+  std::optional<FoundBinary> IsCorrectFile(const std::string& symbol_file,
+                                           const std::string& build_id);
 
-  base::Optional<FoundBinary> FindBinaryInRoot(const std::string& root_str,
-                                               const std::string& abspath,
-                                               const std::string& build_id);
+  std::optional<FoundBinary> FindBinaryInRoot(const std::string& root_str,
+                                              const std::string& abspath,
+                                              const std::string& build_id);
 
  private:
   std::vector<std::string> roots_;
-  std::map<std::string, base::Optional<FoundBinary>> cache_;
+  std::map<std::string, std::optional<FoundBinary>> cache_;
 };
 
 class LLVMSymbolizerProcess {
diff --git a/src/profiling/symbolizer/local_symbolizer_unittest.cc b/src/profiling/symbolizer/local_symbolizer_unittest.cc
index 919e3ff..04d4855 100644
--- a/src/profiling/symbolizer/local_symbolizer_unittest.cc
+++ b/src/profiling/symbolizer/local_symbolizer_unittest.cc
@@ -163,7 +163,7 @@
 
   LocalBinaryIndexer indexer({tmp.path() + "/dir1", tmp.path() + "/dir2"});
 
-  base::Optional<FoundBinary> bin1 =
+  std::optional<FoundBinary> bin1 =
       indexer.FindBinary("", "AAAAAAAAAAAAAAAAAAAA");
   ASSERT_TRUE(bin1.has_value());
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
@@ -171,7 +171,7 @@
 #else
   EXPECT_EQ(bin1.value().file_name, tmp.path() + "/dir1/elf1");
 #endif
-  base::Optional<FoundBinary> bin2 =
+  std::optional<FoundBinary> bin2 =
       indexer.FindBinary("", "BBBBBBBBBBBBBBBBBBBB");
   ASSERT_TRUE(bin2.has_value());
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
@@ -208,17 +208,17 @@
 
   LocalBinaryIndexer indexer({tmp.AbsolutePath("sym")});
 
-  base::Optional<FoundBinary> bin1 =
+  std::optional<FoundBinary> bin1 =
       indexer.FindBinary("", "AAAAAAAAAAAAAAAAAAAA");
   ASSERT_TRUE(bin1.has_value());
   EXPECT_EQ(bin1.value().file_name, tmp.AbsolutePath("sym/elf1"));
 
-  base::Optional<FoundBinary> bin2 =
+  std::optional<FoundBinary> bin2 =
       indexer.FindBinary("", "BBBBBBBBBBBBBBBBBBBB");
   ASSERT_TRUE(bin2.has_value());
   EXPECT_EQ(bin2.value().file_name, tmp.AbsolutePath("sym/dir1/elf2"));
 
-  base::Optional<FoundBinary> bin3 =
+  std::optional<FoundBinary> bin3 =
       indexer.FindBinary("", "CCCCCCCCCCCCCCCCCCCC");
   ASSERT_TRUE(bin3.has_value());
   EXPECT_EQ(bin3.value().file_name, tmp.AbsolutePath("sym/dir1/elf3"));
@@ -241,7 +241,7 @@
 
   LocalBinaryIndexer indexer({tmp.AbsolutePath("main")});
 
-  base::Optional<FoundBinary> bin1 =
+  std::optional<FoundBinary> bin1 =
       indexer.FindBinary("", "AAAAAAAAAAAAAAAAAAAA");
   ASSERT_TRUE(bin1.has_value());
   EXPECT_EQ(bin1.value().file_name, tmp.AbsolutePath("main/elf1"));
@@ -259,7 +259,7 @@
 
   LocalBinaryFinder finder({tmp.path() + "/root"});
 
-  base::Optional<FoundBinary> bin1 =
+  std::optional<FoundBinary> bin1 =
       finder.FindBinary("/dir/elf1.so", "AAAAAAAAAAAAAAAAAAAA");
   ASSERT_TRUE(bin1.has_value());
   EXPECT_EQ(bin1.value().file_name, tmp.path() + "/root/dir/elf1.so");
@@ -273,7 +273,7 @@
 
   LocalBinaryFinder finder({tmp.path() + "/root"});
 
-  base::Optional<FoundBinary> bin1 =
+  std::optional<FoundBinary> bin1 =
       finder.FindBinary("/dir/base.apk!elf1.so", "AAAAAAAAAAAAAAAAAAAA");
   ASSERT_TRUE(bin1.has_value());
   EXPECT_EQ(bin1.value().file_name, tmp.path() + "/root/dir/elf1.so");
@@ -286,7 +286,7 @@
 
   LocalBinaryFinder finder({tmp.path() + "/root"});
 
-  base::Optional<FoundBinary> bin1 =
+  std::optional<FoundBinary> bin1 =
       finder.FindBinary("/ignored_dir/elf1.so", "AAAAAAAAAAAAAAAAAAAA");
   ASSERT_TRUE(bin1.has_value());
   EXPECT_EQ(bin1.value().file_name, tmp.path() + "/root/elf1.so");
@@ -299,7 +299,7 @@
 
   LocalBinaryFinder finder({tmp.path() + "/root"});
 
-  base::Optional<FoundBinary> bin1 = finder.FindBinary(
+  std::optional<FoundBinary> bin1 = finder.FindBinary(
       "/ignored_dir/base.apk!elf1.so", "AAAAAAAAAAAAAAAAAAAA");
   ASSERT_TRUE(bin1.has_value());
   EXPECT_EQ(bin1.value().file_name, tmp.path() + "/root/elf1.so");
@@ -315,7 +315,7 @@
 
   LocalBinaryFinder finder({tmp.path() + "/root"});
 
-  base::Optional<FoundBinary> bin1 =
+  std::optional<FoundBinary> bin1 =
       finder.FindBinary("/ignored_dir/ignored_name.so", "AAAAAAAAAAAAAAAAAAAA");
   ASSERT_TRUE(bin1.has_value());
   EXPECT_EQ(
diff --git a/src/tools/multithreaded_alloc.cc b/src/tools/multithreaded_alloc.cc
index 4c5e603..a4490d9 100644
--- a/src/tools/multithreaded_alloc.cc
+++ b/src/tools/multithreaded_alloc.cc
@@ -23,13 +23,13 @@
 #include <condition_variable>
 #include <iterator>
 #include <mutex>
+#include <optional>
 #include <thread>
 #include <vector>
 
 #include "perfetto/base/logging.h"
 #include "perfetto/base/time.h"
 #include "perfetto/ext/base/getopt.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/heap_profile.h"
 
@@ -87,21 +87,21 @@
     PERFETTO_FATAL("%s NUMBER_THREADS RUNTIME_MS PENDING_ALLOCS", argv[0]);
   }
 
-  perfetto::base::Optional<uint64_t> opt_no_threads =
+  std::optional<uint64_t> opt_no_threads =
       perfetto::base::CStringToUInt64(argv[1]);
   if (!opt_no_threads) {
     PERFETTO_FATAL("Invalid number of threads: %s", argv[1]);
   }
   uint64_t no_threads = *opt_no_threads;
 
-  perfetto::base::Optional<uint64_t> opt_runtime_ms =
+  std::optional<uint64_t> opt_runtime_ms =
       perfetto::base::CStringToUInt64(argv[2]);
   if (!opt_runtime_ms) {
     PERFETTO_FATAL("Invalid runtime: %s", argv[2]);
   }
   uint64_t runtime_ms = *opt_runtime_ms;
 
-  perfetto::base::Optional<uint64_t> opt_pending_allocs =
+  std::optional<uint64_t> opt_pending_allocs =
       perfetto::base::CStringToUInt64(argv[3]);
   if (!opt_runtime_ms) {
     PERFETTO_FATAL("Invalid number of pending allocs: %s", argv[3]);
diff --git a/src/tools/proto_merger/proto_file.cc b/src/tools/proto_merger/proto_file.cc
index 8b28627..bf1a715 100644
--- a/src/tools/proto_merger/proto_file.cc
+++ b/src/tools/proto_merger/proto_file.cc
@@ -60,8 +60,8 @@
         "repeated",  // LABEL_REPEATED
 };
 
-base::Optional<std::string> MinimizeType(const std::string& a,
-                                         const std::string& b) {
+std::optional<std::string> MinimizeType(const std::string& a,
+                                        const std::string& b) {
   auto a_pieces = base::SplitString(a, ".");
   auto b_pieces = base::SplitString(b, ".");
 
@@ -71,7 +71,7 @@
       return a.substr(skip);
     skip += a_pieces[i].size() + 1;
   }
-  return base::nullopt;
+  return std::nullopt;
 }
 
 std::string SimpleFieldTypeFromDescriptor(
@@ -263,10 +263,10 @@
 }  // namespace
 
 ProtoFile ProtoFileFromDescriptor(
-    std::string premable,
+    std::string preamble,
     const google::protobuf::FileDescriptor& desc) {
   ProtoFile file;
-  file.preamble = std::move(premable);
+  file.preamble = std::move(preamble);
   for (int i = 0; i < desc.enum_type_count(); ++i) {
     file.enums.push_back(EnumFromDescriptor(*desc.enum_type(i)));
   }
diff --git a/src/tools/proto_merger/proto_file.h b/src/tools/proto_merger/proto_file.h
index a7056da..985af47 100644
--- a/src/tools/proto_merger/proto_file.h
+++ b/src/tools/proto_merger/proto_file.h
@@ -27,7 +27,7 @@
 namespace perfetto {
 namespace proto_merger {
 
-/// Simplified representation of the coomponents of a .proto file.
+// Simplified representation of the components of a .proto file.
 struct ProtoFile {
   struct Option {
     std::string key;
@@ -85,7 +85,7 @@
 };
 
 // Creates a ProtoFile struct from a libprotobuf-full descriptor clas.
-ProtoFile ProtoFileFromDescriptor(std::string premable,
+ProtoFile ProtoFileFromDescriptor(std::string preamble,
                                   const google::protobuf::FileDescriptor&);
 
 }  // namespace proto_merger
diff --git a/src/tools/proto_merger/proto_merger.cc b/src/tools/proto_merger/proto_merger.cc
index 65e20d8..ba7a701 100644
--- a/src/tools/proto_merger/proto_merger.cc
+++ b/src/tools/proto_merger/proto_merger.cc
@@ -16,19 +16,20 @@
 
 #include "src/tools/proto_merger/proto_merger.h"
 
+#include <optional>
+
 #include "perfetto/base/logging.h"
 #include "perfetto/base/status.h"
-#include "perfetto/ext/base/optional.h"
 
 namespace perfetto {
 namespace proto_merger {
 namespace {
 
 template <typename Key, typename Value>
-base::Optional<Value> FindInMap(const std::map<Key, Value>& map,
-                                const Key& key) {
+std::optional<Value> FindInMap(const std::map<Key, Value>& map,
+                               const Key& key) {
   auto it = map.find(key);
-  return it == map.end() ? base::nullopt : base::make_optional(it->second);
+  return it == map.end() ? std::nullopt : std::make_optional(it->second);
 }
 
 // Finds the given 'name' in the vector by comparing against
@@ -181,7 +182,7 @@
         input.packageless_type.c_str(), upstream.packageless_type.c_str());
   }
 
-  // If the packageless type mathces, the type should also match.
+  // If the packageless type matches, the type should also match.
   PERFETTO_CHECK(input.type == upstream.type);
 
   // Get the comments, label and the name from the source of truth.
@@ -253,8 +254,8 @@
       continue;
 
     // If the input value doesn't exist, create a fake "input" that we can pass
-    // to the merge functon. This basically has the effect that the upstream
-    // item is taken but *not* recrusively; i.e. any fields which are inside the
+    // to the merge function. This basically has the effect that the upstream
+    // item is taken but *not* recursively; i.e. any fields which are inside the
     // message/oneof are checked against the allowlist individually. If we just
     // took the whole upstream here, we could add fields which were not
     // allowlisted.
diff --git a/src/trace_processor/containers/nullable_vector.h b/src/trace_processor/containers/nullable_vector.h
index 44bb084..0880b12 100644
--- a/src/trace_processor/containers/nullable_vector.h
+++ b/src/trace_processor/containers/nullable_vector.h
@@ -20,9 +20,9 @@
 #include <stdint.h>
 
 #include <deque>
+#include <optional>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "src/trace_processor/containers/row_map.h"
 
 namespace perfetto {
@@ -67,14 +67,14 @@
   // Creates a dense nullable vector
   static NullableVector<T> Dense() { return NullableVector<T>(Mode::kDense); }
 
-  // Returns the optional value at |idx| or base::nullopt if the value is null.
-  base::Optional<T> Get(uint32_t idx) const {
+  // Returns the optional value at |idx| or std::nullopt if the value is null.
+  std::optional<T> Get(uint32_t idx) const {
     bool contains = valid_.IsSet(idx);
     if (mode_ == Mode::kDense) {
-      return contains ? base::make_optional(data_[idx]) : base::nullopt;
+      return contains ? std::make_optional(data_[idx]) : std::nullopt;
     } else {
-      return contains ? base::make_optional(data_[valid_.CountSetBits(idx)])
-                      : base::nullopt;
+      return contains ? std::make_optional(data_[valid_.CountSetBits(idx)])
+                      : std::nullopt;
     }
   }
 
@@ -85,7 +85,7 @@
   }
 
   // Adds the given optional value to the NullableVector.
-  void Append(base::Optional<T> val) {
+  void Append(std::optional<T> val) {
     if (val) {
       Append(*val);
     } else {
diff --git a/src/trace_processor/containers/nullable_vector_unittest.cc b/src/trace_processor/containers/nullable_vector_unittest.cc
index 471f616..c256ec4 100644
--- a/src/trace_processor/containers/nullable_vector_unittest.cc
+++ b/src/trace_processor/containers/nullable_vector_unittest.cc
@@ -26,23 +26,23 @@
   NullableVector<int64_t> sv;
   sv.Append(10);
   sv.Append(20);
-  sv.Append(base::nullopt);
+  sv.Append(std::nullopt);
   sv.Append(40);
 
   ASSERT_FALSE(sv.IsDense());
   ASSERT_EQ(sv.size(), 4u);
-  ASSERT_EQ(sv.Get(0), base::Optional<int64_t>(10));
-  ASSERT_EQ(sv.Get(1), base::Optional<int64_t>(20));
-  ASSERT_EQ(sv.Get(2), base::nullopt);
-  ASSERT_EQ(sv.Get(3), base::Optional<int64_t>(40));
+  ASSERT_EQ(sv.Get(0), std::optional<int64_t>(10));
+  ASSERT_EQ(sv.Get(1), std::optional<int64_t>(20));
+  ASSERT_EQ(sv.Get(2), std::nullopt);
+  ASSERT_EQ(sv.Get(3), std::optional<int64_t>(40));
 }
 
 TEST(NullableVector, Set) {
   NullableVector<int64_t> sv;
   sv.Append(10);
   sv.Append(20);
-  sv.Append(base::nullopt);
-  sv.Append(base::nullopt);
+  sv.Append(std::nullopt);
+  sv.Append(std::nullopt);
   sv.Append(40);
 
   sv.Set(0, 15);
@@ -50,7 +50,7 @@
 
   ASSERT_EQ(*sv.Get(0), 15);
   ASSERT_EQ(*sv.Get(1), 20);
-  ASSERT_EQ(sv.Get(2), base::nullopt);
+  ASSERT_EQ(sv.Get(2), std::nullopt);
   ASSERT_EQ(*sv.Get(3), 30);
   ASSERT_EQ(*sv.Get(4), 40);
 }
@@ -64,27 +64,27 @@
 
   sv.Set(1, 22);
 
-  ASSERT_EQ(sv.Get(0), base::Optional<int64_t>(1));
-  ASSERT_EQ(sv.Get(1), base::Optional<int64_t>(22));
-  ASSERT_EQ(sv.Get(2), base::Optional<int64_t>(3));
-  ASSERT_EQ(sv.Get(3), base::Optional<int64_t>(4));
+  ASSERT_EQ(sv.Get(0), std::optional<int64_t>(1));
+  ASSERT_EQ(sv.Get(1), std::optional<int64_t>(22));
+  ASSERT_EQ(sv.Get(2), std::optional<int64_t>(3));
+  ASSERT_EQ(sv.Get(3), std::optional<int64_t>(4));
 }
 
 TEST(NullableVector, Dense) {
   auto sv = NullableVector<int64_t>::Dense();
 
   sv.Append(0);
-  sv.Append(base::nullopt);
+  sv.Append(std::nullopt);
   sv.Append(2);
   sv.Append(3);
-  sv.Append(base::nullopt);
+  sv.Append(std::nullopt);
 
   ASSERT_TRUE(sv.IsDense());
   ASSERT_EQ(sv.Get(0), 0);
-  ASSERT_EQ(sv.Get(1), base::nullopt);
+  ASSERT_EQ(sv.Get(1), std::nullopt);
   ASSERT_EQ(sv.Get(2), 2);
   ASSERT_EQ(sv.Get(3), 3);
-  ASSERT_EQ(sv.Get(4), base::nullopt);
+  ASSERT_EQ(sv.Get(4), std::nullopt);
 
   sv.Set(1, 1);
   ASSERT_EQ(sv.Get(1), 1);
diff --git a/src/trace_processor/containers/row_map.h b/src/trace_processor/containers/row_map.h
index 06d650a..8ab3915 100644
--- a/src/trace_processor/containers/row_map.h
+++ b/src/trace_processor/containers/row_map.h
@@ -20,10 +20,10 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "src/trace_processor/containers/bit_vector.h"
 #include "src/trace_processor/containers/bit_vector_iterators.h"
 
@@ -305,24 +305,24 @@
   }
 
   // Returns the first row of the given |index| in the RowMap.
-  base::Optional<InputRow> RowOf(OutputIndex index) const {
+  std::optional<InputRow> RowOf(OutputIndex index) const {
     switch (mode_) {
       case Mode::kRange: {
         if (index < start_index_ || index >= end_index_)
-          return base::nullopt;
+          return std::nullopt;
         return index - start_index_;
       }
       case Mode::kBitVector: {
         return index < bit_vector_.size() && bit_vector_.IsSet(index)
-                   ? base::make_optional(bit_vector_.CountSetBits(index))
-                   : base::nullopt;
+                   ? std::make_optional(bit_vector_.CountSetBits(index))
+                   : std::nullopt;
       }
       case Mode::kIndexVector: {
         auto it = std::find(index_vector_.begin(), index_vector_.end(), index);
         return it != index_vector_.end()
-                   ? base::make_optional(static_cast<InputRow>(
+                   ? std::make_optional(static_cast<InputRow>(
                          std::distance(index_vector_.begin(), it)))
-                   : base::nullopt;
+                   : std::nullopt;
       }
     }
     PERFETTO_FATAL("For GCC");
diff --git a/src/trace_processor/containers/row_map_unittest.cc b/src/trace_processor/containers/row_map_unittest.cc
index 5be6c06..6e1ca11 100644
--- a/src/trace_processor/containers/row_map_unittest.cc
+++ b/src/trace_processor/containers/row_map_unittest.cc
@@ -34,11 +34,11 @@
   ASSERT_EQ(rm.Get(1), 31u);
   ASSERT_EQ(rm.Get(16), 46u);
 
-  ASSERT_EQ(rm.RowOf(29), base::nullopt);
+  ASSERT_EQ(rm.RowOf(29), std::nullopt);
   ASSERT_EQ(rm.RowOf(30), 0u);
   ASSERT_EQ(rm.RowOf(37), 7u);
   ASSERT_EQ(rm.RowOf(46), 16u);
-  ASSERT_EQ(rm.RowOf(47), base::nullopt);
+  ASSERT_EQ(rm.RowOf(47), std::nullopt);
 }
 
 TEST(RowMapUnittest, SmokeBitVector) {
@@ -54,8 +54,8 @@
   ASSERT_EQ(rm.RowOf(4u), 1u);
   ASSERT_EQ(rm.RowOf(5u), 2u);
 
-  ASSERT_EQ(rm.RowOf(1u), base::nullopt);
-  ASSERT_EQ(rm.RowOf(100u), base::nullopt);
+  ASSERT_EQ(rm.RowOf(1u), std::nullopt);
+  ASSERT_EQ(rm.RowOf(100u), std::nullopt);
 }
 
 TEST(RowMapUnittest, SmokeIndexVector) {
diff --git a/src/trace_processor/containers/string_pool.h b/src/trace_processor/containers/string_pool.h
index ddc57cd..73e0e2b 100644
--- a/src/trace_processor/containers/string_pool.h
+++ b/src/trace_processor/containers/string_pool.h
@@ -21,11 +21,11 @@
 #include <stdint.h>
 
 #include <limits>
+#include <optional>
 #include <vector>
 
 #include "perfetto/ext/base/flat_hash_map.h"
 #include "perfetto/ext/base/hash.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/paged_memory.h"
 #include "perfetto/protozero/proto_utils.h"
 #include "src/trace_processor/containers/null_term_string_view.h"
@@ -132,7 +132,7 @@
     return *id;
   }
 
-  base::Optional<Id> GetId(base::StringView str) const {
+  std::optional<Id> GetId(base::StringView str) const {
     if (str.data() == nullptr)
       return Id::Null();
 
@@ -142,7 +142,7 @@
       PERFETTO_DCHECK(Get(*id) == str);
       return *id;
     }
-    return base::nullopt;
+    return std::nullopt;
   }
 
   NullTermStringView Get(Id id) const {
diff --git a/src/trace_processor/db/column.cc b/src/trace_processor/db/column.cc
index 4fec8fc..01c6b5e 100644
--- a/src/trace_processor/db/column.cc
+++ b/src/trace_processor/db/column.cc
@@ -56,16 +56,16 @@
     bool is_storage_dense;
     switch (type_) {
       case ColumnType::kInt32:
-        is_storage_dense = storage<base::Optional<int32_t>>().IsDense();
+        is_storage_dense = storage<std::optional<int32_t>>().IsDense();
         break;
       case ColumnType::kUint32:
-        is_storage_dense = storage<base::Optional<uint32_t>>().IsDense();
+        is_storage_dense = storage<std::optional<uint32_t>>().IsDense();
         break;
       case ColumnType::kInt64:
-        is_storage_dense = storage<base::Optional<int64_t>>().IsDense();
+        is_storage_dense = storage<std::optional<int64_t>>().IsDense();
         break;
       case ColumnType::kDouble:
-        is_storage_dense = storage<base::Optional<double>>().IsDense();
+        is_storage_dense = storage<std::optional<double>>().IsDense();
         break;
       case ColumnType::kString:
         PERFETTO_FATAL("String column should not be nullable");
@@ -159,7 +159,7 @@
     PERFETTO_DCHECK(value.is_null());
     if (is_nullable) {
       overlay().FilterInto(rm, [this](uint32_t row) {
-        return !storage<base::Optional<T>>().Get(row).has_value();
+        return !storage<std::optional<T>>().Get(row).has_value();
       });
     } else {
       rm->Clear();
@@ -169,7 +169,7 @@
     PERFETTO_DCHECK(value.is_null());
     if (is_nullable) {
       overlay().FilterInto(rm, [this](uint32_t row) {
-        return storage<base::Optional<T>>().Get(row).has_value();
+        return storage<std::optional<T>>().Get(row).has_value();
       });
     }
     return;
@@ -227,7 +227,7 @@
     case FilterOp::kLt:
       overlay().FilterInto(rm, [this, &cmp](uint32_t idx) {
         if (is_nullable) {
-          auto opt_value = storage<base::Optional<T>>().Get(idx);
+          auto opt_value = storage<std::optional<T>>().Get(idx);
           return opt_value && cmp(*opt_value) < 0;
         }
         return cmp(storage<T>().Get(idx)) < 0;
@@ -236,7 +236,7 @@
     case FilterOp::kEq:
       overlay().FilterInto(rm, [this, &cmp](uint32_t idx) {
         if (is_nullable) {
-          auto opt_value = storage<base::Optional<T>>().Get(idx);
+          auto opt_value = storage<std::optional<T>>().Get(idx);
           return opt_value && cmp(*opt_value) == 0;
         }
         return cmp(storage<T>().Get(idx)) == 0;
@@ -245,7 +245,7 @@
     case FilterOp::kGt:
       overlay().FilterInto(rm, [this, &cmp](uint32_t idx) {
         if (is_nullable) {
-          auto opt_value = storage<base::Optional<T>>().Get(idx);
+          auto opt_value = storage<std::optional<T>>().Get(idx);
           return opt_value && cmp(*opt_value) > 0;
         }
         return cmp(storage<T>().Get(idx)) > 0;
@@ -254,7 +254,7 @@
     case FilterOp::kNe:
       overlay().FilterInto(rm, [this, &cmp](uint32_t idx) {
         if (is_nullable) {
-          auto opt_value = storage<base::Optional<T>>().Get(idx);
+          auto opt_value = storage<std::optional<T>>().Get(idx);
           return opt_value && cmp(*opt_value) != 0;
         }
         return cmp(storage<T>().Get(idx)) != 0;
@@ -263,7 +263,7 @@
     case FilterOp::kLe:
       overlay().FilterInto(rm, [this, &cmp](uint32_t idx) {
         if (is_nullable) {
-          auto opt_value = storage<base::Optional<T>>().Get(idx);
+          auto opt_value = storage<std::optional<T>>().Get(idx);
           return opt_value && cmp(*opt_value) <= 0;
         }
         return cmp(storage<T>().Get(idx)) <= 0;
@@ -272,7 +272,7 @@
     case FilterOp::kGe:
       overlay().FilterInto(rm, [this, &cmp](uint32_t idx) {
         if (is_nullable) {
-          auto opt_value = storage<base::Optional<T>>().Get(idx);
+          auto opt_value = storage<std::optional<T>>().Get(idx);
           return opt_value && cmp(*opt_value) >= 0;
         }
         return cmp(storage<T>().Get(idx)) >= 0;
@@ -486,8 +486,8 @@
 
   overlay().StableSort(out, [this](uint32_t a_idx, uint32_t b_idx) {
     if (is_nullable) {
-      auto a_val = storage<base::Optional<T>>().Get(a_idx);
-      auto b_val = storage<base::Optional<T>>().Get(b_idx);
+      auto a_val = storage<std::optional<T>>().Get(a_idx);
+      auto b_val = storage<std::optional<T>>().Get(b_idx);
 
       int res = compare::NullableNumeric(a_val, b_val);
       return desc ? res > 0 : res < 0;
diff --git a/src/trace_processor/db/column.h b/src/trace_processor/db/column.h
index 1d1b347..04425b9 100644
--- a/src/trace_processor/db/column.h
+++ b/src/trace_processor/db/column.h
@@ -18,9 +18,9 @@
 #define SRC_TRACE_PROCESSOR_DB_COLUMN_H_
 
 #include <stdint.h>
+#include <optional>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/trace_processor/basic_types.h"
 #include "src/trace_processor/containers/row_map.h"
 #include "src/trace_processor/containers/string_pool.h"
@@ -100,7 +100,7 @@
   static constexpr ColumnType ToColumnType() { return ColumnType::kString; }
 };
 template <typename T>
-struct ColumnTypeHelper<base::Optional<T>> : public ColumnTypeHelper<T> {};
+struct ColumnTypeHelper<std::optional<T>> : public ColumnTypeHelper<T> {};
 
 class Table;
 
@@ -262,7 +262,7 @@
   SqlValue Get(uint32_t row) const { return GetAtIdx(overlay().Get(row)); }
 
   // Returns the row containing the given value in the Column.
-  base::Optional<uint32_t> IndexOf(SqlValue value) const {
+  std::optional<uint32_t> IndexOf(SqlValue value) const {
     switch (type_) {
       // TODO(lalitm): investigate whether we could make this more efficient
       // by first checking the type of the column and comparing explicitly
@@ -276,11 +276,11 @@
           if (compare::SqlValue(Get(i), value) == 0)
             return i;
         }
-        return base::nullopt;
+        return std::nullopt;
       }
       case ColumnType::kId: {
         if (value.type != SqlValue::Type::kLong)
-          return base::nullopt;
+          return std::nullopt;
         return overlay().RowOf(static_cast<uint32_t>(value.long_value));
       }
       case ColumnType::kDummy:
@@ -328,11 +328,11 @@
     FilterIntoSlow(op, value, rm);
   }
 
-  // Returns the minimum value in this column. Returns nullopt if this column
-  // is empty.
-  base::Optional<SqlValue> Min() const {
+  // Returns the minimum value in this column. Returns std::nullopt if this
+  // column is empty.
+  std::optional<SqlValue> Min() const {
     if (overlay().empty())
-      return base::nullopt;
+      return std::nullopt;
 
     if (IsSorted())
       return Get(0);
@@ -342,11 +342,11 @@
     return *std::min_element(b, e, &compare::SqlValueComparator);
   }
 
-  // Returns the minimum value in this column. Returns nullopt if this column
-  // is empty.
-  base::Optional<SqlValue> Max() const {
+  // Returns the minimum value in this column. Returns std::nullopt if this
+  // column is empty.
+  std::optional<SqlValue> Max() const {
     if (overlay().empty())
-      return base::nullopt;
+      return std::nullopt;
 
     if (IsSorted())
       return Get(overlay().size() - 1);
@@ -525,7 +525,7 @@
   template <typename T>
   SqlValue GetAtIdxTyped(uint32_t idx) const {
     if (IsNullable()) {
-      auto opt_value = storage<base::Optional<T>>().Get(idx);
+      auto opt_value = storage<std::optional<T>>().Get(idx);
       return opt_value ? ToSqlValue(*opt_value) : SqlValue();
     }
     return ToSqlValue(storage<T>().Get(idx));
diff --git a/src/trace_processor/db/column_storage.h b/src/trace_processor/db/column_storage.h
index 70c8385..6cf2f30 100644
--- a/src/trace_processor/db/column_storage.h
+++ b/src/trace_processor/db/column_storage.h
@@ -66,7 +66,7 @@
 
 // Class used for implementing storage for nullable columns.
 template <typename T>
-class ColumnStorage<base::Optional<T>> : public ColumnStorageBase {
+class ColumnStorage<std::optional<T>> : public ColumnStorageBase {
  public:
   ColumnStorage() = default;
 
@@ -76,19 +76,19 @@
   ColumnStorage(ColumnStorage&&) = default;
   ColumnStorage& operator=(ColumnStorage&&) noexcept = default;
 
-  base::Optional<T> Get(uint32_t idx) const { return nv_.Get(idx); }
+  std::optional<T> Get(uint32_t idx) const { return nv_.Get(idx); }
   void Append(T val) { nv_.Append(val); }
-  void Append(base::Optional<T> val) { nv_.Append(std::move(val)); }
+  void Append(std::optional<T> val) { nv_.Append(std::move(val)); }
   void Set(uint32_t idx, T val) { nv_.Set(idx, val); }
   uint32_t size() const { return nv_.size(); }
   bool IsDense() const { return nv_.IsDense(); }
   void ShrinkToFit() { nv_.ShrinkToFit(); }
 
   template <bool IsDense>
-  static ColumnStorage<base::Optional<T>> Create() {
+  static ColumnStorage<std::optional<T>> Create() {
     return IsDense
-               ? ColumnStorage<base::Optional<T>>(NullableVector<T>::Dense())
-               : ColumnStorage<base::Optional<T>>(NullableVector<T>::Sparse());
+               ? ColumnStorage<std::optional<T>>(NullableVector<T>::Dense())
+               : ColumnStorage<std::optional<T>>(NullableVector<T>::Sparse());
   }
 
  private:
diff --git a/src/trace_processor/db/column_storage_overlay.h b/src/trace_processor/db/column_storage_overlay.h
index dad6c82..108dccd 100644
--- a/src/trace_processor/db/column_storage_overlay.h
+++ b/src/trace_processor/db/column_storage_overlay.h
@@ -20,10 +20,10 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "src/trace_processor/containers/bit_vector.h"
 #include "src/trace_processor/containers/bit_vector_iterators.h"
 #include "src/trace_processor/containers/row_map.h"
@@ -113,7 +113,7 @@
   OutputIndex Get(uint32_t row) const { return row_map_.Get(row); }
 
   // Returns the first row of the given |index| in the ColumnStorageOverlay.
-  base::Optional<InputRow> RowOf(OutputIndex index) const {
+  std::optional<InputRow> RowOf(OutputIndex index) const {
     return row_map_.RowOf(index);
   }
 
diff --git a/src/trace_processor/db/compare.h b/src/trace_processor/db/compare.h
index 3aeefbb..e118294 100644
--- a/src/trace_processor/db/compare.h
+++ b/src/trace_processor/db/compare.h
@@ -20,8 +20,8 @@
 #include <stdint.h>
 
 #include <algorithm>
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/trace_processor/basic_types.h"
 
@@ -112,7 +112,7 @@
 // This method was defined from observing the behaviour of SQLite when sorting
 // on columns containing nulls.
 template <typename T>
-inline int NullableNumeric(base::Optional<T> a, base::Optional<T> b) {
+inline int NullableNumeric(std::optional<T> a, std::optional<T> b) {
   if (!a)
     return b ? -1 : 0;
 
diff --git a/src/trace_processor/db/table.h b/src/trace_processor/db/table.h
index 21962bf..c1cf66c 100644
--- a/src/trace_processor/db/table.h
+++ b/src/trace_processor/db/table.h
@@ -21,10 +21,10 @@
 
 #include <limits>
 #include <numeric>
+#include <optional>
 #include <vector>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "src/trace_processor/containers/string_pool.h"
 #include "src/trace_processor/db/column.h"
 #include "src/trace_processor/db/column_storage_overlay.h"
@@ -148,19 +148,19 @@
   // Returns the column at index |idx| in the Table.
   const Column& GetColumn(uint32_t idx) const { return columns_[idx]; }
 
-  // Returns the column index with the given name or base::nullopt otherwise.
-  base::Optional<uint32_t> GetColumnIndexByName(const char* name) const {
+  // Returns the column index with the given name or std::nullopt otherwise.
+  std::optional<uint32_t> GetColumnIndexByName(const char* name) const {
     auto it = std::find_if(
         columns_.begin(), columns_.end(),
         [name](const Column& col) { return strcmp(col.name(), name) == 0; });
     if (it == columns_.end())
-      return base::nullopt;
+      return std::nullopt;
     return static_cast<uint32_t>(std::distance(columns_.begin(), it));
   }
 
   // Returns the column with the given name or nullptr otherwise.
   const Column* GetColumnByName(const char* name) const {
-    base::Optional<uint32_t> opt_idx = GetColumnIndexByName(name);
+    std::optional<uint32_t> opt_idx = GetColumnIndexByName(name);
     if (!opt_idx)
       return nullptr;
     return &columns_[*opt_idx];
diff --git a/src/trace_processor/db/table_unittest.cc b/src/trace_processor/db/table_unittest.cc
index e915ce2..6f370ca 100644
--- a/src/trace_processor/db/table_unittest.cc
+++ b/src/trace_processor/db/table_unittest.cc
@@ -15,7 +15,6 @@
  */
 
 #include "src/trace_processor/db/table.h"
-#include "perfetto/ext/base/optional.h"
 #include "src/trace_processor/db/typed_column.h"
 #include "src/trace_processor/tables/macros.h"
 
diff --git a/src/trace_processor/db/typed_column.h b/src/trace_processor/db/typed_column.h
index dae1b86..7bf0fad 100644
--- a/src/trace_processor/db/typed_column.h
+++ b/src/trace_processor/db/typed_column.h
@@ -91,7 +91,7 @@
   void Append(T v) { mutable_storage()->Append(Serializer::Serialize(v)); }
 
   // Returns the row containing the given value in the Column.
-  base::Optional<uint32_t> IndexOf(sql_value_type v) const {
+  std::optional<uint32_t> IndexOf(sql_value_type v) const {
     return Column::IndexOf(ToSqlValue(v));
   }
 
@@ -190,7 +190,7 @@
 
   Id operator[](uint32_t row) const { return Id(overlay().Get(row)); }
 
-  base::Optional<uint32_t> IndexOf(Id id) const {
+  std::optional<uint32_t> IndexOf(Id id) const {
     return overlay().RowOf(id.value);
   }
 
diff --git a/src/trace_processor/db/typed_column_internal.h b/src/trace_processor/db/typed_column_internal.h
index 5ffc811..634feac 100644
--- a/src/trace_processor/db/typed_column_internal.h
+++ b/src/trace_processor/db/typed_column_internal.h
@@ -34,10 +34,10 @@
   static serialized_type Serialize(T value) { return value; }
   static T Deserialize(serialized_type value) { return value; }
 
-  static base::Optional<serialized_type> Serialize(base::Optional<T> value) {
+  static std::optional<serialized_type> Serialize(std::optional<T> value) {
     return value;
   }
-  static base::Optional<T> Deserialize(base::Optional<serialized_type> value) {
+  static std::optional<T> Deserialize(std::optional<serialized_type> value) {
     return value;
   }
 };
@@ -53,11 +53,11 @@
   static serialized_type Serialize(T value) { return value.value; }
   static T Deserialize(serialized_type value) { return T{value}; }
 
-  static base::Optional<serialized_type> Serialize(base::Optional<T> value) {
-    return value ? base::make_optional(Serialize(*value)) : base::nullopt;
+  static std::optional<serialized_type> Serialize(std::optional<T> value) {
+    return value ? std::make_optional(Serialize(*value)) : std::nullopt;
   }
-  static base::Optional<T> Deserialize(base::Optional<serialized_type> value) {
-    return value ? base::make_optional(Deserialize(*value)) : base::nullopt;
+  static std::optional<T> Deserialize(std::optional<serialized_type> value) {
+    return value ? std::make_optional(Deserialize(*value)) : std::nullopt;
   }
 };
 
@@ -69,10 +69,10 @@
   static serialized_type Serialize(StringPool::Id value) { return value; }
   static StringPool::Id Deserialize(serialized_type value) { return value; }
 
-  static serialized_type Serialize(base::Optional<StringPool::Id> value) {
+  static serialized_type Serialize(std::optional<StringPool::Id> value) {
     // Since StringPool::Id == 0 is always treated as null, rewrite
-    // base::nullopt -> 0 to remove an extra check at filter time for
-    // base::nullopt. Instead, that code can assume that the ColumnStorage
+    // std::nullopt -> 0 to remove an extra check at filter time for
+    // std::nullopt. Instead, that code can assume that the ColumnStorage
     // layer always returns a valid id and can handle the nullability at the
     // stringpool level.
     // TODO(lalitm): remove this special casing if we migrate all tables over
@@ -80,8 +80,8 @@
     // in the stringpool.
     return value ? Serialize(*value) : StringPool::Id::Null();
   }
-  static base::Optional<serialized_type> Deserialize(
-      base::Optional<StringPool::Id> value) {
+  static std::optional<serialized_type> Deserialize(
+      std::optional<StringPool::Id> value) {
     return value;
   }
 };
@@ -113,12 +113,12 @@
 
 // Specialization for Optional types.
 template <typename T>
-struct TypeHandler<base::Optional<T>> {
+struct TypeHandler<std::optional<T>> {
   using non_optional_type = T;
   using sql_value_type =
       typename Serializer<non_optional_type>::serialized_type;
   using stored_type =
-      base::Optional<typename Serializer<non_optional_type>::serialized_type>;
+      std::optional<typename Serializer<non_optional_type>::serialized_type>;
 
   static constexpr bool is_optional = true;
   static constexpr bool is_string = false;
@@ -127,7 +127,7 @@
     return nv.Get(idx);
   }
 
-  static bool Equals(base::Optional<T> a, base::Optional<T> b) {
+  static bool Equals(std::optional<T> a, std::optional<T> b) {
     // We need to use equal_to here as it could be T == double and because we
     // enable all compile time warnings, we will get complaints if we just use
     // a == b. This is the same reason why we can't also just use equal_to using
@@ -138,7 +138,7 @@
   }
 };
 
-// Specialization for Optional<StringId> types.
+// Specialization for std::optional<StringId> types.
 template <>
 struct TypeHandler<StringPool::Id> {
   using non_optional_type = StringPool::Id;
@@ -156,30 +156,29 @@
   static bool Equals(StringPool::Id a, StringPool::Id b) { return a == b; }
 };
 
-// Specialization for Optional<StringId> types.
+// Specialization for std::optional<StringId> types.
 template <>
-struct TypeHandler<base::Optional<StringPool::Id>> {
-  // get_type removes the base::Optional since we convert base::nullopt ->
+struct TypeHandler<std::optional<StringPool::Id>> {
+  // get_type removes the base::Optional since we convert std::nullopt ->
   // StringPool::Id::Null (see Serializer<StringPool> above).
   using non_optional_type = StringPool::Id;
   using sql_value_type = NullTermStringView;
   using stored_type = StringPool::Id;
 
   // is_optional is false again because we always unwrap
-  // base::Optional<StringPool::Id> into StringPool::Id.
+  // std::optional<StringPool::Id> into StringPool::Id.
   static constexpr bool is_optional = false;
   static constexpr bool is_string = true;
 
-  static base::Optional<StringPool::Id> Get(
-      const ColumnStorage<stored_type>& nv,
-      uint32_t idx) {
+  static std::optional<StringPool::Id> Get(const ColumnStorage<stored_type>& nv,
+                                           uint32_t idx) {
     StringPool::Id id = nv.Get(idx);
-    return id.is_null() ? base::nullopt : base::make_optional(id);
+    return id.is_null() ? std::nullopt : std::make_optional(id);
   }
 
-  static bool Equals(base::Optional<StringPool::Id> a,
-                     base::Optional<StringPool::Id> b) {
-    // To match our handling of treating base::nullopt ==
+  static bool Equals(std::optional<StringPool::Id> a,
+                     std::optional<StringPool::Id> b) {
+    // To match our handling of treating std::nullopt ==
     // StringPool::Id::Null(), ensure that they both compare equal to each
     // other.
     return a == b || (!a && b->is_null()) || (!b && a->is_null());
diff --git a/src/trace_processor/db/view.cc b/src/trace_processor/db/view.cc
index 1855329..5b462c7 100644
--- a/src/trace_processor/db/view.cc
+++ b/src/trace_processor/db/view.cc
@@ -55,10 +55,10 @@
                           std::initializer_list<JoinTable> joins,
                           std::initializer_list<OutputColumn> cols,
                           View* view) {
-  // Insert the node for the root table; the column indices being nullopt
+  // Insert the node for the root table; the column indices being std::nullopt
   // indicates this is the root.
   std::unique_ptr<TableNode> root_node(
-      new TableNode{root_table, base::nullopt, base::nullopt, JoinFlag::kNoFlag,
+      new TableNode{root_table, std::nullopt, std::nullopt, JoinFlag::kNoFlag,
                     TableNode::Children{}});
   base::FlatHashMap<base::StringView, TableNode*> node_map;
   node_map.Insert(root_table_name, root_node.get());
@@ -78,7 +78,7 @@
     TableNode* prev_node = *prev_node_it;
 
     // Verify that the previous table's column exists.
-    base::Optional<uint32_t> opt_prev_col_idx =
+    std::optional<uint32_t> opt_prev_col_idx =
         prev_node->table->GetColumnIndexByName(join.prev_col);
     if (!opt_prev_col_idx) {
       return base::ErrStatus(
@@ -87,7 +87,7 @@
     }
 
     // Verify that the current table's column exists.
-    base::Optional<uint32_t> opt_col_idx =
+    std::optional<uint32_t> opt_col_idx =
         join.table->GetColumnIndexByName(join.col);
     if (!opt_col_idx) {
       return base::ErrStatus(
@@ -304,7 +304,7 @@
     right_rm_iv.reserve(left_rm.size());
     left_col.overlay().FilterInto(&left_rm, [&](uint32_t idx) {
       // Check if the right table has the value from the left table.
-      base::Optional<uint32_t> opt_idx =
+      std::optional<uint32_t> opt_idx =
           right_col.IndexOf(left_col.GetAtIdx(idx));
 
       // If it doesn't, return false indicating that this row should be
diff --git a/src/trace_processor/db/view.h b/src/trace_processor/db/view.h
index 66c8564..8f830f8 100644
--- a/src/trace_processor/db/view.h
+++ b/src/trace_processor/db/view.h
@@ -22,13 +22,13 @@
 #include <iterator>
 #include <memory>
 #include <numeric>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "perfetto/base/logging.h"
 #include "perfetto/base/status.h"
 #include "perfetto/ext/base/flat_hash_map.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/small_vector.h"
 #include "perfetto/trace_processor/iterator.h"
 #include "src/trace_processor/containers/bit_vector.h"
@@ -208,11 +208,11 @@
     // The index of the id column in |table|.
     // In practice, this will always be zero (as id columns are implicitly the
     // first column) but having this allows flexibility for the future.
-    base::Optional<uint32_t> join_col_idx;
+    std::optional<uint32_t> join_col_idx;
 
     // The index of the column in the parent table which is selecting the rows
     // in |table|.
-    base::Optional<uint32_t> parent_join_col_idx;
+    std::optional<uint32_t> parent_join_col_idx;
 
     // Set of bitwise-ORed flags modifying how the join should be perfomed. See
     // |JoinFlag| struct for potential flags.
diff --git a/src/trace_processor/export_json.cc b/src/trace_processor/export_json.cc
index 7709681..dcac72d 100644
--- a/src/trace_processor/export_json.cc
+++ b/src/trace_processor/export_json.cc
@@ -86,8 +86,8 @@
 const char kStrippedArgument[] = "__stripped__";
 
 const char* GetNonNullString(const TraceStorage* storage,
-                             base::Optional<StringId> id) {
-  return id == base::nullopt || *id == kNullStringId
+                             std::optional<StringId> id) {
+  return id == std::nullopt || *id == kNullStringId
              ? ""
              : storage->GetString(*id).c_str();
 }
@@ -608,7 +608,7 @@
                             args_sets_[set_id].toStyledString().c_str());
               return;
             }
-            base::Optional<uint32_t> index = base::StringToUInt32(s);
+            std::optional<uint32_t> index = base::StringToUInt32(s);
             if (PERFETTO_UNLIKELY(!index)) {
               PERFETTO_ELOG("Expected to be able to extract index from %s",
                             key_part.c_str());
@@ -683,7 +683,7 @@
     const auto& thread_table = storage_->thread_table();
     for (UniqueTid utid = 0; utid < thread_table.row_count(); utid++) {
       uint32_t exported_pid = 0;
-      base::Optional<UniquePid> upid = thread_table.upid()[utid];
+      std::optional<UniquePid> upid = thread_table.upid()[utid];
       if (upid) {
         auto exported_pid_it = upids_to_exported_pids_.find(*upid);
         PERFETTO_DCHECK(exported_pid_it != upids_to_exported_pids_.end());
@@ -742,7 +742,7 @@
 
     const auto& process_table = storage_->process_table();
     for (UniquePid upid = 0; upid < process_table.row_count(); ++upid) {
-      base::Optional<int64_t> start_timestamp_ns =
+      std::optional<int64_t> start_timestamp_ns =
           process_table.start_ts()[upid];
       if (!start_timestamp_ns.has_value())
         continue;
@@ -795,7 +795,7 @@
       event["pid"] = 0;
       event["tid"] = 0;
 
-      base::Optional<UniqueTid> legacy_utid;
+      std::optional<UniqueTid> legacy_utid;
       std::string legacy_phase;
 
       event["args"] = args_builder_.GetArgs(it.arg_set_id());  // Makes a copy.
@@ -837,10 +837,10 @@
       const auto& virtual_track_slices = storage_->virtual_track_slices();
 
       int64_t duration_ns = it.dur();
-      base::Optional<int64_t> thread_ts_ns;
-      base::Optional<int64_t> thread_duration_ns;
-      base::Optional<int64_t> thread_instruction_count;
-      base::Optional<int64_t> thread_instruction_delta;
+      std::optional<int64_t> thread_ts_ns;
+      std::optional<int64_t> thread_duration_ns;
+      std::optional<int64_t> thread_instruction_count;
+      std::optional<int64_t> thread_instruction_delta;
 
       if (it.thread_dur()) {
         thread_ts_ns = it.thread_ts();
@@ -849,7 +849,7 @@
         thread_instruction_delta = it.thread_instruction_delta();
       } else {
         SliceId id = it.id();
-        base::Optional<uint32_t> vtrack_slice_row =
+        std::optional<uint32_t> vtrack_slice_row =
             virtual_track_slices.FindRowForSliceId(id);
         if (vtrack_slice_row) {
           thread_ts_ns =
@@ -1054,25 +1054,25 @@
     return util::OkStatus();
   }
 
-  base::Optional<Json::Value> CreateFlowEventV1(uint32_t flow_id,
-                                                SliceId slice_id,
-                                                std::string name,
-                                                std::string cat,
-                                                Json::Value args,
-                                                bool flow_begin) {
+  std::optional<Json::Value> CreateFlowEventV1(uint32_t flow_id,
+                                               SliceId slice_id,
+                                               std::string name,
+                                               std::string cat,
+                                               Json::Value args,
+                                               bool flow_begin) {
     const auto& slices = storage_->slice_table();
     const auto& thread_tracks = storage_->thread_track_table();
 
     auto opt_slice_idx = slices.id().IndexOf(slice_id);
     if (!opt_slice_idx)
-      return base::nullopt;
+      return std::nullopt;
     uint32_t slice_idx = opt_slice_idx.value();
 
     TrackId track_id = storage_->slice_table().track_id()[slice_idx];
     auto opt_thread_track_idx = thread_tracks.id().IndexOf(track_id);
     // catapult only supports flow events attached to thread-track slices
     if (!opt_thread_track_idx)
-      return base::nullopt;
+      return std::nullopt;
 
     UniqueTid utid = thread_tracks.utid()[opt_thread_track_idx.value()];
     auto pid_and_tid = UtidToPidAndTid(utid);
@@ -1112,9 +1112,9 @@
       } else {
         auto opt_slice_out_idx = slice_table.id().IndexOf(slice_out);
         PERFETTO_DCHECK(opt_slice_out_idx.has_value());
-        base::Optional<StringId> cat_id =
+        std::optional<StringId> cat_id =
             slice_table.category()[opt_slice_out_idx.value()];
-        base::Optional<StringId> name_id =
+        std::optional<StringId> name_id =
             slice_table.name()[opt_slice_out_idx.value()];
         cat = GetNonNullString(storage_, cat_id);
         name = GetNonNullString(storage_, name_id);
@@ -1211,13 +1211,13 @@
   }
 
   util::Status ExportRawEvents() {
-    base::Optional<StringId> raw_legacy_event_key_id =
+    std::optional<StringId> raw_legacy_event_key_id =
         storage_->string_pool().GetId("track_event.legacy_event");
-    base::Optional<StringId> raw_legacy_system_trace_event_id =
+    std::optional<StringId> raw_legacy_system_trace_event_id =
         storage_->string_pool().GetId("chrome_event.legacy_system_trace");
-    base::Optional<StringId> raw_legacy_user_trace_event_id =
+    std::optional<StringId> raw_legacy_user_trace_event_id =
         storage_->string_pool().GetId("chrome_event.legacy_user_trace");
-    base::Optional<StringId> raw_chrome_metadata_event_id =
+    std::optional<StringId> raw_chrome_metadata_event_id =
         storage_->string_pool().GetId("chrome_event.metadata");
 
     const auto& events = storage_->raw_table();
@@ -1393,7 +1393,7 @@
       const auto& mappings = storage_->stack_profile_mapping_table();
 
       std::vector<std::string> callstack;
-      base::Optional<CallsiteId> opt_callsite_id = samples.callsite_id()[i];
+      std::optional<CallsiteId> opt_callsite_id = samples.callsite_id()[i];
 
       while (opt_callsite_id) {
         CallsiteId callsite_id = *opt_callsite_id;
@@ -1445,7 +1445,7 @@
       // For now, only do this when the trace has already been symbolized i.e.
       // are not directly output by Chrome, to avoid interfering with other
       // processing pipelines.
-      base::Optional<CallsiteId> opt_current_callsite_id =
+      std::optional<CallsiteId> opt_current_callsite_id =
           samples.callsite_id()[i];
 
       if (opt_current_callsite_id && storage_->symbol_table().row_count() > 0) {
@@ -1556,9 +1556,9 @@
 
   util::Status ExportMemorySnapshots() {
     const auto& memory_snapshots = storage_->memory_snapshot_table();
-    base::Optional<StringId> private_footprint_id =
+    std::optional<StringId> private_footprint_id =
         storage_->string_pool().GetId("chrome.private_footprint_kb");
-    base::Optional<StringId> peak_resident_set_id =
+    std::optional<StringId> peak_resident_set_id =
         storage_->string_pool().GetId("chrome.peak_resident_set_kb");
 
     for (uint32_t memory_index = 0; memory_index < memory_snapshots.row_count();
diff --git a/src/trace_processor/export_json_unittest.cc b/src/trace_processor/export_json_unittest.cc
index 07722a0..61d0976 100644
--- a/src/trace_processor/export_json_unittest.cc
+++ b/src/trace_processor/export_json_unittest.cc
@@ -28,9 +28,9 @@
 #include "perfetto/ext/base/temp_file.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
 #include "src/trace_processor/importers/common/event_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/importers/common/process_tracker.h"
 #include "src/trace_processor/importers/common/track_tracker.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
 #include "src/trace_processor/importers/proto/track_event_tracker.h"
 #include "src/trace_processor/storage/trace_storage.h"
 #include "src/trace_processor/types/trace_processor_context.h"
@@ -830,16 +830,16 @@
 
 TEST_F(ExportJsonTest, DuplicatePidAndTid) {
   UniqueTid upid1 = context_.process_tracker->StartNewProcess(
-      base::nullopt, base::nullopt, 1, kNullStringId,
+      std::nullopt, std::nullopt, 1, kNullStringId,
       ThreadNamePriority::kTrackDescriptor);
   UniqueTid utid1a = context_.process_tracker->UpdateThread(1, 1);
   UniqueTid utid1b = context_.process_tracker->UpdateThread(2, 1);
-  UniqueTid utid1c = context_.process_tracker->StartNewThread(base::nullopt, 2);
+  UniqueTid utid1c = context_.process_tracker->StartNewThread(std::nullopt, 2);
   // Associate the new thread with its process.
   ASSERT_EQ(utid1c, context_.process_tracker->UpdateThread(2, 1));
 
   UniqueTid upid2 = context_.process_tracker->StartNewProcess(
-      base::nullopt, base::nullopt, 1, kNullStringId,
+      std::nullopt, std::nullopt, 1, kNullStringId,
       ThreadNamePriority::kTrackDescriptor);
   UniqueTid utid2a = context_.process_tracker->UpdateThread(1, 1);
   UniqueTid utid2b = context_.process_tracker->UpdateThread(2, 1);
@@ -1542,7 +1542,7 @@
        storage->InternString("bar_file"), 77});
   frames->mutable_symbol_set_id()->Set(frame_2.row, symbol_set_id);
 
-  auto frame_callsite_1 = callsites->Insert({0, base::nullopt, frame_1.id});
+  auto frame_callsite_1 = callsites->Insert({0, std::nullopt, frame_1.id});
 
   auto frame_callsite_2 =
       callsites->Insert({1, frame_callsite_1.id, frame_2.id});
diff --git a/src/trace_processor/importers/android_bugreport/android_bugreport_parser.cc b/src/trace_processor/importers/android_bugreport/android_bugreport_parser.cc
index 5e80c24..87aa0f5 100644
--- a/src/trace_processor/importers/android_bugreport/android_bugreport_parser.cc
+++ b/src/trace_processor/importers/android_bugreport/android_bugreport_parser.cc
@@ -17,9 +17,9 @@
 #include "src/trace_processor/importers/android_bugreport/android_bugreport_parser.h"
 
 #include <algorithm>
+#include <optional>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/trace_processor/trace_blob.h"
 #include "perfetto/trace_processor/trace_blob_view.h"
@@ -247,7 +247,7 @@
   // Typical name: "bugreport-product-TP1A.220623.001-2022-06-24-16-24-37.txt".
   auto year_str = br_file->name().substr(
       br_file->name().size() - strlen("2022-12-31-23-59-00.txt"), 4);
-  base::Optional<int32_t> year = base::StringToInt32(year_str);
+  std::optional<int32_t> year = base::StringToInt32(year_str);
   if (!year.has_value()) {
     PERFETTO_ELOG("Could not parse the year from %s", br_file->name().c_str());
     return false;
diff --git a/src/trace_processor/importers/android_bugreport/android_log_parser.cc b/src/trace_processor/importers/android_bugreport/android_log_parser.cc
index cf42150..b825862 100644
--- a/src/trace_processor/importers/android_bugreport/android_log_parser.cc
+++ b/src/trace_processor/importers/android_bugreport/android_log_parser.cc
@@ -17,10 +17,10 @@
 #include "src/trace_processor/importers/android_bugreport/android_log_parser.h"
 
 #include <string.h>
+#include <optional>
 
 #include "perfetto/base/logging.h"
 #include "perfetto/base/time.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "src/trace_processor/types/trace_processor_context.h"
 
@@ -42,9 +42,9 @@
 //      input="123",  decimal_scale=1000 -> res=123
 //      input="1234", decimal_scale=1000 -> res=123
 //      input="1234", decimal_scale=1000000 -> res=123400
-base::Optional<int> ReadNumAndAdvance(base::StringView* it,
-                                      char sep,
-                                      int decimal_scale = 0) {
+std::optional<int> ReadNumAndAdvance(base::StringView* it,
+                                     char sep,
+                                     int decimal_scale = 0) {
   int num = 0;
   bool sep_found = false;
   size_t next_it = 0;
@@ -73,13 +73,14 @@
     invalid_chars_found = true;
   }
   if (!sep_found)
-    return base::nullopt;
+    return std::nullopt;
   // If we find non-digit characters, we want to still skip the token but return
-  // nullopt. The parser below relies on token skipping to deal with cases where
-  // the uid (which we don't care about) is literal ("root" rather than 0).
+  // std::nullopt. The parser below relies on token skipping to deal with cases
+  // where the uid (which we don't care about) is literal ("root" rather than
+  // 0).
   *it = it->substr(next_it);
   if (invalid_chars_found)
-    return base::nullopt;
+    return std::nullopt;
   return num;
 }
 
@@ -146,18 +147,18 @@
     // 06-24 16:24:23.441532 23153 23153 I wm_on_stop_called: message ...
     // 07-28 14:25:13.506  root     0     0 I x86/fpu : Supporting XSAVE feature
     // 0x002: 'SSE registers'
-    base::Optional<int> month = ReadNumAndAdvance(&it, '-');
-    base::Optional<int> day = ReadNumAndAdvance(&it, ' ');
-    base::Optional<int> hour = ReadNumAndAdvance(&it, ':');
-    base::Optional<int> minute = ReadNumAndAdvance(&it, ':');
-    base::Optional<int> sec = ReadNumAndAdvance(&it, '.');
-    base::Optional<int> ns = ReadNumAndAdvance(&it, ' ', 1000 * 1000 * 1000);
+    std::optional<int> month = ReadNumAndAdvance(&it, '-');
+    std::optional<int> day = ReadNumAndAdvance(&it, ' ');
+    std::optional<int> hour = ReadNumAndAdvance(&it, ':');
+    std::optional<int> minute = ReadNumAndAdvance(&it, ':');
+    std::optional<int> sec = ReadNumAndAdvance(&it, '.');
+    std::optional<int> ns = ReadNumAndAdvance(&it, ' ', 1000 * 1000 * 1000);
 
     if (fmt == LogcatFormat::kBugreport)
       ReadNumAndAdvance(&it, ' ');  // Skip the UID column.
 
-    base::Optional<int> pid = ReadNumAndAdvance(&it, ' ');
-    base::Optional<int> tid = ReadNumAndAdvance(&it, ' ');
+    std::optional<int> pid = ReadNumAndAdvance(&it, ' ');
+    std::optional<int> tid = ReadNumAndAdvance(&it, ' ');
 
     if (!month || !day || !hour || !minute || !sec || !ns || !pid || !tid) {
       ++parse_failures;
diff --git a/src/trace_processor/importers/common/BUILD.gn b/src/trace_processor/importers/common/BUILD.gn
index 22a1154..7795398 100644
--- a/src/trace_processor/importers/common/BUILD.gn
+++ b/src/trace_processor/importers/common/BUILD.gn
@@ -33,6 +33,8 @@
     "flow_tracker.h",
     "global_args_tracker.cc",
     "global_args_tracker.h",
+    "metadata_tracker.cc",
+    "metadata_tracker.h",
     "process_tracker.cc",
     "process_tracker.h",
     "slice_tracker.cc",
diff --git a/src/trace_processor/importers/common/args_tracker.cc b/src/trace_processor/importers/common/args_tracker.cc
index 113c590..69eca73 100644
--- a/src/trace_processor/importers/common/args_tracker.cc
+++ b/src/trace_processor/importers/common/args_tracker.cc
@@ -82,7 +82,7 @@
     ArgSetId set_id =
         context_->global_args_tracker->AddArgSet(&args_[0], i, next_rid_idx);
     if (col->IsNullable()) {
-      TypedColumn<base::Optional<uint32_t>>::FromColumn(col)->Set(row, set_id);
+      TypedColumn<std::optional<uint32_t>>::FromColumn(col)->Set(row, set_id);
     } else {
       TypedColumn<uint32_t>::FromColumn(col)->Set(row, set_id);
     }
diff --git a/src/trace_processor/importers/common/args_translation_table.cc b/src/trace_processor/importers/common/args_translation_table.cc
index d1559e0..74cdc34 100644
--- a/src/trace_processor/importers/common/args_translation_table.cc
+++ b/src/trace_processor/importers/common/args_translation_table.cc
@@ -14,10 +14,11 @@
  * limitations under the License.
  */
 
-#include "src/trace_processor/importers/common/args_translation_table.h"
-#include "perfetto/ext/base/optional.h"
+#include <optional>
+
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/string_view.h"
+#include "src/trace_processor/importers/common/args_translation_table.h"
 
 namespace perfetto {
 namespace trace_processor {
@@ -105,8 +106,8 @@
 void ArgsTranslationTable::TranslateArgs(
     const ArgsTracker::CompactArgSet& arg_set,
     ArgsTracker::BoundInserter& inserter) const {
-  base::Optional<uint64_t> mapping_id;
-  base::Optional<uint64_t> rel_pc;
+  std::optional<uint64_t> mapping_id;
+  std::optional<uint64_t> rel_pc;
 
   for (const auto& arg : arg_set) {
     const auto key_type =
@@ -119,7 +120,7 @@
     switch (*key_type) {
       case KeyType::kChromeHistogramHash: {
         inserter.AddArg(interned_chrome_histogram_hash_key_, arg.value);
-        const base::Optional<base::StringView> translated_value =
+        const std::optional<base::StringView> translated_value =
             TranslateChromeHistogramHash(arg.value.uint_value);
         if (translated_value) {
           inserter.AddArg(
@@ -130,7 +131,7 @@
       }
       case KeyType::kChromeUserEventHash: {
         inserter.AddArg(interned_chrome_user_event_hash_key_, arg.value);
-        const base::Optional<base::StringView> translated_value =
+        const std::optional<base::StringView> translated_value =
             TranslateChromeUserEventHash(arg.value.uint_value);
         if (translated_value) {
           inserter.AddArg(
@@ -142,7 +143,7 @@
       case KeyType::kChromePerformanceMarkMarkHash: {
         inserter.AddArg(interned_chrome_performance_mark_mark_hash_key_,
                         arg.value);
-        const base::Optional<base::StringView> translated_value =
+        const std::optional<base::StringView> translated_value =
             TranslateChromePerformanceMarkMarkHash(arg.value.uint_value);
         if (translated_value) {
           inserter.AddArg(
@@ -154,7 +155,7 @@
       case KeyType::kChromePerformanceMarkSiteHash: {
         inserter.AddArg(interned_chrome_performance_mark_site_hash_key_,
                         arg.value);
-        const base::Optional<base::StringView> translated_value =
+        const std::optional<base::StringView> translated_value =
             TranslateChromePerformanceMarkSiteHash(arg.value.uint_value);
         if (translated_value) {
           inserter.AddArg(
@@ -164,7 +165,7 @@
         break;
       }
       case KeyType::kClassName: {
-        const base::Optional<StringId> translated_class_name =
+        const std::optional<StringId> translated_class_name =
             TranslateClassName(arg.value.string_value);
         if (translated_class_name) {
           inserter.AddArg(arg.flat_key, arg.key,
@@ -187,7 +188,7 @@
   EmitMojoMethodLocation(mapping_id, rel_pc, inserter);
 }
 
-base::Optional<ArgsTranslationTable::KeyType>
+std::optional<ArgsTranslationTable::KeyType>
 ArgsTranslationTable::KeyIdAndTypeToEnum(StringId flat_key_id,
                                          StringId key_id,
                                          Variadic::Type type) const {
@@ -215,66 +216,66 @@
       return KeyType::kClassName;
     }
   }
-  return base::nullopt;
+  return std::nullopt;
 }
 
-base::Optional<base::StringView>
+std::optional<base::StringView>
 ArgsTranslationTable::TranslateChromeHistogramHash(uint64_t hash) const {
   auto* value = chrome_histogram_hash_to_name_.Find(hash);
   if (!value) {
-    return base::nullopt;
+    return std::nullopt;
   }
   return base::StringView(*value);
 }
 
-base::Optional<base::StringView>
+std::optional<base::StringView>
 ArgsTranslationTable::TranslateChromeUserEventHash(uint64_t hash) const {
   auto* value = chrome_user_event_hash_to_action_.Find(hash);
   if (!value) {
-    return base::nullopt;
+    return std::nullopt;
   }
   return base::StringView(*value);
 }
 
-base::Optional<base::StringView>
+std::optional<base::StringView>
 ArgsTranslationTable::TranslateChromePerformanceMarkSiteHash(
     uint64_t hash) const {
   auto* value = chrome_performance_mark_site_hash_to_name_.Find(hash);
   if (!value) {
-    return base::nullopt;
+    return std::nullopt;
   }
   return base::StringView(*value);
 }
 
-base::Optional<base::StringView>
+std::optional<base::StringView>
 ArgsTranslationTable::TranslateChromePerformanceMarkMarkHash(
     uint64_t hash) const {
   auto* value = chrome_performance_mark_mark_hash_to_name_.Find(hash);
   if (!value) {
-    return base::nullopt;
+    return std::nullopt;
   }
   return base::StringView(*value);
 }
 
-base::Optional<ArgsTranslationTable::SourceLocation>
+std::optional<ArgsTranslationTable::SourceLocation>
 ArgsTranslationTable::TranslateNativeSymbol(MappingId mapping_id,
                                             uint64_t rel_pc) const {
   auto loc =
       native_symbol_to_location_.Find(std::make_pair(mapping_id, rel_pc));
   if (!loc) {
-    return base::nullopt;
+    return std::nullopt;
   }
   return *loc;
 }
 
-base::Optional<StringId> ArgsTranslationTable::TranslateClassName(
+std::optional<StringId> ArgsTranslationTable::TranslateClassName(
     StringId obfuscated_class_name_id) const {
   return deobfuscation_mapping_table_.TranslateClass(obfuscated_class_name_id);
 }
 
 void ArgsTranslationTable::EmitMojoMethodLocation(
-    base::Optional<uint64_t> mapping_id,
-    base::Optional<uint64_t> rel_pc,
+    std::optional<uint64_t> mapping_id,
+    std::optional<uint64_t> rel_pc,
     ArgsTracker::BoundInserter& inserter) const {
   if (!mapping_id || !rel_pc) {
     return;
diff --git a/src/trace_processor/importers/common/args_translation_table.h b/src/trace_processor/importers/common/args_translation_table.h
index e1b3178..f5bb1b2 100644
--- a/src/trace_processor/importers/common/args_translation_table.h
+++ b/src/trace_processor/importers/common/args_translation_table.h
@@ -18,9 +18,9 @@
 #define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_ARGS_TRANSLATION_TABLE_H_
 
 #include <cstdint>
+#include <optional>
 
 #include "perfetto/ext/base/flat_hash_map.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
 #include "src/trace_processor/importers/common/deobfuscation_mapping_table.h"
@@ -86,23 +86,23 @@
     deobfuscation_mapping_table_ = std::move(deobfuscation_mapping_table);
   }
 
-  base::Optional<base::StringView> TranslateChromeHistogramHashForTesting(
+  std::optional<base::StringView> TranslateChromeHistogramHashForTesting(
       uint64_t hash) const {
     return TranslateChromeHistogramHash(hash);
   }
-  base::Optional<base::StringView> TranslateChromeUserEventHashForTesting(
+  std::optional<base::StringView> TranslateChromeUserEventHashForTesting(
       uint64_t hash) const {
     return TranslateChromeUserEventHash(hash);
   }
-  base::Optional<base::StringView>
+  std::optional<base::StringView>
   TranslateChromePerformanceMarkSiteHashForTesting(uint64_t hash) const {
     return TranslateChromePerformanceMarkSiteHash(hash);
   }
-  base::Optional<base::StringView>
+  std::optional<base::StringView>
   TranslateChromePerformanceMarkMarkHashForTesting(uint64_t hash) const {
     return TranslateChromePerformanceMarkMarkHash(hash);
   }
-  base::Optional<StringId> TranslateClassNameForTesting(
+  std::optional<StringId> TranslateClassNameForTesting(
       StringId obfuscated_class_name_id) const {
     return TranslateClassName(obfuscated_class_name_id);
   }
@@ -180,29 +180,30 @@
   DeobfuscationMappingTable deobfuscation_mapping_table_;
 
   // Returns the corresponding SupportedKey enum if the table knows how to
-  // translate the argument with the given key and type, and nullopt otherwise.
-  base::Optional<KeyType> KeyIdAndTypeToEnum(StringId flat_key_id,
-                                             StringId key_id,
-                                             Variadic::Type type) const;
+  // translate the argument with the given key and type, and std::nullopt
+  // otherwise.
+  std::optional<KeyType> KeyIdAndTypeToEnum(StringId flat_key_id,
+                                            StringId key_id,
+                                            Variadic::Type type) const;
 
-  base::Optional<base::StringView> TranslateChromeHistogramHash(
+  std::optional<base::StringView> TranslateChromeHistogramHash(
       uint64_t hash) const;
-  base::Optional<base::StringView> TranslateChromeUserEventHash(
+  std::optional<base::StringView> TranslateChromeUserEventHash(
       uint64_t hash) const;
-  base::Optional<base::StringView> TranslateChromePerformanceMarkSiteHash(
+  std::optional<base::StringView> TranslateChromePerformanceMarkSiteHash(
       uint64_t hash) const;
-  base::Optional<base::StringView> TranslateChromePerformanceMarkMarkHash(
+  std::optional<base::StringView> TranslateChromePerformanceMarkMarkHash(
       uint64_t hash) const;
-  base::Optional<SourceLocation> TranslateNativeSymbol(MappingId mapping_id,
-                                                       uint64_t rel_pc) const;
+  std::optional<SourceLocation> TranslateNativeSymbol(MappingId mapping_id,
+                                                      uint64_t rel_pc) const;
 
-  // Returns the deobfuscated name of a Java class or base::nullopt if
+  // Returns the deobfuscated name of a Java class or std::nullopt if
   // translation is not found.
-  base::Optional<StringId> TranslateClassName(
+  std::optional<StringId> TranslateClassName(
       StringId obfuscated_class_name_id) const;
 
-  void EmitMojoMethodLocation(base::Optional<uint64_t> mapping_id,
-                              base::Optional<uint64_t> rel_pc,
+  void EmitMojoMethodLocation(std::optional<uint64_t> mapping_id,
+                              std::optional<uint64_t> rel_pc,
                               ArgsTracker::BoundInserter& inserter) const;
 };
 
diff --git a/src/trace_processor/importers/common/args_translation_table_unittest.cc b/src/trace_processor/importers/common/args_translation_table_unittest.cc
index 904e607..e44b034 100644
--- a/src/trace_processor/importers/common/args_translation_table_unittest.cc
+++ b/src/trace_processor/importers/common/args_translation_table_unittest.cc
@@ -15,7 +15,9 @@
  */
 
 #include "src/trace_processor/importers/common/args_translation_table.h"
-#include "perfetto/ext/base/optional.h"
+
+#include <optional>
+
 #include "src/trace_processor/importers/common/deobfuscation_mapping_table.h"
 #include "test/gtest_and_gmock.h"
 
@@ -26,8 +28,8 @@
 TEST(ArgsTranslationTable, EmptyTableByDefault) {
   TraceStorage storage;
   ArgsTranslationTable table(&storage);
-  EXPECT_EQ(table.TranslateChromeHistogramHashForTesting(1), base::nullopt);
-  EXPECT_EQ(table.TranslateChromeUserEventHashForTesting(1), base::nullopt);
+  EXPECT_EQ(table.TranslateChromeHistogramHashForTesting(1), std::nullopt);
+  EXPECT_EQ(table.TranslateChromeUserEventHashForTesting(1), std::nullopt);
 }
 
 TEST(ArgsTranslationTable, TranslatesHistogramHashes) {
@@ -36,10 +38,10 @@
   table.AddChromeHistogramTranslationRule(1, "hash1");
   table.AddChromeHistogramTranslationRule(10, "hash2");
   EXPECT_EQ(table.TranslateChromeHistogramHashForTesting(1),
-            base::Optional<base::StringView>("hash1"));
+            std::optional<base::StringView>("hash1"));
   EXPECT_EQ(table.TranslateChromeHistogramHashForTesting(10),
-            base::Optional<base::StringView>("hash2"));
-  EXPECT_EQ(table.TranslateChromeHistogramHashForTesting(2), base::nullopt);
+            std::optional<base::StringView>("hash2"));
+  EXPECT_EQ(table.TranslateChromeHistogramHashForTesting(2), std::nullopt);
 }
 
 TEST(ArgsTranslationTable, TranslatesUserEventHashes) {
@@ -48,10 +50,10 @@
   table.AddChromeUserEventTranslationRule(1, "action1");
   table.AddChromeUserEventTranslationRule(10, "action2");
   EXPECT_EQ(table.TranslateChromeUserEventHashForTesting(1),
-            base::Optional<base::StringView>("action1"));
+            std::optional<base::StringView>("action1"));
   EXPECT_EQ(table.TranslateChromeUserEventHashForTesting(10),
-            base::Optional<base::StringView>("action2"));
-  EXPECT_EQ(table.TranslateChromeUserEventHashForTesting(2), base::nullopt);
+            std::optional<base::StringView>("action2"));
+  EXPECT_EQ(table.TranslateChromeUserEventHashForTesting(2), std::nullopt);
 }
 
 TEST(ArgsTranslationTable, TranslatesPerformanceMarkSiteHashes) {
@@ -60,11 +62,11 @@
   table.AddChromePerformanceMarkSiteTranslationRule(1, "hash1");
   table.AddChromePerformanceMarkSiteTranslationRule(10, "hash2");
   EXPECT_EQ(table.TranslateChromePerformanceMarkSiteHashForTesting(1),
-            base::Optional<base::StringView>("hash1"));
+            std::optional<base::StringView>("hash1"));
   EXPECT_EQ(table.TranslateChromePerformanceMarkSiteHashForTesting(10),
-            base::Optional<base::StringView>("hash2"));
+            std::optional<base::StringView>("hash2"));
   EXPECT_EQ(table.TranslateChromePerformanceMarkSiteHashForTesting(2),
-            base::nullopt);
+            std::nullopt);
 }
 
 TEST(ArgsTranslationTable, TranslatesPerformanceMarkMarkHashes) {
@@ -73,11 +75,11 @@
   table.AddChromePerformanceMarkMarkTranslationRule(1, "hash1");
   table.AddChromePerformanceMarkMarkTranslationRule(10, "hash2");
   EXPECT_EQ(table.TranslateChromePerformanceMarkMarkHashForTesting(1),
-            base::Optional<base::StringView>("hash1"));
+            std::optional<base::StringView>("hash1"));
   EXPECT_EQ(table.TranslateChromePerformanceMarkMarkHashForTesting(10),
-            base::Optional<base::StringView>("hash2"));
+            std::optional<base::StringView>("hash2"));
   EXPECT_EQ(table.TranslateChromePerformanceMarkMarkHashForTesting(2),
-            base::nullopt);
+            std::nullopt);
 }
 
 TEST(ArgsTranslationTable, TranslateClassName) {
@@ -93,8 +95,8 @@
   table.AddDeobfuscationMappingTable(std::move(deobfuscation_mapping));
 
   EXPECT_EQ(table.TranslateClassNameForTesting(xyz_id),
-            base::Optional<StringId>(class_x_id));
-  EXPECT_EQ(table.TranslateClassNameForTesting(abc_id), base::nullopt);
+            std::optional<StringId>(class_x_id));
+  EXPECT_EQ(table.TranslateClassNameForTesting(abc_id), std::nullopt);
 }
 
 TEST(ArgsTranslationTable, NeedsTranslation) {
diff --git a/src/trace_processor/importers/common/clock_tracker.cc b/src/trace_processor/importers/common/clock_tracker.cc
index a2feea9..987739c 100644
--- a/src/trace_processor/importers/common/clock_tracker.cc
+++ b/src/trace_processor/importers/common/clock_tracker.cc
@@ -36,8 +36,8 @@
 
 using Clock = protos::pbzero::ClockSnapshot::Clock;
 
-ClockTracker::ClockTracker(TraceStorage* storage)
-    : storage_(storage),
+ClockTracker::ClockTracker(TraceProcessorContext* context)
+    : context_(context),
       trace_time_clock_id_(protos::pbzero::BUILTIN_CLOCK_BOOTTIME) {}
 
 ClockTracker::~ClockTracker() = default;
@@ -67,7 +67,7 @@
                       " cannot use incremental encoding; this is only "
                       "supported for sequence-scoped clocks.",
                       clock_id);
-        storage_->IncrementStats(stats::invalid_clock_snapshots);
+        context_->storage->IncrementStats(stats::invalid_clock_snapshots);
         return snapshot_id;
       }
       domain.unit_multiplier_ns = clock_ts.clock.unit_multiplier_ns;
@@ -83,7 +83,7 @@
                     clock_id, clock_ts.clock.unit_multiplier_ns,
                     clock_ts.clock.is_incremental, domain.unit_multiplier_ns,
                     domain.is_incremental);
-      storage_->IncrementStats(stats::invalid_clock_snapshots);
+      context_->storage->IncrementStats(stats::invalid_clock_snapshots);
       return snapshot_id;
     }
     const int64_t timestamp_ns = clock_ts.timestamp * domain.unit_multiplier_ns;
@@ -95,7 +95,7 @@
       PERFETTO_ELOG("Clock sync error: duplicate clock domain with id=%" PRIu64
                     " at snapshot %" PRIu32 ".",
                     clock_id, snapshot_id);
-      storage_->IncrementStats(stats::invalid_clock_snapshots);
+      context_->storage->IncrementStats(stats::invalid_clock_snapshots);
       return snapshot_id;
     }
 
@@ -119,7 +119,7 @@
                       " not >= %" PRId64 ".",
                       clock_id, snapshot_id, timestamp_ns,
                       vect.timestamps_ns.back());
-        storage_->IncrementStats(stats::invalid_clock_snapshots);
+        context_->storage->IncrementStats(stats::invalid_clock_snapshots);
         return snapshot_id;
       }
 
@@ -220,12 +220,12 @@
   PERFETTO_DCHECK(!IsSequenceClock(src_clock_id));
   PERFETTO_DCHECK(!IsSequenceClock(target_clock_id));
 
-  storage_->IncrementStats(stats::clock_sync_cache_miss);
+  context_->storage->IncrementStats(stats::clock_sync_cache_miss);
 
   ClockPath path = FindPath(src_clock_id, target_clock_id);
   if (!path.valid()) {
     // Too many logs maybe emitted when path is invalid.
-    storage_->IncrementStats(stats::clock_sync_failure);
+    context_->storage->IncrementStats(stats::clock_sync_failure);
     return base::ErrStatus("No path from clock %" PRIu64 " to %" PRIu64
                            " at timestamp %" PRId64,
                            src_clock_id, target_clock_id, src_timestamp);
diff --git a/src/trace_processor/importers/common/clock_tracker.h b/src/trace_processor/importers/common/clock_tracker.h
index 2e4a3b1..a4edd3c 100644
--- a/src/trace_processor/importers/common/clock_tracker.h
+++ b/src/trace_processor/importers/common/clock_tracker.h
@@ -22,15 +22,17 @@
 #include <array>
 #include <cinttypes>
 #include <map>
+#include <optional>
 #include <random>
 #include <set>
 #include <vector>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/status_or.h"
 #include "perfetto/ext/base/string_utils.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/storage/trace_storage.h"
+#include "src/trace_processor/types/trace_processor_context.h"
 
 namespace perfetto {
 namespace trace_processor {
@@ -116,9 +118,9 @@
 
 class ClockTracker {
  public:
-  using ClockId = uint64_t;
+  using ClockId = int64_t;
 
-  explicit ClockTracker(TraceStorage*);
+  explicit ClockTracker(TraceProcessorContext*);
   virtual ~ClockTracker();
 
   // Clock description.
@@ -153,7 +155,7 @@
   // passed as argument to ClockTracker functions.
   static ClockId SeqenceToGlobalClock(uint32_t seq_id, uint32_t clock_id) {
     PERFETTO_DCHECK(IsSequenceClock(clock_id));
-    return (static_cast<uint64_t>(seq_id) << 32) | clock_id;
+    return (static_cast<int64_t>(seq_id) << 32) | clock_id;
   }
 
   // Appends a new snapshot for the given clock domains.
@@ -162,6 +164,12 @@
   uint32_t AddSnapshot(const std::vector<ClockTimestamp>&);
 
   base::StatusOr<int64_t> ToTraceTime(ClockId clock_id, int64_t timestamp) {
+    if (PERFETTO_UNLIKELY(!trace_time_clock_id_used_for_conversion_)) {
+      context_->metadata_tracker->SetMetadata(
+          metadata::trace_time_clock_id,
+          Variadic::Integer(trace_time_clock_id_));
+      trace_time_clock_id_used_for_conversion_ = true;
+    }
     trace_time_clock_id_used_for_conversion_ = true;
     if (clock_id == trace_time_clock_id_)
       return timestamp;
@@ -189,6 +197,8 @@
       return;
     }
     trace_time_clock_id_ = clock_id;
+    context_->metadata_tracker->SetMetadata(
+        metadata::trace_time_clock_id, Variadic::Integer(trace_time_clock_id_));
   }
 
   void set_cache_lookups_disabled_for_testing(bool v) {
@@ -328,7 +338,7 @@
     return &it->second;
   }
 
-  TraceStorage* const storage_;
+  TraceProcessorContext* const context_;
   ClockId trace_time_clock_id_ = 0;
   std::map<ClockId, ClockDomain> clocks_;
   std::set<ClockGraphEdge> graph_;
diff --git a/src/trace_processor/importers/common/clock_tracker_unittest.cc b/src/trace_processor/importers/common/clock_tracker_unittest.cc
index 0614372..74a665f 100644
--- a/src/trace_processor/importers/common/clock_tracker_unittest.cc
+++ b/src/trace_processor/importers/common/clock_tracker_unittest.cc
@@ -16,9 +16,10 @@
 
 #include "src/trace_processor/importers/common/clock_tracker.h"
 
+#include <optional>
 #include <random>
 
-#include "perfetto/ext/base/optional.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/storage/trace_storage.h"
 #include "src/trace_processor/types/trace_processor_context.h"
 #include "test/gtest_and_gmock.h"
@@ -31,9 +32,15 @@
 
 class ClockTrackerTest : public ::testing::Test {
  public:
+  ClockTrackerTest() {
+    context_.storage.reset(new TraceStorage());
+    context_.metadata_tracker.reset(
+        new MetadataTracker(context_.storage.get()));
+  }
+
   // using ClockId = uint64_t;
-  TraceStorage storage_;
-  ClockTracker ct_{&storage_};
+  TraceProcessorContext context_;
+  ClockTracker ct_{&context_};
   base::StatusOr<int64_t> Convert(ClockTracker::ClockId src_clock_id,
                                   int64_t src_timestamp,
                                   ClockTracker::ClockId target_clock_id) {
diff --git a/src/trace_processor/importers/common/deobfuscation_mapping_table.cc b/src/trace_processor/importers/common/deobfuscation_mapping_table.cc
index af5bbf3..243295b 100644
--- a/src/trace_processor/importers/common/deobfuscation_mapping_table.cc
+++ b/src/trace_processor/importers/common/deobfuscation_mapping_table.cc
@@ -39,50 +39,50 @@
       .second;
 }
 
-base::Optional<StringId> DeobfuscationMappingTable::TranslateClass(
+std::optional<StringId> DeobfuscationMappingTable::TranslateClass(
     StringId obfuscated_class_name) const {
   if (PERFETTO_UNLIKELY(!default_package_id_.has_value())) {
-    return base::nullopt;
+    return std::nullopt;
   }
   return TranslateClass(default_package_id_.value(), obfuscated_class_name);
 }
 
-base::Optional<StringId> DeobfuscationMappingTable::TranslateClass(
+std::optional<StringId> DeobfuscationMappingTable::TranslateClass(
     const PackageId& package,
     StringId obfuscated_class_name) const {
   const ObfuscatedClassesToMembers* classes_translation_ptr =
       class_per_package_translation_.Find(package);
   if (classes_translation_ptr == nullptr) {
-    return base::nullopt;
+    return std::nullopt;
   }
   const ClassTranslation* class_translation_ptr =
       classes_translation_ptr->Find(obfuscated_class_name);
   if (class_translation_ptr == nullptr) {
-    return base::nullopt;
+    return std::nullopt;
   }
   return class_translation_ptr->deobfuscated_class_name;
 }
 
-base::Optional<StringId> DeobfuscationMappingTable::TranslateMember(
+std::optional<StringId> DeobfuscationMappingTable::TranslateMember(
     const PackageId& package,
     StringId obfuscated_class_name,
     StringId obfuscated_member) const {
   const ObfuscatedClassesToMembers* classes_translation_ptr =
       class_per_package_translation_.Find(package);
   if (classes_translation_ptr == nullptr) {
-    return base::nullopt;
+    return std::nullopt;
   }
 
   const ClassTranslation* class_translation_ptr =
       classes_translation_ptr->Find(obfuscated_class_name);
   if (class_translation_ptr == nullptr) {
-    return base::nullopt;
+    return std::nullopt;
   }
 
   const StringId* member_translation_ptr =
       class_translation_ptr->members.Find(obfuscated_member);
   if (member_translation_ptr == nullptr) {
-    return base::nullopt;
+    return std::nullopt;
   }
   return *member_translation_ptr;
 }
diff --git a/src/trace_processor/importers/common/deobfuscation_mapping_table.h b/src/trace_processor/importers/common/deobfuscation_mapping_table.h
index 7022b19..9beeab9 100644
--- a/src/trace_processor/importers/common/deobfuscation_mapping_table.h
+++ b/src/trace_processor/importers/common/deobfuscation_mapping_table.h
@@ -18,12 +18,12 @@
 #define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_DEOBFUSCATION_MAPPING_TABLE_H_
 
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "perfetto/ext/base/flat_hash_map.h"
 #include "perfetto/ext/base/hash.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 #include "src/trace_processor/storage/trace_storage.h"
 
@@ -58,16 +58,16 @@
   // These functions return the deobfuscated class/member name from an
   // obfuscated class/member name.
   // If a package is not provided, the |default_package_id_| is used.
-  // If translation is not found, returns base::nullopt.
+  // If translation is not found, returns std::nullopt.
 
-  base::Optional<StringId> TranslateClass(StringId obfuscated_class_name) const;
+  std::optional<StringId> TranslateClass(StringId obfuscated_class_name) const;
 
-  base::Optional<StringId> TranslateClass(const PackageId& package,
-                                          StringId obfuscated_class_name) const;
+  std::optional<StringId> TranslateClass(const PackageId& package,
+                                         StringId obfuscated_class_name) const;
 
-  base::Optional<StringId> TranslateMember(const PackageId& package,
-                                           StringId obfuscated_class_name,
-                                           StringId obfuscated_member) const;
+  std::optional<StringId> TranslateMember(const PackageId& package,
+                                          StringId obfuscated_class_name,
+                                          StringId obfuscated_member) const;
 
  private:
   struct PackageIdHash {
@@ -94,7 +94,7 @@
   // We need this because curently TraceProcessor doesn't use the package
   // version of the arguments.
   // TODO(b/244700870): start use the package version of arguments.
-  base::Optional<PackageId> default_package_id_;
+  std::optional<PackageId> default_package_id_;
 };
 
 }  // namespace trace_processor
diff --git a/src/trace_processor/importers/common/deobfuscation_mapping_table_unittest.cc b/src/trace_processor/importers/common/deobfuscation_mapping_table_unittest.cc
index 5b24492..d663db4 100644
--- a/src/trace_processor/importers/common/deobfuscation_mapping_table_unittest.cc
+++ b/src/trace_processor/importers/common/deobfuscation_mapping_table_unittest.cc
@@ -30,8 +30,8 @@
   StringId xyz_id = storage.InternString("xyz");
 
   DeobfuscationMappingTable table;
-  EXPECT_EQ(table.TranslateClass(xyz_id), base::nullopt);
-  EXPECT_EQ(table.TranslateClass(PackageId{"app", 123}, xyz_id), base::nullopt);
+  EXPECT_EQ(table.TranslateClass(xyz_id), std::nullopt);
+  EXPECT_EQ(table.TranslateClass(PackageId{"app", 123}, xyz_id), std::nullopt);
 }
 
 TEST(DeobfuscationMappingTable, TranslateClassSingleInsert) {
@@ -45,8 +45,8 @@
                             base::FlatHashMap<StringId, StringId>{});
   EXPECT_EQ(table.TranslateClass(xyz_id), class_x_id);
   EXPECT_EQ(table.TranslateClass(PackageId{"app", 123}, xyz_id), class_x_id);
-  EXPECT_EQ(table.TranslateClass(PackageId{"app", 124}, xyz_id), base::nullopt);
-  EXPECT_EQ(table.TranslateClass(PackageId{"app", 123}, abc_id), base::nullopt);
+  EXPECT_EQ(table.TranslateClass(PackageId{"app", 124}, xyz_id), std::nullopt);
+  EXPECT_EQ(table.TranslateClass(PackageId{"app", 123}, abc_id), std::nullopt);
 }
 
 TEST(DeobfuscationMappingTable, TranslateClassMultipleInsert) {
@@ -65,11 +65,10 @@
   table.AddClassTranslation(PackageId{"app3", 123}, abc_id, class_a_id,
                             base::FlatHashMap<StringId, StringId>{});
   EXPECT_EQ(table.TranslateClass(xyz_id), class_x_id);
-  EXPECT_EQ(table.TranslateClass(abc_id), base::nullopt);
+  EXPECT_EQ(table.TranslateClass(abc_id), std::nullopt);
   EXPECT_EQ(table.TranslateClass(PackageId{"app1", 123}, xyz_id), class_x_id);
   EXPECT_EQ(table.TranslateClass(PackageId{"app2", 123}, xyz_id), class_y_id);
-  EXPECT_EQ(table.TranslateClass(PackageId{"app1", 123}, abc_id),
-            base::nullopt);
+  EXPECT_EQ(table.TranslateClass(PackageId{"app1", 123}, abc_id), std::nullopt);
 }
 
 TEST(DeobfuscationMappingTable, TranslateMember) {
@@ -95,11 +94,11 @@
   EXPECT_EQ(table.TranslateMember(PackageId{"app1", 123}, xyz_id, mmm_2_id),
             member_2_id);
   EXPECT_EQ(table.TranslateMember(PackageId{"app1", 123}, xyz_id, mmm_4_id),
-            base::nullopt);
+            std::nullopt);
   EXPECT_EQ(table.TranslateMember(PackageId{"app1", 123}, abc_id, mmm_2_id),
-            base::nullopt);
+            std::nullopt);
   EXPECT_EQ(table.TranslateMember(PackageId{"app1", 124}, xyz_id, mmm_2_id),
-            base::nullopt);
+            std::nullopt);
 }
 
 }  // namespace
diff --git a/src/trace_processor/importers/common/event_tracker.cc b/src/trace_processor/importers/common/event_tracker.cc
index cf59e40..0ed799b 100644
--- a/src/trace_processor/importers/common/event_tracker.cc
+++ b/src/trace_processor/importers/common/event_tracker.cc
@@ -17,9 +17,9 @@
 #include "src/trace_processor/importers/common/event_tracker.h"
 
 #include <math.h>
+#include <optional>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/utils.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
 #include "src/trace_processor/importers/common/process_tracker.h"
@@ -36,7 +36,7 @@
 
 EventTracker::~EventTracker() = default;
 
-base::Optional<CounterId> EventTracker::PushProcessCounterForThread(
+std::optional<CounterId> EventTracker::PushProcessCounterForThread(
     int64_t timestamp,
     double value,
     StringId name_id,
@@ -52,15 +52,15 @@
   return opt_id;
 }
 
-base::Optional<CounterId> EventTracker::PushCounter(int64_t timestamp,
-                                                    double value,
-                                                    TrackId track_id) {
+std::optional<CounterId> EventTracker::PushCounter(int64_t timestamp,
+                                                   double value,
+                                                   TrackId track_id) {
   if (timestamp < max_timestamp_) {
     PERFETTO_DLOG(
         "counter event (ts: %" PRId64 ") out of order by %.4f ms, skipping",
         timestamp, static_cast<double>(max_timestamp_ - timestamp) / 1e6);
     context_->storage->IncrementStats(stats::counter_events_out_of_order);
-    return base::nullopt;
+    return std::nullopt;
   }
   max_timestamp_ = timestamp;
 
@@ -68,7 +68,7 @@
   return counter_values->Insert({timestamp, track_id, value}).id;
 }
 
-base::Optional<CounterId> EventTracker::PushCounter(
+std::optional<CounterId> EventTracker::PushCounter(
     int64_t timestamp,
     double value,
     TrackId track_id,
@@ -85,7 +85,7 @@
   const auto& thread_table = context_->storage->thread_table();
   for (const auto& pending_counter : pending_upid_resolution_counter_) {
     UniqueTid utid = pending_counter.utid;
-    base::Optional<UniquePid> upid = thread_table.upid()[utid];
+    std::optional<UniquePid> upid = thread_table.upid()[utid];
 
     TrackId track_id = kInvalidTrackId;
     if (upid.has_value()) {
diff --git a/src/trace_processor/importers/common/event_tracker.h b/src/trace_processor/importers/common/event_tracker.h
index 16117f0..626e80e 100644
--- a/src/trace_processor/importers/common/event_tracker.h
+++ b/src/trace_processor/importers/common/event_tracker.h
@@ -42,16 +42,16 @@
 
   // Adds a counter event to the counters table returning the index of the
   // newly added row.
-  virtual base::Optional<CounterId> PushCounter(int64_t timestamp,
-                                                double value,
-                                                TrackId track_id);
+  virtual std::optional<CounterId> PushCounter(int64_t timestamp,
+                                               double value,
+                                               TrackId track_id);
 
   // Adds a counter event with args to the counters table returning the index of
   // the newly added row.
-  base::Optional<CounterId> PushCounter(int64_t timestamp,
-                                        double value,
-                                        TrackId track_id,
-                                        SetArgsCallback args_callback);
+  std::optional<CounterId> PushCounter(int64_t timestamp,
+                                       double value,
+                                       TrackId track_id,
+                                       SetArgsCallback args_callback);
 
   // Adds a counter event to the counters table for counter events which
   // should be associated with a process but only have a thread context
@@ -59,7 +59,7 @@
   //
   // This function will resolve the utid to a upid when the events are
   // flushed (see |FlushPendingEvents()|).
-  virtual base::Optional<CounterId> PushProcessCounterForThread(
+  virtual std::optional<CounterId> PushProcessCounterForThread(
       int64_t timestamp,
       double value,
       StringId name_id,
diff --git a/src/trace_processor/importers/common/flow_tracker.cc b/src/trace_processor/importers/common/flow_tracker.cc
index ff9f609..7805544 100644
--- a/src/trace_processor/importers/common/flow_tracker.cc
+++ b/src/trace_processor/importers/common/flow_tracker.cc
@@ -40,7 +40,7 @@
   it is a bit tricky to make it here.
   We suspect that this case is too rare or impossible */
 void FlowTracker::Begin(TrackId track_id, FlowId flow_id) {
-  base::Optional<SliceId> open_slice_id =
+  std::optional<SliceId> open_slice_id =
       context_->slice_tracker->GetTopmostSliceOnTrack(track_id);
   if (!open_slice_id) {
     context_->storage->IncrementStats(stats::flow_no_enclosing_slice);
@@ -58,7 +58,7 @@
 }
 
 void FlowTracker::Step(TrackId track_id, FlowId flow_id) {
-  base::Optional<SliceId> open_slice_id =
+  std::optional<SliceId> open_slice_id =
       context_->slice_tracker->GetTopmostSliceOnTrack(track_id);
   if (!open_slice_id) {
     context_->storage->IncrementStats(stats::flow_no_enclosing_slice);
@@ -86,7 +86,7 @@
     pending_flow_ids_map_[track_id].push_back(flow_id);
     return;
   }
-  base::Optional<SliceId> open_slice_id =
+  std::optional<SliceId> open_slice_id =
       context_->slice_tracker->GetTopmostSliceOnTrack(track_id);
   if (!open_slice_id) {
     context_->storage->IncrementStats(stats::flow_no_enclosing_slice);
diff --git a/src/trace_processor/importers/proto/metadata_tracker.cc b/src/trace_processor/importers/common/metadata_tracker.cc
similarity index 97%
rename from src/trace_processor/importers/proto/metadata_tracker.cc
rename to src/trace_processor/importers/common/metadata_tracker.cc
index a5e6928..7468c42 100644
--- a/src/trace_processor/importers/proto/metadata_tracker.cc
+++ b/src/trace_processor/importers/common/metadata_tracker.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 
 #include "perfetto/ext/base/crash_keys.h"
 #include "src/trace_processor/importers/common/process_tracker.h"
@@ -52,7 +52,7 @@
 
   auto* metadata_table = storage_->mutable_metadata_table();
   uint32_t key_idx = static_cast<uint32_t>(key);
-  base::Optional<uint32_t> opt_row =
+  std::optional<uint32_t> opt_row =
       metadata_table->name().IndexOf(metadata::kNames[key_idx]);
   if (opt_row) {
     WriteValue(*opt_row, value);
diff --git a/src/trace_processor/importers/proto/metadata_tracker.h b/src/trace_processor/importers/common/metadata_tracker.h
similarity index 91%
rename from src/trace_processor/importers/proto/metadata_tracker.h
rename to src/trace_processor/importers/common/metadata_tracker.h
index c3e587e..80cace9 100644
--- a/src/trace_processor/importers/proto/metadata_tracker.h
+++ b/src/trace_processor/importers/common/metadata_tracker.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_METADATA_TRACKER_H_
-#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_METADATA_TRACKER_H_
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_METADATA_TRACKER_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_METADATA_TRACKER_H_
 
 #include "src/trace_processor/storage/trace_storage.h"
 
@@ -70,4 +70,4 @@
 }  // namespace trace_processor
 }  // namespace perfetto
 
-#endif  // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_METADATA_TRACKER_H_
+#endif  // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_METADATA_TRACKER_H_
diff --git a/src/trace_processor/importers/common/parser_types.h b/src/trace_processor/importers/common/parser_types.h
index e6575f1..2b5648a 100644
--- a/src/trace_processor/importers/common/parser_types.h
+++ b/src/trace_processor/importers/common/parser_types.h
@@ -68,8 +68,8 @@
   }
 
   TracePacketData trace_packet_data;
-  base::Optional<int64_t> thread_timestamp;
-  base::Optional<int64_t> thread_instruction_count;
+  std::optional<int64_t> thread_timestamp;
+  std::optional<int64_t> thread_instruction_count;
   double counter_value = 0;
   std::array<double, kMaxNumExtraCounters> extra_counter_values = {};
 };
diff --git a/src/trace_processor/importers/common/process_tracker.cc b/src/trace_processor/importers/common/process_tracker.cc
index df14d2c..473c48e 100644
--- a/src/trace_processor/importers/common/process_tracker.cc
+++ b/src/trace_processor/importers/common/process_tracker.cc
@@ -48,7 +48,7 @@
 
 ProcessTracker::~ProcessTracker() = default;
 
-UniqueTid ProcessTracker::StartNewThread(base::Optional<int64_t> timestamp,
+UniqueTid ProcessTracker::StartNewThread(std::optional<int64_t> timestamp,
                                          uint32_t tid) {
   tables::ThreadTable::Row row;
   row.tid = tid;
@@ -74,7 +74,7 @@
   // we would have already ended the process and we don't want to
   // create a new thread here (see b/193520421 for an example of a trace
   // where this happens in practice).
-  base::Optional<UniqueTid> opt_utid = GetThreadOrNull(tid);
+  std::optional<UniqueTid> opt_utid = GetThreadOrNull(tid);
   if (!opt_utid)
     return;
 
@@ -97,10 +97,10 @@
   pids_.Erase(tid);
 }
 
-base::Optional<UniqueTid> ProcessTracker::GetThreadOrNull(uint32_t tid) {
-  auto opt_utid = GetThreadOrNull(tid, base::nullopt);
+std::optional<UniqueTid> ProcessTracker::GetThreadOrNull(uint32_t tid) {
+  auto opt_utid = GetThreadOrNull(tid, std::nullopt);
   if (!opt_utid)
-    return base::nullopt;
+    return std::nullopt;
 
   auto* threads = context_->storage->mutable_thread_table();
   UniqueTid utid = *opt_utid;
@@ -117,7 +117,7 @@
 
 UniqueTid ProcessTracker::GetOrCreateThread(uint32_t tid) {
   auto utid = GetThreadOrNull(tid);
-  return utid ? *utid : StartNewThread(base::nullopt, tid);
+  return utid ? *utid : StartNewThread(std::nullopt, tid);
 }
 
 UniqueTid ProcessTracker::UpdateThreadName(uint32_t tid,
@@ -168,15 +168,15 @@
   return true;
 }
 
-base::Optional<UniqueTid> ProcessTracker::GetThreadOrNull(
+std::optional<UniqueTid> ProcessTracker::GetThreadOrNull(
     uint32_t tid,
-    base::Optional<uint32_t> pid) {
+    std::optional<uint32_t> pid) {
   auto* threads = context_->storage->mutable_thread_table();
   auto* processes = context_->storage->mutable_process_table();
 
   auto vector_it = tids_.Find(tid);
   if (!vector_it)
-    return base::nullopt;
+    return std::nullopt;
 
   // Iterate backwards through the threads so ones later in the trace are more
   // likely to be picked.
@@ -202,17 +202,17 @@
     if (!pid || current_pid == *pid)
       return current_utid;
   }
-  return base::nullopt;
+  return std::nullopt;
 }
 
 UniqueTid ProcessTracker::UpdateThread(uint32_t tid, uint32_t pid) {
   auto* thread_table = context_->storage->mutable_thread_table();
 
   // Try looking for a thread that matches both tid and thread group id (pid).
-  base::Optional<UniqueTid> opt_utid = GetThreadOrNull(tid, pid);
+  std::optional<UniqueTid> opt_utid = GetThreadOrNull(tid, pid);
 
   // If no matching thread was found, create a new one.
-  UniqueTid utid = opt_utid ? *opt_utid : StartNewThread(base::nullopt, tid);
+  UniqueTid utid = opt_utid ? *opt_utid : StartNewThread(std::nullopt, tid);
   PERFETTO_DCHECK(thread_table->tid()[utid] == tid);
 
   // Find matching process or create new one.
@@ -229,23 +229,23 @@
   trusted_pids_[uuid] = trusted_pid;
 }
 
-base::Optional<uint32_t> ProcessTracker::GetTrustedPid(uint64_t uuid) {
+std::optional<uint32_t> ProcessTracker::GetTrustedPid(uint64_t uuid) {
   if (trusted_pids_.find(uuid) == trusted_pids_.end())
-    return base::nullopt;
+    return std::nullopt;
   return trusted_pids_[uuid];
 }
 
-base::Optional<uint32_t> ProcessTracker::ResolveNamespacedTid(
+std::optional<uint32_t> ProcessTracker::ResolveNamespacedTid(
     uint32_t root_level_pid,
     uint32_t tid) {
   if (root_level_pid <= 0)  // Not a valid pid.
-    return base::nullopt;
+    return std::nullopt;
 
   // If the process doesn't run in a namespace (or traced_probes doesn't observe
-  // that), return base::nullopt as failure to resolve.
+  // that), return std::nullopt as failure to resolve.
   auto process_it = namespaced_processes_.find(root_level_pid);
   if (process_it == namespaced_processes_.end())
-    return base::nullopt;
+    return std::nullopt;
 
   // Check if it's the main thread.
   const auto& process = process_it->second;
@@ -264,11 +264,11 @@
   }
 
   // Failed to resolve or the thread isn't namespaced
-  return base::nullopt;
+  return std::nullopt;
 }
 
-UniquePid ProcessTracker::StartNewProcess(base::Optional<int64_t> timestamp,
-                                          base::Optional<uint32_t> parent_tid,
+UniquePid ProcessTracker::StartNewProcess(std::optional<int64_t> timestamp,
+                                          std::optional<uint32_t> parent_tid,
                                           uint32_t pid,
                                           StringId main_thread_name,
                                           ThreadNamePriority priority) {
@@ -311,10 +311,10 @@
 }
 
 UniquePid ProcessTracker::SetProcessMetadata(uint32_t pid,
-                                             base::Optional<uint32_t> ppid,
+                                             std::optional<uint32_t> ppid,
                                              base::StringView name,
                                              base::StringView cmdline) {
-  base::Optional<UniquePid> pupid;
+  std::optional<UniquePid> pupid;
   if (ppid.has_value()) {
     pupid = GetOrCreateProcess(ppid.value());
   }
@@ -363,7 +363,7 @@
   auto* process_table = context_->storage->mutable_process_table();
 
   UniqueTid utid = UpdateThreadName(tid, thread_name, priority);
-  base::Optional<UniquePid> opt_upid = thread_table->upid()[utid];
+  std::optional<UniquePid> opt_upid = thread_table->upid()[utid];
   if (opt_upid.has_value() && process_table->pid()[*opt_upid] == tid) {
     PERFETTO_DCHECK(thread_table->is_main_thread()[utid]);
     process_table->mutable_name()->Set(*opt_upid, thread_name);
diff --git a/src/trace_processor/importers/common/process_tracker.h b/src/trace_processor/importers/common/process_tracker.h
index 37298a6..df648c2 100644
--- a/src/trace_processor/importers/common/process_tracker.h
+++ b/src/trace_processor/importers/common/process_tracker.h
@@ -62,7 +62,7 @@
 
   // Called when a task_newtask is observed. This force the tracker to start
   // a new UTID for the thread, which is needed for TID-recycling resolution.
-  UniqueTid StartNewThread(base::Optional<int64_t> timestamp, uint32_t tid);
+  UniqueTid StartNewThread(std::optional<int64_t> timestamp, uint32_t tid);
 
   // Returns whether a thread is considered alive by the process tracker.
   bool IsThreadAlive(UniqueTid utid);
@@ -71,8 +71,8 @@
   // end the thread lifetime for the utid associated with the given tid.
   void EndThread(int64_t timestamp, uint32_t tid);
 
-  // Returns the thread utid or base::nullopt if it doesn't exist.
-  base::Optional<UniqueTid> GetThreadOrNull(uint32_t tid);
+  // Returns the thread utid or std::nullopt if it doesn't exist.
+  std::optional<UniqueTid> GetThreadOrNull(uint32_t tid);
 
   // Returns the thread utid (or creates a new entry if not present)
   UniqueTid GetOrCreateThread(uint32_t tid);
@@ -97,23 +97,23 @@
   // Associates trusted_pid with track UUID.
   void UpdateTrustedPid(uint32_t trusted_pid, uint64_t uuid);
 
-  // Returns the trusted_pid associated with the track UUID, or base::nullopt if
+  // Returns the trusted_pid associated with the track UUID, or std::nullopt if
   // not found.
-  base::Optional<uint32_t> GetTrustedPid(uint64_t uuid);
+  std::optional<uint32_t> GetTrustedPid(uint64_t uuid);
 
   // Performs namespace-local to root-level resolution of thread or process id,
   // given tid (can be root-level or namespace-local, but we don't know
   // beforehand) and root-level pid/tgid that the thread belongs to.
   // Returns the root-level thread id for tid on successful resolution;
-  // otherwise, returns base::nullopt on resolution failure, or the thread of
+  // otherwise, returns std::nullopt on resolution failure, or the thread of
   // tid isn't running in a pid namespace.
-  base::Optional<uint32_t> ResolveNamespacedTid(uint32_t root_level_pid,
-                                                uint32_t tid);
+  std::optional<uint32_t> ResolveNamespacedTid(uint32_t root_level_pid,
+                                               uint32_t tid);
 
   // Called when a task_newtask without the CLONE_THREAD flag is observed.
   // This force the tracker to start both a new UTID and a new UPID.
-  UniquePid StartNewProcess(base::Optional<int64_t> timestamp,
-                            base::Optional<uint32_t> parent_tid,
+  UniquePid StartNewProcess(std::optional<int64_t> timestamp,
+                            std::optional<uint32_t> parent_tid,
                             uint32_t pid,
                             StringId main_thread_name,
                             ThreadNamePriority priority);
@@ -122,7 +122,7 @@
   // for that pid or assigns a new one.
   // Virtual for testing.
   virtual UniquePid SetProcessMetadata(uint32_t pid,
-                                       base::Optional<uint32_t> ppid,
+                                       std::optional<uint32_t> ppid,
                                        base::StringView name,
                                        base::StringView cmdline);
 
@@ -149,9 +149,9 @@
   virtual UniquePid GetOrCreateProcess(uint32_t pid);
 
   // Returns the upid for a given pid.
-  base::Optional<UniquePid> UpidForPidForTesting(uint32_t pid) {
+  std::optional<UniquePid> UpidForPidForTesting(uint32_t pid) {
     auto it = pids_.Find(pid);
-    return it ? base::make_optional(*it) : base::nullopt;
+    return it ? std::make_optional(*it) : std::nullopt;
   }
 
   // Returns the bounds of a range that includes all UniqueTids that have the
@@ -191,10 +191,10 @@
 
  private:
   // Returns the utid of a thread having |tid| and |pid| as the parent process.
-  // pid == base::nullopt matches all processes.
-  // Returns base::nullopt if such a thread doesn't exist.
-  base::Optional<uint32_t> GetThreadOrNull(uint32_t tid,
-                                           base::Optional<uint32_t> pid);
+  // pid == std::nullopt matches all processes.
+  // Returns std::nullopt if such a thread doesn't exist.
+  std::optional<uint32_t> GetThreadOrNull(uint32_t tid,
+                                          std::optional<uint32_t> pid);
 
   // Called whenever we discover that the passed thread belongs to the passed
   // process. The |pending_assocs_| vector is scanned to see if there are any
diff --git a/src/trace_processor/importers/common/process_tracker_unittest.cc b/src/trace_processor/importers/common/process_tracker_unittest.cc
index de4102e..e4f06ce 100644
--- a/src/trace_processor/importers/common/process_tracker_unittest.cc
+++ b/src/trace_processor/importers/common/process_tracker_unittest.cc
@@ -16,8 +16,9 @@
 
 #include "src/trace_processor/importers/common/process_tracker.h"
 
+#include <optional>
+
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
 #include "src/trace_processor/importers/common/event_tracker.h"
 #include "test/gtest_and_gmock.h"
@@ -46,7 +47,7 @@
 };
 
 TEST_F(ProcessTrackerTest, PushProcess) {
-  context.process_tracker->SetProcessMetadata(1, base::nullopt, "test",
+  context.process_tracker->SetProcessMetadata(1, std::nullopt, "test",
                                               base::StringView());
   auto opt_upid = context.process_tracker->UpidForPidForTesting(1);
   ASSERT_EQ(opt_upid.value_or(-1), 1u);
@@ -65,18 +66,18 @@
 }
 
 TEST_F(ProcessTrackerTest, PushTwoProcessEntries_SamePidAndName) {
-  context.process_tracker->SetProcessMetadata(1, base::nullopt, "test",
+  context.process_tracker->SetProcessMetadata(1, std::nullopt, "test",
                                               base::StringView());
-  context.process_tracker->SetProcessMetadata(1, base::nullopt, "test",
+  context.process_tracker->SetProcessMetadata(1, std::nullopt, "test",
                                               base::StringView());
   auto opt_upid = context.process_tracker->UpidForPidForTesting(1);
   ASSERT_EQ(opt_upid.value_or(-1), 1u);
 }
 
 TEST_F(ProcessTrackerTest, PushTwoProcessEntries_DifferentPid) {
-  context.process_tracker->SetProcessMetadata(1, base::nullopt, "test",
+  context.process_tracker->SetProcessMetadata(1, std::nullopt, "test",
                                               base::StringView());
-  context.process_tracker->SetProcessMetadata(3, base::nullopt, "test",
+  context.process_tracker->SetProcessMetadata(3, std::nullopt, "test",
                                               base::StringView());
   auto opt_upid = context.process_tracker->UpidForPidForTesting(1);
   ASSERT_EQ(opt_upid.value_or(-1), 1u);
@@ -85,7 +86,7 @@
 }
 
 TEST_F(ProcessTrackerTest, AddProcessEntry_CorrectName) {
-  context.process_tracker->SetProcessMetadata(1, base::nullopt, "test",
+  context.process_tracker->SetProcessMetadata(1, std::nullopt, "test",
                                               base::StringView());
   auto name = context.storage->process_table().name().GetString(1);
 
@@ -108,12 +109,12 @@
 
 TEST_F(ProcessTrackerTest, PidReuseWithoutStartAndEndThread) {
   UniquePid p1 = context.process_tracker->StartNewProcess(
-      base::nullopt, base::nullopt, /*pid=*/1, kNullStringId,
+      std::nullopt, std::nullopt, /*pid=*/1, kNullStringId,
       ThreadNamePriority::kFtrace);
   UniqueTid t1 = context.process_tracker->UpdateThread(/*tid=*/2, /*pid=*/1);
 
   UniquePid p2 = context.process_tracker->StartNewProcess(
-      base::nullopt, base::nullopt, /*pid=*/1, kNullStringId,
+      std::nullopt, std::nullopt, /*pid=*/1, kNullStringId,
       ThreadNamePriority::kFtrace);
   UniqueTid t2 = context.process_tracker->UpdateThread(/*tid=*/2, /*pid=*/1);
 
@@ -128,7 +129,7 @@
 
 TEST_F(ProcessTrackerTest, Cmdline) {
   UniquePid upid = context.process_tracker->SetProcessMetadata(
-      1, base::nullopt, "test", "cmdline blah");
+      1, std::nullopt, "test", "cmdline blah");
   ASSERT_EQ(context.storage->process_table().cmdline().GetString(upid),
             "cmdline blah");
 }
@@ -158,7 +159,7 @@
 
 TEST_F(ProcessTrackerTest, SetStartTsIfUnset) {
   auto upid = context.process_tracker->StartNewProcess(
-      /*timestamp=*/base::nullopt, 0u, 123, kNullStringId,
+      /*timestamp=*/std::nullopt, 0u, 123, kNullStringId,
       ThreadNamePriority::kFtrace);
   context.process_tracker->SetStartTsIfUnset(upid, 1000);
   ASSERT_EQ(context.storage->process_table().start_ts()[upid], 1000);
@@ -188,7 +189,7 @@
 
 TEST_F(ProcessTrackerTest, EndThreadAfterProcessEnd) {
   context.process_tracker->StartNewProcess(
-      100, base::nullopt, 123, kNullStringId, ThreadNamePriority::kFtrace);
+      100, std::nullopt, 123, kNullStringId, ThreadNamePriority::kFtrace);
   context.process_tracker->UpdateThread(124, 123);
 
   context.process_tracker->EndThread(200, 123);
@@ -237,7 +238,7 @@
 
   // Don't resolve if the process/thread isn't namespaced.
   ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(2001, 2002),
-            base::nullopt);
+            std::nullopt);
 
   // Resolve from namespace-local PID to root-level PID.
   ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1001, 1).value(),
diff --git a/src/trace_processor/importers/common/slice_tracker.cc b/src/trace_processor/importers/common/slice_tracker.cc
index 9f93fac..5f3af01 100644
--- a/src/trace_processor/importers/common/slice_tracker.cc
+++ b/src/trace_processor/importers/common/slice_tracker.cc
@@ -38,11 +38,11 @@
 
 SliceTracker::~SliceTracker() = default;
 
-base::Optional<SliceId> SliceTracker::Begin(int64_t timestamp,
-                                            TrackId track_id,
-                                            StringId category,
-                                            StringId raw_name,
-                                            SetArgsCallback args_callback) {
+std::optional<SliceId> SliceTracker::Begin(int64_t timestamp,
+                                           TrackId track_id,
+                                           StringId category,
+                                           StringId raw_name,
+                                           SetArgsCallback args_callback) {
   const StringId name =
       context_->slice_translation_table->TranslateName(raw_name);
   tables::SliceTable::Row row(timestamp, kPendingDuration, track_id, category,
@@ -77,12 +77,12 @@
   });
 }
 
-base::Optional<SliceId> SliceTracker::Scoped(int64_t timestamp,
-                                             TrackId track_id,
-                                             StringId category,
-                                             StringId raw_name,
-                                             int64_t duration,
-                                             SetArgsCallback args_callback) {
+std::optional<SliceId> SliceTracker::Scoped(int64_t timestamp,
+                                            TrackId track_id,
+                                            StringId category,
+                                            StringId raw_name,
+                                            int64_t duration,
+                                            SetArgsCallback args_callback) {
   PERFETTO_DCHECK(duration >= 0);
 
   const StringId name =
@@ -93,11 +93,11 @@
   });
 }
 
-base::Optional<SliceId> SliceTracker::End(int64_t timestamp,
-                                          TrackId track_id,
-                                          StringId category,
-                                          StringId raw_name,
-                                          SetArgsCallback args_callback) {
+std::optional<SliceId> SliceTracker::End(int64_t timestamp,
+                                         TrackId track_id,
+                                         StringId category,
+                                         StringId raw_name,
+                                         SetArgsCallback args_callback) {
   const StringId name =
       context_->slice_translation_table->TranslateName(raw_name);
   auto finder = [this, category, name](const SlicesStack& stack) {
@@ -106,23 +106,23 @@
   return CompleteSlice(timestamp, track_id, args_callback, finder);
 }
 
-base::Optional<uint32_t> SliceTracker::AddArgs(TrackId track_id,
-                                               StringId category,
-                                               StringId name,
-                                               SetArgsCallback args_callback) {
+std::optional<uint32_t> SliceTracker::AddArgs(TrackId track_id,
+                                              StringId category,
+                                              StringId name,
+                                              SetArgsCallback args_callback) {
   auto* it = stacks_.Find(track_id);
   if (!it)
-    return base::nullopt;
+    return std::nullopt;
 
   auto& stack = it->slice_stack;
   if (stack.empty())
-    return base::nullopt;
+    return std::nullopt;
 
   auto* slices = context_->storage->mutable_slice_table();
-  base::Optional<uint32_t> stack_idx =
+  std::optional<uint32_t> stack_idx =
       MatchingIncompleteSliceIndex(stack, name, category);
   if (!stack_idx.has_value())
-    return base::nullopt;
+    return std::nullopt;
 
   tables::SliceTable::RowNumber num = stack[*stack_idx].row;
   tables::SliceTable::RowReference ref = num.ToRowReference(slices);
@@ -135,7 +135,7 @@
   return num.row_number();
 }
 
-base::Optional<SliceId> SliceTracker::StartSlice(
+std::optional<SliceId> SliceTracker::StartSlice(
     int64_t timestamp,
     TrackId track_id,
     SetArgsCallback args_callback,
@@ -143,7 +143,7 @@
   // At this stage all events should be globally timestamp ordered.
   if (timestamp < prev_timestamp_) {
     context_->storage->IncrementStats(stats::slice_out_of_order);
-    return base::nullopt;
+    return std::nullopt;
   }
   prev_timestamp_ = timestamp;
 
@@ -159,7 +159,7 @@
     // If this is an unnestable track, don't start a new slice if one already
     // exists.
     if (!stack.empty()) {
-      return base::nullopt;
+      return std::nullopt;
     }
   }
 
@@ -168,12 +168,12 @@
 
   size_t depth = stack.size();
 
-  base::Optional<tables::SliceTable::RowReference> parent_ref =
-      depth == 0 ? base::nullopt
-                 : base::make_optional(stack.back().row.ToRowReference(slices));
+  std::optional<tables::SliceTable::RowReference> parent_ref =
+      depth == 0 ? std::nullopt
+                 : std::make_optional(stack.back().row.ToRowReference(slices));
   int64_t parent_stack_id = parent_ref ? parent_ref->stack_id() : 0;
-  base::Optional<tables::SliceTable::Id> parent_id =
-      parent_ref ? base::make_optional(parent_ref->id()) : base::nullopt;
+  std::optional<tables::SliceTable::Id> parent_id =
+      parent_ref ? std::make_optional(parent_ref->id()) : std::nullopt;
 
   SliceId id = inserter();
   tables::SliceTable::RowReference ref = *slices->FindById(id);
@@ -185,7 +185,7 @@
     PERFETTO_DLOG("Last slice: %s", parent_name.c_str());
     PERFETTO_DLOG("Current slice: %s", name.c_str());
     PERFETTO_DFATAL("Slices with too large depth found.");
-    return base::nullopt;
+    return std::nullopt;
   }
   StackPush(track_id, ref);
 
@@ -204,35 +204,35 @@
   return id;
 }
 
-base::Optional<SliceId> SliceTracker::CompleteSlice(
+std::optional<SliceId> SliceTracker::CompleteSlice(
     int64_t timestamp,
     TrackId track_id,
     SetArgsCallback args_callback,
-    std::function<base::Optional<uint32_t>(const SlicesStack&)> finder) {
+    std::function<std::optional<uint32_t>(const SlicesStack&)> finder) {
   // At this stage all events should be globally timestamp ordered.
   if (timestamp < prev_timestamp_) {
     context_->storage->IncrementStats(stats::slice_out_of_order);
-    return base::nullopt;
+    return std::nullopt;
   }
   prev_timestamp_ = timestamp;
 
   auto it = stacks_.Find(track_id);
   if (!it)
-    return base::nullopt;
+    return std::nullopt;
 
   TrackInfo& track_info = *it;
   SlicesStack& stack = track_info.slice_stack;
   MaybeCloseStack(timestamp, stack, track_id);
   if (stack.empty())
-    return base::nullopt;
+    return std::nullopt;
 
   auto* slices = context_->storage->mutable_slice_table();
-  base::Optional<uint32_t> stack_idx = finder(stack);
+  std::optional<uint32_t> stack_idx = finder(stack);
 
   // If we are trying to close slices that are not open on the stack (e.g.,
   // slices that began before tracing started), bail out.
   if (!stack_idx)
-    return base::nullopt;
+    return std::nullopt;
 
   const auto& slice_info = stack[stack_idx.value()];
 
@@ -266,8 +266,8 @@
 
 // Returns the first incomplete slice in the stack with matching name and
 // category. We assume null category/name matches everything. Returns
-// nullopt if no matching slice is found.
-base::Optional<uint32_t> SliceTracker::MatchingIncompleteSliceIndex(
+// std::nullopt if no matching slice is found.
+std::optional<uint32_t> SliceTracker::MatchingIncompleteSliceIndex(
     const SlicesStack& stack,
     StringId name,
     StringId category) {
@@ -277,19 +277,19 @@
         stack[static_cast<size_t>(i)].row.ToRowReference(slices);
     if (ref.dur() != kPendingDuration)
       continue;
-    base::Optional<StringId> other_category = ref.category();
+    std::optional<StringId> other_category = ref.category();
     if (!category.is_null() && (!other_category || other_category->is_null() ||
                                 category != other_category)) {
       continue;
     }
-    base::Optional<StringId> other_name = ref.name();
+    std::optional<StringId> other_name = ref.name();
     if (!name.is_null() && other_name && !other_name->is_null() &&
         name != other_name) {
       continue;
     }
     return static_cast<uint32_t>(i);
   }
-  return base::nullopt;
+  return std::nullopt;
 }
 
 void SliceTracker::MaybeAddTranslatableArgs(SliceInfo& slice_info) {
@@ -339,14 +339,14 @@
   on_slice_begin_callback_ = callback;
 }
 
-base::Optional<SliceId> SliceTracker::GetTopmostSliceOnTrack(
+std::optional<SliceId> SliceTracker::GetTopmostSliceOnTrack(
     TrackId track_id) const {
   const auto* iter = stacks_.Find(track_id);
   if (!iter)
-    return base::nullopt;
+    return std::nullopt;
   const auto& stack = iter->slice_stack;
   if (stack.empty())
-    return base::nullopt;
+    return std::nullopt;
   const auto& slice = context_->storage->slice_table();
   return stack.back().row.ToRowReference(slice).id();
 }
diff --git a/src/trace_processor/importers/common/slice_tracker.h b/src/trace_processor/importers/common/slice_tracker.h
index b2bdebd..f0f59da 100644
--- a/src/trace_processor/importers/common/slice_tracker.h
+++ b/src/trace_processor/importers/common/slice_tracker.h
@@ -39,7 +39,7 @@
   virtual ~SliceTracker();
 
   // virtual for testing
-  virtual base::Optional<SliceId> Begin(
+  virtual std::optional<SliceId> Begin(
       int64_t timestamp,
       TrackId track_id,
       StringId category,
@@ -56,7 +56,7 @@
                              SetArgsCallback args_callback);
 
   template <typename Table>
-  base::Optional<SliceId> BeginTyped(
+  std::optional<SliceId> BeginTyped(
       Table* table,
       typename Table::Row row,
       SetArgsCallback args_callback = SetArgsCallback()) {
@@ -70,7 +70,7 @@
   }
 
   // virtual for testing
-  virtual base::Optional<SliceId> Scoped(
+  virtual std::optional<SliceId> Scoped(
       int64_t timestamp,
       TrackId track_id,
       StringId category,
@@ -79,7 +79,7 @@
       SetArgsCallback args_callback = SetArgsCallback());
 
   template <typename Table>
-  base::Optional<SliceId> ScopedTyped(
+  std::optional<SliceId> ScopedTyped(
       Table* table,
       typename Table::Row row,
       SetArgsCallback args_callback = SetArgsCallback()) {
@@ -92,7 +92,7 @@
   }
 
   // virtual for testing
-  virtual base::Optional<SliceId> End(
+  virtual std::optional<SliceId> End(
       int64_t timestamp,
       TrackId track_id,
       StringId opt_category = {},
@@ -102,16 +102,16 @@
   // Usually args should be added in the Begin or End args_callback but this
   // method is for the situation where new args need to be added to an
   // in-progress slice.
-  base::Optional<uint32_t> AddArgs(TrackId track_id,
-                                   StringId category,
-                                   StringId name,
-                                   SetArgsCallback args_callback);
+  std::optional<uint32_t> AddArgs(TrackId track_id,
+                                  StringId category,
+                                  StringId name,
+                                  SetArgsCallback args_callback);
 
   void FlushPendingSlices();
 
   void SetOnSliceBeginCallback(OnSliceBeginCallback callback);
 
-  base::Optional<SliceId> GetTopmostSliceOnTrack(TrackId track_id) const;
+  std::optional<SliceId> GetTopmostSliceOnTrack(TrackId track_id) const;
 
  private:
   // Slices which have been opened but haven't been closed yet will be marked
@@ -141,23 +141,22 @@
   };
 
   // virtual for testing.
-  virtual base::Optional<SliceId> StartSlice(int64_t timestamp,
-                                             TrackId track_id,
-                                             SetArgsCallback args_callback,
-                                             std::function<SliceId()> inserter);
+  virtual std::optional<SliceId> StartSlice(int64_t timestamp,
+                                            TrackId track_id,
+                                            SetArgsCallback args_callback,
+                                            std::function<SliceId()> inserter);
 
-  base::Optional<SliceId> CompleteSlice(
+  std::optional<SliceId> CompleteSlice(
       int64_t timestamp,
       TrackId track_id,
       SetArgsCallback args_callback,
-      std::function<base::Optional<uint32_t>(const SlicesStack&)> finder);
+      std::function<std::optional<uint32_t>(const SlicesStack&)> finder);
 
   void MaybeCloseStack(int64_t end_ts, const SlicesStack&, TrackId track_id);
 
-  base::Optional<uint32_t> MatchingIncompleteSliceIndex(
-      const SlicesStack& stack,
-      StringId name,
-      StringId category);
+  std::optional<uint32_t> MatchingIncompleteSliceIndex(const SlicesStack& stack,
+                                                       StringId name,
+                                                       StringId category);
 
   int64_t GetStackHash(const SlicesStack&);
 
diff --git a/src/trace_processor/importers/common/slice_tracker_unittest.cc b/src/trace_processor/importers/common/slice_tracker_unittest.cc
index 5b8d37d..ab214eb 100644
--- a/src/trace_processor/importers/common/slice_tracker_unittest.cc
+++ b/src/trace_processor/importers/common/slice_tracker_unittest.cc
@@ -322,7 +322,7 @@
   SliceId parent = context.storage->slice_table().id()[0];
   SliceId child = context.storage->slice_table().id()[1];
   EXPECT_THAT(context.storage->slice_table().parent_id().ToVectorForTesting(),
-              ElementsAre(base::nullopt, parent, child));
+              ElementsAre(std::nullopt, parent, child));
 }
 
 TEST(SliceTrackerTest, IgnoreMismatchedEnds) {
@@ -460,7 +460,7 @@
   TrackId track{1u};
   TrackId track2{2u};
 
-  EXPECT_EQ(tracker.GetTopmostSliceOnTrack(track), base::nullopt);
+  EXPECT_EQ(tracker.GetTopmostSliceOnTrack(track), std::nullopt);
 
   tracker.Begin(100, track, StringId::Raw(11), StringId::Raw(11));
   SliceId slice1 = context.storage->slice_table().id()[0];
@@ -472,7 +472,7 @@
 
   EXPECT_EQ(tracker.GetTopmostSliceOnTrack(track).value(), slice2);
 
-  EXPECT_EQ(tracker.GetTopmostSliceOnTrack(track2), base::nullopt);
+  EXPECT_EQ(tracker.GetTopmostSliceOnTrack(track2), std::nullopt);
 
   tracker.End(140, track, StringId::Raw(22), StringId::Raw(22));
 
@@ -480,7 +480,7 @@
 
   tracker.End(330, track, StringId::Raw(11), StringId::Raw(11));
 
-  EXPECT_EQ(tracker.GetTopmostSliceOnTrack(track), base::nullopt);
+  EXPECT_EQ(tracker.GetTopmostSliceOnTrack(track), std::nullopt);
 }
 
 TEST(SliceTrackerTest, OnSliceBeginCallback) {
diff --git a/src/trace_processor/importers/common/system_info_tracker.cc b/src/trace_processor/importers/common/system_info_tracker.cc
index f8c1007..89f0baf 100644
--- a/src/trace_processor/importers/common/system_info_tracker.cc
+++ b/src/trace_processor/importers/common/system_info_tracker.cc
@@ -26,7 +26,7 @@
 void SystemInfoTracker::SetKernelVersion(base::StringView name,
                                          base::StringView release) {
   if (name.empty() || release.empty() || name != "Linux") {
-    version_ = base::nullopt;
+    version_ = std::nullopt;
     return;
   }
 
diff --git a/src/trace_processor/importers/common/system_info_tracker.h b/src/trace_processor/importers/common/system_info_tracker.h
index af108c5..d9544d1 100644
--- a/src/trace_processor/importers/common/system_info_tracker.h
+++ b/src/trace_processor/importers/common/system_info_tracker.h
@@ -17,7 +17,8 @@
 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_SYSTEM_INFO_TRACKER_H_
 #define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_SYSTEM_INFO_TRACKER_H_
 
-#include "perfetto/ext/base/optional.h"
+#include <optional>
+
 #include "perfetto/ext/base/string_view.h"
 #include "src/trace_processor/types/destructible.h"
 #include "src/trace_processor/types/trace_processor_context.h"
@@ -42,12 +43,12 @@
 
   void SetKernelVersion(base::StringView name, base::StringView release);
 
-  base::Optional<VersionNumber> GetKernelVersion() { return version_; }
+  std::optional<VersionNumber> GetKernelVersion() { return version_; }
 
  private:
   explicit SystemInfoTracker();
 
-  base::Optional<VersionNumber> version_;
+  std::optional<VersionNumber> version_;
 };
 }  // namespace trace_processor
 }  // namespace perfetto
diff --git a/src/trace_processor/importers/common/track_tracker.h b/src/trace_processor/importers/common/track_tracker.h
index f172148..c4a4232 100644
--- a/src/trace_processor/importers/common/track_tracker.h
+++ b/src/trace_processor/importers/common/track_tracker.h
@@ -145,7 +145,7 @@
     }
   };
   struct ChromeTrackTuple {
-    base::Optional<int64_t> upid;
+    std::optional<int64_t> upid;
     int64_t source_id = 0;
     StringId source_scope = StringId::Null();
 
@@ -178,8 +178,8 @@
   std::map<std::pair<StringId, int32_t>, TrackId>
       energy_per_uid_counter_tracks_;
 
-  base::Optional<TrackId> chrome_global_instant_track_id_;
-  base::Optional<TrackId> trigger_track_id_;
+  std::optional<TrackId> chrome_global_instant_track_id_;
+  std::optional<TrackId> trigger_track_id_;
 
   const StringId source_key_ = kNullStringId;
   const StringId source_id_key_ = kNullStringId;
diff --git a/src/trace_processor/importers/ftrace/binder_tracker.cc b/src/trace_processor/importers/ftrace/binder_tracker.cc
index 5e95579..7133c1f 100644
--- a/src/trace_processor/importers/ftrace/binder_tracker.cc
+++ b/src/trace_processor/importers/ftrace/binder_tracker.cc
@@ -170,7 +170,7 @@
     return;
   }
 
-  base::Optional<SliceId> recv_slice_id;
+  std::optional<SliceId> recv_slice_id;
   if (transaction.is_oneway) {
     recv_slice_id = context_->slice_tracker->Scoped(
         ts, track_id, binder_category_id_, async_rcv_id_, 0,
diff --git a/src/trace_processor/importers/ftrace/binder_tracker.h b/src/trace_processor/importers/ftrace/binder_tracker.h
index aa710e3..b17990a 100644
--- a/src/trace_processor/importers/ftrace/binder_tracker.h
+++ b/src/trace_processor/importers/ftrace/binder_tracker.h
@@ -18,10 +18,10 @@
 #define SRC_TRACE_PROCESSOR_IMPORTERS_FTRACE_BINDER_TRACKER_H_
 
 #include <stdint.h>
+#include <optional>
 
 #include "perfetto/base/flat_set.h"
 #include "perfetto/ext/base/flat_hash_map.h"
-#include "perfetto/ext/base/optional.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
 #include "src/trace_processor/storage/trace_storage.h"
 #include "src/trace_processor/types/destructible.h"
@@ -72,8 +72,8 @@
     bool is_reply = false;
     bool is_oneway = false;
     SetArgsCallback args_inserter;
-    base::Optional<TrackId> send_track_id;
-    base::Optional<SliceId> send_slice_id;
+    std::optional<TrackId> send_track_id;
+    std::optional<SliceId> send_slice_id;
   };
 
   TraceProcessorContext* const context_;
diff --git a/src/trace_processor/importers/ftrace/drm_tracker.cc b/src/trace_processor/importers/ftrace/drm_tracker.cc
index ebe5b31..003b827 100644
--- a/src/trace_processor/importers/ftrace/drm_tracker.cc
+++ b/src/trace_processor/importers/ftrace/drm_tracker.cc
@@ -184,7 +184,7 @@
     inserter->AddArg(sched_arg_job_id_, Variadic::UnsignedInteger(job_id));
   };
 
-  base::Optional<SliceId> slice_id =
+  std::optional<SliceId> slice_id =
       context_->slice_tracker->Begin(timestamp, ring.track_id, kNullStringId,
                                      sched_slice_job_id_, args_inserter);
 
@@ -210,7 +210,7 @@
     inserter->AddArg(sched_arg_job_id_, Variadic::UnsignedInteger(job_id));
   };
 
-  base::Optional<SliceId> slice_id = context_->slice_tracker->Scoped(
+  std::optional<SliceId> slice_id = context_->slice_tracker->Scoped(
       timestamp, track_id, kNullStringId, sched_slice_schedule_id_, 0,
       args_inserter);
 
diff --git a/src/trace_processor/importers/ftrace/ftrace_parser.cc b/src/trace_processor/importers/ftrace/ftrace_parser.cc
index 7033130..29af4bc 100644
--- a/src/trace_processor/importers/ftrace/ftrace_parser.cc
+++ b/src/trace_processor/importers/ftrace/ftrace_parser.cc
@@ -22,6 +22,7 @@
 #include "perfetto/protozero/proto_decoder.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
 #include "src/trace_processor/importers/common/async_track_set_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/importers/common/parser_types.h"
 #include "src/trace_processor/importers/common/process_tracker.h"
 #include "src/trace_processor/importers/ftrace/binder_tracker.h"
@@ -29,7 +30,6 @@
 #include "src/trace_processor/importers/ftrace/v4l2_tracker.h"
 #include "src/trace_processor/importers/ftrace/virtio_video_tracker.h"
 #include "src/trace_processor/importers/i2c/i2c_tracker.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
 #include "src/trace_processor/importers/proto/packet_sequence_state.h"
 #include "src/trace_processor/importers/syscalls/syscall_tracker.h"
 #include "src/trace_processor/importers/systrace/systrace_parser.h"
@@ -1079,7 +1079,7 @@
               ? metadata::all_data_source_started_ns
               : metadata::tracing_started_ns;
       const auto& metadata = context_->storage->metadata_table();
-      base::Optional<uint32_t> opt_row =
+      std::optional<uint32_t> opt_row =
           metadata.name().IndexOf(metadata::kNames[event_key]);
       if (opt_row) {
         drop_ftrace_data_before_ts_ = *metadata.int_value()[*opt_row];
@@ -1304,7 +1304,7 @@
   // [wr][atrace_slice..]
   // ...............[wri]
   //
-  base::Optional<UniqueTid> opt_utid =
+  std::optional<UniqueTid> opt_utid =
       context_->process_tracker->GetThreadOrNull(pid);
   if (opt_utid) {
     SyscallTracker::GetOrCreate(context_)->MaybeTruncateOngoingWriteSlice(
@@ -1403,7 +1403,6 @@
       evt.func_name(), tgid, evt.value());
 }
 
-
 /** Parses ion heap events present in Pixel kernels. */
 void FtraceParser::ParseIonHeapGrowOrShrink(int64_t timestamp,
                                             uint32_t pid,
@@ -1717,7 +1716,8 @@
                                        ThreadNamePriority::kFtrace);
   proc_tracker->AssociateThreads(source_utid, new_utid);
 
-  ThreadStateTracker::GetOrCreate(context_)->PushNewTaskEvent(timestamp, new_utid, source_utid);
+  ThreadStateTracker::GetOrCreate(context_)->PushNewTaskEvent(
+      timestamp, new_utid, source_utid);
 }
 
 void FtraceParser::ParseTaskRename(ConstBytes blob) {
@@ -1842,7 +1842,7 @@
 }
 
 void FtraceParser::ParseCmaAllocStart(int64_t timestamp, uint32_t pid) {
-  base::Optional<VersionNumber> kernel_version =
+  std::optional<VersionNumber> kernel_version =
       SystemInfoTracker::GetOrCreate(context_)->GetKernelVersion();
   // CmaAllocInfo event only exists after 5.10
   if (kernel_version < VersionNumber{5, 10})
@@ -1858,7 +1858,7 @@
 void FtraceParser::ParseCmaAllocInfo(int64_t timestamp,
                                      uint32_t pid,
                                      ConstBytes blob) {
-  base::Optional<VersionNumber> kernel_version =
+  std::optional<VersionNumber> kernel_version =
       SystemInfoTracker::GetOrCreate(context_)->GetKernelVersion();
   // CmaAllocInfo event only exists after 5.10
   if (kernel_version < VersionNumber{5, 10})
@@ -2098,7 +2098,7 @@
     // the event as otherwise we would create fake processes which we
     // definitely want to avoid.
     // See b/192274404 for more info.
-    base::Optional<UniqueTid> opt_utid =
+    std::optional<UniqueTid> opt_utid =
         context_->process_tracker->GetThreadOrNull(pid);
     if (!opt_utid)
       return;
@@ -2156,7 +2156,7 @@
       protos::pbzero::InternedData::kKernelSymbolsFieldNumber,
       protos::pbzero::InternedString>(caller_iid);
 
-  base::Optional<StringId> blocked_function_str_id = base::nullopt;
+  std::optional<StringId> blocked_function_str_id = std::nullopt;
   if (interned_string) {
     protozero::ConstBytes str = interned_string->str();
     blocked_function_str_id = context_->storage->InternString(
@@ -2226,7 +2226,7 @@
 
   uint64_t nic_received_kilobytes = nic_received_bytes_[name] / 1024;
   TrackId track = context_->track_tracker->InternGlobalCounterTrack(name);
-  base::Optional<CounterId> id = context_->event_tracker->PushCounter(
+  std::optional<CounterId> id = context_->event_tracker->PushCounter(
       timestamp, static_cast<double>(nic_received_kilobytes), track);
   if (!id) {
     return;
@@ -2257,7 +2257,7 @@
 
   uint64_t nic_transmitted_kilobytes = nic_transmitted_bytes_[name] / 1024;
   TrackId track = context_->track_tracker->InternGlobalCounterTrack(name);
-  base::Optional<CounterId> id = context_->event_tracker->PushCounter(
+  std::optional<CounterId> id = context_->event_tracker->PushCounter(
       timestamp, static_cast<double>(nic_transmitted_kilobytes), track);
   if (!id) {
     return;
@@ -2416,7 +2416,7 @@
 
   TrackId track =
       context_->track_tracker->InternGlobalCounterTrack(kfree_skb_name_id_);
-  base::Optional<CounterId> id = context_->event_tracker->PushCounter(
+  std::optional<CounterId> id = context_->event_tracker->PushCounter(
       timestamp, static_cast<double>(num_of_kfree_skb_ip_prot), track);
   if (!id) {
     return;
diff --git a/src/trace_processor/importers/ftrace/rss_stat_tracker.cc b/src/trace_processor/importers/ftrace/rss_stat_tracker.cc
index 80ca10f..faebf94 100644
--- a/src/trace_processor/importers/ftrace/rss_stat_tracker.cc
+++ b/src/trace_processor/importers/ftrace/rss_stat_tracker.cc
@@ -47,8 +47,8 @@
                                   ConstBytes blob) {
   uint32_t member;
   int64_t size;
-  base::Optional<bool> curr;
-  base::Optional<int64_t> mm_id;
+  std::optional<bool> curr;
+  std::optional<int64_t> mm_id;
 
   if (field_id == FtraceEvent::kRssStatFieldNumber) {
     protos::pbzero::RssStatFtraceEvent::Decoder rss(blob.data, blob.size);
@@ -56,10 +56,10 @@
     member = static_cast<uint32_t>(rss.member());
     size = rss.size();
     if (rss.has_curr()) {
-      curr = base::make_optional(static_cast<bool>(rss.curr()));
+      curr = std::make_optional(static_cast<bool>(rss.curr()));
     }
     if (rss.has_mm_id()) {
-      mm_id = base::make_optional(rss.mm_id());
+      mm_id = std::make_optional(rss.mm_id());
     }
 
     ParseRssStat(ts, pid, size, member, curr, mm_id);
@@ -69,8 +69,8 @@
 
     member = static_cast<uint32_t>(rss.member());
     size = rss.size();
-    curr = base::make_optional(static_cast<bool>(rss.curr()));
-    mm_id = base::make_optional(rss.mm_id());
+    curr = std::make_optional(static_cast<bool>(rss.curr()));
+    mm_id = std::make_optional(rss.mm_id());
 
     ParseRssStat(ts, pid, size, member, curr, mm_id);
   } else {
@@ -82,8 +82,8 @@
                                   uint32_t pid,
                                   int64_t size,
                                   uint32_t member,
-                                  base::Optional<bool> curr,
-                                  base::Optional<int64_t> mm_id) {
+                                  std::optional<bool> curr,
+                                  std::optional<int64_t> mm_id) {
   const auto kRssStatUnknown = static_cast<uint32_t>(rss_members_.size()) - 1;
   if (member >= rss_members_.size()) {
     context_->storage->IncrementStats(stats::rss_stat_unknown_keys);
@@ -95,7 +95,7 @@
     return;
   }
 
-  base::Optional<UniqueTid> utid;
+  std::optional<UniqueTid> utid;
   if (mm_id.has_value() && curr.has_value()) {
     utid = FindUtidForMmId(*mm_id, *curr, pid);
   } else {
@@ -110,9 +110,9 @@
   }
 }
 
-base::Optional<UniqueTid> RssStatTracker::FindUtidForMmId(int64_t mm_id,
-                                                          bool is_curr,
-                                                          uint32_t pid) {
+std::optional<UniqueTid> RssStatTracker::FindUtidForMmId(int64_t mm_id,
+                                                         bool is_curr,
+                                                         uint32_t pid) {
   // If curr is true, we can just overwrite the state in the map and return
   // the utid correspodning to |pid|.
   if (is_curr) {
@@ -125,7 +125,7 @@
   // mm id.
   auto* it = mm_id_to_utid_.Find(mm_id);
   if (!it)
-    return base::nullopt;
+    return std::nullopt;
 
   // If the utid in the map is the same as our current utid but curr is false,
   // that means we are in the middle of a process changing mm structs (i.e. in
@@ -135,7 +135,7 @@
   const UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
   if (mm_utid == utid) {
     mm_id_to_utid_.Erase(mm_id);
-    return base::nullopt;
+    return std::nullopt;
   }
 
   // Verify that the utid in the map is still alive. This can happen if an mm
@@ -143,7 +143,7 @@
   // know the new process that struct will be associated with.
   if (!context_->process_tracker->IsThreadAlive(mm_utid)) {
     mm_id_to_utid_.Erase(mm_id);
-    return base::nullopt;
+    return std::nullopt;
   }
 
   // This case happens when a process is changing the VM of another process and
diff --git a/src/trace_processor/importers/ftrace/rss_stat_tracker.h b/src/trace_processor/importers/ftrace/rss_stat_tracker.h
index b3ba29a..7139d6c 100644
--- a/src/trace_processor/importers/ftrace/rss_stat_tracker.h
+++ b/src/trace_processor/importers/ftrace/rss_stat_tracker.h
@@ -40,13 +40,13 @@
                     uint32_t pid,
                     int64_t size,
                     uint32_t member,
-                    base::Optional<bool> curr,
-                    base::Optional<int64_t> mm_id);
+                    std::optional<bool> curr,
+                    std::optional<int64_t> mm_id);
 
  private:
-  base::Optional<UniqueTid> FindUtidForMmId(int64_t mm_id,
-                                            bool is_curr,
-                                            uint32_t pid);
+  std::optional<UniqueTid> FindUtidForMmId(int64_t mm_id,
+                                           bool is_curr,
+                                           uint32_t pid);
 
   base::FlatHashMap<int64_t, UniqueTid> mm_id_to_utid_;
   std::vector<StringId> rss_members_;
diff --git a/src/trace_processor/importers/ftrace/sched_event_tracker.cc b/src/trace_processor/importers/ftrace/sched_event_tracker.cc
index 3ee1fa1..f67e571 100644
--- a/src/trace_processor/importers/ftrace/sched_event_tracker.cc
+++ b/src/trace_processor/importers/ftrace/sched_event_tracker.cc
@@ -313,7 +313,7 @@
 StringId SchedEventTracker::TaskStateToStringId(int64_t task_state_int) {
   using ftrace_utils::TaskState;
 
-  base::Optional<VersionNumber> kernel_version =
+  std::optional<VersionNumber> kernel_version =
       SystemInfoTracker::GetOrCreate(context_)->GetKernelVersion();
   TaskState task_state = TaskState::FromRawPrevState(
       static_cast<uint16_t>(task_state_int), kernel_version);
diff --git a/src/trace_processor/importers/ftrace/sched_event_tracker_unittest.cc b/src/trace_processor/importers/ftrace/sched_event_tracker_unittest.cc
index 22b1139..5d275d6 100644
--- a/src/trace_processor/importers/ftrace/sched_event_tracker_unittest.cc
+++ b/src/trace_processor/importers/ftrace/sched_event_tracker_unittest.cc
@@ -68,7 +68,7 @@
 
   const auto& timestamps = context.storage->sched_slice_table().ts();
   ASSERT_EQ(timestamps[0], timestamp);
-  ASSERT_EQ(context.storage->thread_table().start_ts()[1], base::nullopt);
+  ASSERT_EQ(context.storage->thread_table().start_ts()[1], std::nullopt);
 
   auto name = context.storage->thread_table().name().GetString(1);
   ASSERT_STREQ(name.c_str(), kCommProc1);
@@ -102,7 +102,7 @@
 
   const auto& timestamps = context.storage->sched_slice_table().ts();
   ASSERT_EQ(timestamps[0], timestamp);
-  ASSERT_EQ(context.storage->thread_table().start_ts()[1], base::nullopt);
+  ASSERT_EQ(context.storage->thread_table().start_ts()[1], std::nullopt);
   ASSERT_EQ(context.storage->sched_slice_table().dur()[0], 1u);
   ASSERT_EQ(context.storage->sched_slice_table().dur()[1], 11u - 1u);
   ASSERT_EQ(context.storage->sched_slice_table().dur()[2], 31u - 11u);
@@ -125,14 +125,14 @@
                                  prio, prev_state,
                                  /*tid=*/1, kCommProc2, prio);
 
-  context.process_tracker->SetProcessMetadata(2, base::nullopt, "test",
+  context.process_tracker->SetProcessMetadata(2, std::nullopt, "test",
                                               base::StringView());
   context.process_tracker->UpdateThread(4, 2);
 
   ASSERT_EQ(context.storage->thread_table().tid()[1], 4u);
   ASSERT_EQ(context.storage->thread_table().upid()[1].value(), 1u);
   ASSERT_EQ(context.storage->process_table().pid()[1], 2u);
-  ASSERT_EQ(context.storage->process_table().start_ts()[1], base::nullopt);
+  ASSERT_EQ(context.storage->process_table().start_ts()[1], std::nullopt);
 }
 
 }  // namespace
diff --git a/src/trace_processor/importers/ftrace/thread_state_tracker.cc b/src/trace_processor/importers/ftrace/thread_state_tracker.cc
index 227a90a..3c6b123 100644
--- a/src/trace_processor/importers/ftrace/thread_state_tracker.cc
+++ b/src/trace_processor/importers/ftrace/thread_state_tracker.cc
@@ -67,19 +67,19 @@
 
   // Close the sleeping state and open runnable state.
   ClosePendingState(event_ts, utid, false);
-  AddOpenState(event_ts, utid, runnable_string_id_, base::nullopt, waker_utid);
+  AddOpenState(event_ts, utid, runnable_string_id_, std::nullopt, waker_utid);
 }
 
 void ThreadStateTracker::PushNewTaskEvent(int64_t event_ts,
                                          UniqueTid utid,
                                          UniqueTid waker_utid) {
-  AddOpenState(event_ts, utid, runnable_string_id_, base::nullopt, waker_utid);
+  AddOpenState(event_ts, utid, runnable_string_id_, std::nullopt, waker_utid);
 }
 
 void ThreadStateTracker::PushBlockedReason(
     UniqueTid utid,
-    base::Optional<bool> io_wait,
-    base::Optional<StringId> blocked_function) {
+    std::optional<bool> io_wait,
+    std::optional<StringId> blocked_function) {
   // Return if there is no state, as there is are no previous rows available.
   if (!HasPreviousRowNumbersForUtid(utid))
     return;
@@ -102,8 +102,8 @@
 void ThreadStateTracker::AddOpenState(int64_t ts,
                                       UniqueTid utid,
                                       StringId state,
-                                      base::Optional<uint32_t> cpu,
-                                      base::Optional<UniqueTid> waker_utid) {
+                                      std::optional<uint32_t> cpu,
+                                      std::optional<UniqueTid> waker_utid) {
   // Ignore utid 0 because it corresponds to the swapper thread which doesn't
   // make sense to insert.
   if (utid == 0)
@@ -124,11 +124,11 @@
   }
 
   if (!prev_row_numbers_for_thread_[utid].has_value()) {
-    prev_row_numbers_for_thread_[utid] = RelatedRows{base::nullopt, row_num};
+    prev_row_numbers_for_thread_[utid] = RelatedRows{std::nullopt, row_num};
   }
 
   if (IsRunning(state)) {
-    prev_row_numbers_for_thread_[utid] = RelatedRows{base::nullopt, row_num};
+    prev_row_numbers_for_thread_[utid] = RelatedRows{std::nullopt, row_num};
   } else if (IsBlocked(state)) {
     prev_row_numbers_for_thread_[utid] = RelatedRows{row_num, row_num};
   } else /* if (IsRunnable(state)) */ {
diff --git a/src/trace_processor/importers/ftrace/thread_state_tracker.h b/src/trace_processor/importers/ftrace/thread_state_tracker.h
index 3f8b7a5..7faae9c 100644
--- a/src/trace_processor/importers/ftrace/thread_state_tracker.h
+++ b/src/trace_processor/importers/ftrace/thread_state_tracker.h
@@ -57,15 +57,15 @@
 
   // Updates the current blocked state for utid with blocked reason.
   void PushBlockedReason(UniqueTid utid,
-                         base::Optional<bool> io_wait,
-                         base::Optional<StringId> blocked_function);
+                         std::optional<bool> io_wait,
+                         std::optional<StringId> blocked_function);
 
  private:
   void AddOpenState(int64_t ts,
                     UniqueTid utid,
                     StringId state,
-                    base::Optional<uint32_t> cpu = base::nullopt,
-                    base::Optional<UniqueTid> waker_utid = base::nullopt);
+                    std::optional<uint32_t> cpu = std::nullopt,
+                    std::optional<UniqueTid> waker_utid = std::nullopt);
   void ClosePendingState(int64_t end_ts, UniqueTid utid, bool data_loss);
 
   bool IsRunning(StringId state);
@@ -89,11 +89,11 @@
   StringId runnable_string_id_;
 
   struct RelatedRows {
-    base::Optional<tables::ThreadStateTable::RowNumber> last_blocked_row;
+    std::optional<tables::ThreadStateTable::RowNumber> last_blocked_row;
     tables::ThreadStateTable::RowNumber last_row;
   };
 
-  std::vector<base::Optional<RelatedRows>> prev_row_numbers_for_thread_;
+  std::vector<std::optional<RelatedRows>> prev_row_numbers_for_thread_;
 };
 }  // namespace trace_processor
 }  // namespace perfetto
diff --git a/src/trace_processor/importers/ftrace/thread_state_tracker_unittest.cc b/src/trace_processor/importers/ftrace/thread_state_tracker_unittest.cc
index 0c6c370..e706a2e 100644
--- a/src/trace_processor/importers/ftrace/thread_state_tracker_unittest.cc
+++ b/src/trace_processor/importers/ftrace/thread_state_tracker_unittest.cc
@@ -58,13 +58,13 @@
   void VerifyThreadState(
       const tables::ThreadStateTable::ConstIterator& it,
       int64_t from,
-      base::Optional<int64_t> to,
+      std::optional<int64_t> to,
       UniqueTid utid,
       const char* state,
-      base::Optional<bool> io_wait = base::nullopt,
-      base::Optional<StringId> blocked_function = base::nullopt,
-      base::Optional<UniqueTid> waker_utid = base::nullopt,
-      base::Optional<int64_t> cpu = base::nullopt) {
+      std::optional<bool> io_wait = std::nullopt,
+      std::optional<StringId> blocked_function = std::nullopt,
+      std::optional<UniqueTid> waker_utid = std::nullopt,
+      std::optional<int64_t> cpu = std::nullopt) {
     ASSERT_EQ(it.ts(), from);
     ASSERT_EQ(it.dur(), to ? *to - from : -1);
     ASSERT_EQ(it.utid(), utid);
@@ -75,7 +75,7 @@
         ASSERT_EQ(it.cpu(), CPU_A);
       }
     } else {
-      ASSERT_EQ(it.cpu(), base::nullopt);
+      ASSERT_EQ(it.cpu(), std::nullopt);
     }
     ASSERT_STREQ(context_.storage->GetString(it.state()).c_str(), state);
     ASSERT_EQ(it.io_wait(), io_wait);
@@ -97,8 +97,8 @@
 
   ASSERT_EQ(context_.storage->thread_state_table().row_count(), 2ul);
   auto rows_it = ThreadStateIterator();
-  VerifyThreadState(rows_it, 10, base::nullopt, THREAD_A, "S");
-  VerifyThreadState(++rows_it, 10, base::nullopt, THREAD_B, kRunning);
+  VerifyThreadState(rows_it, 10, std::nullopt, THREAD_A, "S");
+  VerifyThreadState(++rows_it, 10, std::nullopt, THREAD_B, kRunning);
 }
 
 TEST_F(ThreadStateTrackerUnittest, StartWithWakingEvent) {
@@ -114,9 +114,9 @@
   ASSERT_EQ(context_.storage->thread_state_table().row_count(), 3ul);
   auto row_it = ThreadStateIterator();
   VerifyThreadState(row_it, 10, 20, THREAD_A, "S");
-  VerifyThreadState(++row_it, 10, base::nullopt, THREAD_B, kRunning);
-  VerifyThreadState(++row_it, 20, base::nullopt, THREAD_A, kRunnable,
-                    base::nullopt, base::nullopt, THREAD_C);
+  VerifyThreadState(++row_it, 10, std::nullopt, THREAD_B, kRunning);
+  VerifyThreadState(++row_it, 20, std::nullopt, THREAD_A, kRunnable,
+                    std::nullopt, std::nullopt, THREAD_C);
 }
 
 TEST_F(ThreadStateTrackerUnittest, BasicPushBlockedReason) {
@@ -125,7 +125,7 @@
   tracker_->PushBlockedReason(THREAD_A, true, StringIdOf(kBlockedFunction));
 
   auto rows_it = ThreadStateIterator();
-  VerifyThreadState(rows_it, 10, base::nullopt, THREAD_A, "S", true,
+  VerifyThreadState(rows_it, 10, std::nullopt, THREAD_A, "S", true,
                     StringIdOf(kBlockedFunction));
 }
 
@@ -150,7 +150,7 @@
 
   // The opening of idle_thred should be discarded so the first row will be
   // for the THREAD_A.
-  VerifyThreadState(rows_it, 10, base::nullopt, THREAD_A, kRunning);
+  VerifyThreadState(rows_it, 10, std::nullopt, THREAD_A, kRunning);
 }
 
 TEST_F(ThreadStateTrackerUnittest, SchedBlockedReasonWithIdleThread) {
@@ -158,19 +158,19 @@
                                  THREAD_A);
   tracker_->PushSchedSwitchEvent(2, CPU_A, THREAD_A, StringIdOf("D"),
                                  IDLE_THREAD);
-  tracker_->PushBlockedReason(THREAD_A, IDLE_THREAD, base::nullopt);
+  tracker_->PushBlockedReason(THREAD_A, IDLE_THREAD, std::nullopt);
   tracker_->PushSchedSwitchEvent(3, CPU_A, IDLE_THREAD, StringIdOf("D"),
                                  THREAD_B);
   tracker_->PushSchedSwitchEvent(4, CPU_A, THREAD_B, StringIdOf("D"),
                                  IDLE_THREAD);
-  tracker_->PushBlockedReason(THREAD_B, 1, base::nullopt);
+  tracker_->PushBlockedReason(THREAD_B, 1, std::nullopt);
 
   auto rows_it = ThreadStateIterator();
 
   VerifyThreadState(rows_it, 1, 2, THREAD_A, kRunning);
-  VerifyThreadState(++rows_it, 2, base::nullopt, THREAD_A, "D", 0);
+  VerifyThreadState(++rows_it, 2, std::nullopt, THREAD_A, "D", 0);
   VerifyThreadState(++rows_it, 3, 4, THREAD_B, kRunning);
-  VerifyThreadState(++rows_it, 4, base::nullopt, THREAD_B, "D", 1);
+  VerifyThreadState(++rows_it, 4, std::nullopt, THREAD_B, "D", 1);
 }
 
 TEST_F(ThreadStateTrackerUnittest, SchedSwitchForcedMigration) {
@@ -178,7 +178,7 @@
   tracker_->PushSchedSwitchEvent(2, CPU_A, THREAD_A, StringIdOf("S"), THREAD_B);
 
   auto rows_it = ThreadStateIterator();
-  VerifyThreadState(rows_it, 1, base::nullopt, THREAD_A, "S");
+  VerifyThreadState(rows_it, 1, std::nullopt, THREAD_A, "S");
   VerifyThreadState(++rows_it, 1, 2, THREAD_B, kRunning);
 }
 
@@ -192,12 +192,12 @@
   tracker_->PushSchedSwitchEvent(7, CPU_A, 0, StringIdOf(kRunnable), 18);
 
   auto rows_it = ThreadStateIterator();
-  VerifyThreadState(rows_it, 2, base::nullopt, 11, "S");
-  VerifyThreadState(++rows_it, 3, base::nullopt, 8, "S");
-  VerifyThreadState(++rows_it, 4, base::nullopt, 17771, "S");
+  VerifyThreadState(rows_it, 2, std::nullopt, 11, "S");
+  VerifyThreadState(++rows_it, 3, std::nullopt, 8, "S");
+  VerifyThreadState(++rows_it, 4, std::nullopt, 17771, "S");
   VerifyThreadState(++rows_it, 4, 5, 17772, kRunning);
-  VerifyThreadState(++rows_it, 5, base::nullopt, 17772, "S");
-  VerifyThreadState(++rows_it, 7, base::nullopt, 18, kRunning);
+  VerifyThreadState(++rows_it, 5, std::nullopt, 17772, "S");
+  VerifyThreadState(++rows_it, 7, std::nullopt, 18, kRunning);
 }
 
 TEST_F(ThreadStateTrackerUnittest, RunningOnMultipleCPUsForcedMigration) {
@@ -206,11 +206,11 @@
   tracker_->PushSchedSwitchEvent(2, CPU_B, THREAD_B, StringIdOf("S"), THREAD_A);
 
   auto rows_it = ThreadStateIterator();
-  VerifyThreadState(rows_it, 1, base::nullopt, THREAD_C, "S");
+  VerifyThreadState(rows_it, 1, std::nullopt, THREAD_C, "S");
   VerifyThreadState(++rows_it, 1, 2, THREAD_A, kRunning);
-  VerifyThreadState(++rows_it, 2, base::nullopt, THREAD_B, "S");
-  VerifyThreadState(++rows_it, 2, base::nullopt, THREAD_A, kRunning,
-                    base::nullopt, base::nullopt, base::nullopt, CPU_B);
+  VerifyThreadState(++rows_it, 2, std::nullopt, THREAD_B, "S");
+  VerifyThreadState(++rows_it, 2, std::nullopt, THREAD_A, kRunning,
+                    std::nullopt, std::nullopt, std::nullopt, CPU_B);
 }
 
 }  // namespace
diff --git a/src/trace_processor/importers/ftrace/v4l2_tracker.cc b/src/trace_processor/importers/ftrace/v4l2_tracker.cc
index 66c1709..c441fb1 100644
--- a/src/trace_processor/importers/ftrace/v4l2_tracker.cc
+++ b/src/trace_processor/importers/ftrace/v4l2_tracker.cc
@@ -88,7 +88,7 @@
 
       StringId buf_name_id =
           context_->storage->InternString(buf_name.string_view());
-      base::Optional<SliceId> slice_id =
+      std::optional<SliceId> slice_id =
           AddSlice(buf_name_id, timestamp, pid, evt);
 
       uint64_t hash = base::Hasher::Combine(evt.device_minor, evt.sequence,
@@ -129,7 +129,7 @@
 
       StringId buf_name_id =
           context_->storage->InternString(buf_name.string_view());
-      base::Optional<SliceId> slice_id =
+      std::optional<SliceId> slice_id =
           AddSlice(buf_name_id, timestamp, pid, evt);
 
       uint64_t hash = base::Hasher::Combine(evt.device_minor, evt.sequence,
@@ -150,9 +150,9 @@
       Vb2V4l2BufQueueFtraceEvent::Decoder pb_evt(bytes.data, bytes.size);
       BufferEvent evt;
       evt.device_minor = pb_evt.minor();
-      evt.index = base::nullopt;
-      evt.type = base::nullopt;
-      evt.bytesused = base::nullopt;
+      evt.index = std::nullopt;
+      evt.type = std::nullopt;
+      evt.bytesused = std::nullopt;
       evt.flags = pb_evt.flags();
       evt.field = pb_evt.field();
       evt.timestamp = pb_evt.timestamp();
@@ -168,10 +168,9 @@
       evt.timecode_userbits2 = pb_evt.timecode_userbits2();
       evt.timecode_userbits3 = pb_evt.timecode_userbits3();
 
-      base::StackString<64> buf_name(
-          "vb2_v4l2_buf_queue minor=%" PRIu32 " seq=%" PRIu32 " type=%" PRIu32
-          " index=%" PRIu32,
-          evt.device_minor, evt.sequence, *evt.type, *evt.index);
+      base::StackString<64> buf_name("vb2_v4l2_buf_queue minor=%" PRIu32
+                                     " seq=%" PRIu32 " type=0 index=0",
+                                     evt.device_minor, evt.sequence);
 
       StringId buf_name_id =
           context_->storage->InternString(buf_name.string_view());
@@ -182,9 +181,9 @@
       Vb2V4l2BufDoneFtraceEvent::Decoder pb_evt(bytes.data, bytes.size);
       BufferEvent evt;
       evt.device_minor = pb_evt.minor();
-      evt.index = base::nullopt;
-      evt.type = base::nullopt;
-      evt.bytesused = base::nullopt;
+      evt.index = std::nullopt;
+      evt.type = std::nullopt;
+      evt.bytesused = std::nullopt;
       evt.flags = pb_evt.flags();
       evt.field = pb_evt.field();
       evt.timestamp = pb_evt.timestamp();
@@ -200,10 +199,9 @@
       evt.timecode_userbits2 = pb_evt.timecode_userbits2();
       evt.timecode_userbits3 = pb_evt.timecode_userbits3();
 
-      base::StackString<64> buf_name(
-          "vb2_v4l2_buf_done minor=%" PRIu32 " seq=%" PRIu32 " type=%" PRIu32
-          " index=%" PRIu32,
-          evt.device_minor, evt.sequence, *evt.type, *evt.index);
+      base::StackString<64> buf_name("vb2_v4l2_buf_done minor=%" PRIu32
+                                     " seq=%" PRIu32 " type=0 index=0",
+                                     evt.device_minor, evt.sequence);
 
       StringId buf_name_id =
           context_->storage->InternString(buf_name.string_view());
@@ -214,9 +212,9 @@
       Vb2V4l2QbufFtraceEvent::Decoder pb_evt(bytes.data, bytes.size);
       BufferEvent evt;
       evt.device_minor = pb_evt.minor();
-      evt.index = base::nullopt;
-      evt.type = base::nullopt;
-      evt.bytesused = base::nullopt;
+      evt.index = std::nullopt;
+      evt.type = std::nullopt;
+      evt.bytesused = std::nullopt;
       evt.flags = pb_evt.flags();
       evt.field = pb_evt.field();
       evt.timestamp = pb_evt.timestamp();
@@ -232,10 +230,9 @@
       evt.timecode_userbits2 = pb_evt.timecode_userbits2();
       evt.timecode_userbits3 = pb_evt.timecode_userbits3();
 
-      base::StackString<64> buf_name(
-          "vb2_v4l2_qbuf minor=%" PRIu32 " seq=%" PRIu32 " type=%" PRIu32
-          " index=%" PRIu32,
-          evt.device_minor, evt.sequence, *evt.type, *evt.index);
+      base::StackString<64> buf_name("vb2_v4l2_qbuf minor=%" PRIu32
+                                     " seq=%" PRIu32 " type=0 index=0",
+                                     evt.device_minor, evt.sequence);
 
       StringId buf_name_id =
           context_->storage->InternString(buf_name.string_view());
@@ -246,9 +243,9 @@
       Vb2V4l2DqbufFtraceEvent::Decoder pb_evt(bytes.data, bytes.size);
       BufferEvent evt;
       evt.device_minor = pb_evt.minor();
-      evt.index = base::nullopt;
-      evt.type = base::nullopt;
-      evt.bytesused = base::nullopt;
+      evt.index = std::nullopt;
+      evt.type = std::nullopt;
+      evt.bytesused = std::nullopt;
       evt.flags = pb_evt.flags();
       evt.field = pb_evt.field();
       evt.timestamp = pb_evt.timestamp();
@@ -264,10 +261,9 @@
       evt.timecode_userbits2 = pb_evt.timecode_userbits2();
       evt.timecode_userbits3 = pb_evt.timecode_userbits3();
 
-      base::StackString<64> buf_name(
-          "vb2_v4l2_qbuf minor=%" PRIu32 " seq=%" PRIu32 " type=%" PRIu32
-          " index=%" PRIu32,
-          evt.device_minor, evt.sequence, *evt.type, *evt.index);
+      base::StackString<64> buf_name("vb2_v4l2_qbuf minor=%" PRIu32
+                                     " seq=%" PRIu32 " type=0 index=0",
+                                     evt.device_minor, evt.sequence);
 
       StringId buf_name_id =
           context_->storage->InternString(buf_name.string_view());
@@ -279,14 +275,14 @@
   }
 }
 
-base::Optional<SliceId> V4l2Tracker::AddSlice(StringId buf_name_id,
-                                              int64_t timestamp,
-                                              uint32_t pid,
-                                              const BufferEvent& evt) {
+std::optional<SliceId> V4l2Tracker::AddSlice(StringId buf_name_id,
+                                             int64_t timestamp,
+                                             uint32_t pid,
+                                             const BufferEvent& evt) {
   UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
   TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
 
-  base::Optional<SliceId> slice_id = context_->slice_tracker->Scoped(
+  std::optional<SliceId> slice_id = context_->slice_tracker->Scoped(
       timestamp, track_id, buf_event_ids_.v4l2, buf_name_id, 0,
       [this, &evt](ArgsTracker::BoundInserter* inserter) {
         this->AddArgs(evt, inserter);
diff --git a/src/trace_processor/importers/ftrace/v4l2_tracker.h b/src/trace_processor/importers/ftrace/v4l2_tracker.h
index f204e1d..057d7e4 100644
--- a/src/trace_processor/importers/ftrace/v4l2_tracker.h
+++ b/src/trace_processor/importers/ftrace/v4l2_tracker.h
@@ -19,9 +19,9 @@
 
 #include <stdint.h>
 #include <cstdint>
+#include <optional>
 
 #include "perfetto/ext/base/flat_hash_map.h"
-#include "perfetto/ext/base/optional.h"
 
 #include "perfetto/protozero/field.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
@@ -58,9 +58,9 @@
   struct BufferEvent {
    public:
     int32_t device_minor;
-    base::Optional<uint32_t> index;
-    base::Optional<uint32_t> type;
-    base::Optional<uint32_t> bytesused;
+    std::optional<uint32_t> index;
+    std::optional<uint32_t> type;
+    std::optional<uint32_t> bytesused;
     uint32_t flags;
     uint32_t field;
     int64_t timestamp;
@@ -155,13 +155,13 @@
   };
 
   struct QueuedBuffer {
-    base::Optional<SliceId> queue_slice_id;
+    std::optional<SliceId> queue_slice_id;
   };
 
-  base::Optional<SliceId> AddSlice(StringId buf_name_id,
-                                   int64_t timestamp,
-                                   uint32_t pid,
-                                   const BufferEvent& evt);
+  std::optional<SliceId> AddSlice(StringId buf_name_id,
+                                  int64_t timestamp,
+                                  uint32_t pid,
+                                  const BufferEvent& evt);
 
   void AddArgs(const BufferEvent& evt, ArgsTracker::BoundInserter* inserter);
 
diff --git a/src/trace_processor/importers/fuchsia/fuchsia_parser_unittest.cc b/src/trace_processor/importers/fuchsia/fuchsia_parser_unittest.cc
index 92ccb20..cf0d569 100644
--- a/src/trace_processor/importers/fuchsia/fuchsia_parser_unittest.cc
+++ b/src/trace_processor/importers/fuchsia/fuchsia_parser_unittest.cc
@@ -26,13 +26,13 @@
 #include "src/trace_processor/importers/common/clock_tracker.h"
 #include "src/trace_processor/importers/common/event_tracker.h"
 #include "src/trace_processor/importers/common/flow_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/importers/common/process_tracker.h"
 #include "src/trace_processor/importers/common/slice_tracker.h"
 #include "src/trace_processor/importers/common/track_tracker.h"
 #include "src/trace_processor/importers/ftrace/sched_event_tracker.h"
 #include "src/trace_processor/importers/proto/additional_modules.h"
 #include "src/trace_processor/importers/proto/default_modules.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
 #include "src/trace_processor/importers/proto/proto_trace_parser.h"
 #include "src/trace_processor/importers/proto/stack_profile_tracker.h"
 #include "src/trace_processor/sorter/trace_sorter.h"
@@ -115,7 +115,7 @@
 
   MOCK_METHOD4(SetProcessMetadata,
                UniquePid(uint32_t pid,
-                         base::Optional<uint32_t> ppid,
+                         std::optional<uint32_t> ppid,
                          base::StringView process_name,
                          base::StringView cmdline));
 
@@ -169,9 +169,9 @@
                     int32_t next_prio));
 
   MOCK_METHOD3(PushCounter,
-               base::Optional<CounterId>(int64_t timestamp,
-                                         double value,
-                                         TrackId track_id));
+               std::optional<CounterId>(int64_t timestamp,
+                                        double value,
+                                        TrackId track_id));
 };
 
 class MockSliceTracker : public SliceTracker {
@@ -180,29 +180,29 @@
       : SliceTracker(context) {}
 
   MOCK_METHOD5(Begin,
-               base::Optional<SliceId>(int64_t timestamp,
-                                       TrackId track_id,
-                                       StringId cat,
-                                       StringId name,
-                                       SetArgsCallback args_callback));
+               std::optional<SliceId>(int64_t timestamp,
+                                      TrackId track_id,
+                                      StringId cat,
+                                      StringId name,
+                                      SetArgsCallback args_callback));
   MOCK_METHOD5(End,
-               base::Optional<SliceId>(int64_t timestamp,
-                                       TrackId track_id,
-                                       StringId cat,
-                                       StringId name,
-                                       SetArgsCallback args_callback));
+               std::optional<SliceId>(int64_t timestamp,
+                                      TrackId track_id,
+                                      StringId cat,
+                                      StringId name,
+                                      SetArgsCallback args_callback));
   MOCK_METHOD6(Scoped,
-               base::Optional<SliceId>(int64_t timestamp,
-                                       TrackId track_id,
-                                       StringId cat,
-                                       StringId name,
-                                       int64_t duration,
-                                       SetArgsCallback args_callback));
+               std::optional<SliceId>(int64_t timestamp,
+                                      TrackId track_id,
+                                      StringId cat,
+                                      StringId name,
+                                      int64_t duration,
+                                      SetArgsCallback args_callback));
   MOCK_METHOD4(StartSlice,
-               base::Optional<SliceId>(int64_t timestamp,
-                                       TrackId track_id,
-                                       SetArgsCallback args_callback,
-                                       std::function<SliceId()> inserter));
+               std::optional<SliceId>(int64_t timestamp,
+                                      TrackId track_id,
+                                      SetArgsCallback args_callback,
+                                      std::function<SliceId()> inserter));
 };
 
 class FuchsiaTraceParserTest : public ::testing::Test {
@@ -228,7 +228,7 @@
     slice_ = new NiceMock<MockSliceTracker>(&context_);
     context_.slice_tracker.reset(slice_);
     context_.slice_translation_table.reset(new SliceTranslationTable(storage_));
-    context_.clock_tracker.reset(new ClockTracker(context_.storage.get()));
+    context_.clock_tracker.reset(new ClockTracker(&context_));
     clock_ = context_.clock_tracker.get();
     context_.flow_tracker.reset(new FlowTracker(&context_));
     context_.sorter.reset(new TraceSorter(&context_, CreateParser(),
diff --git a/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc b/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc
index 514bfcb..d2dbb1f 100644
--- a/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc
+++ b/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc
@@ -593,7 +593,7 @@
           // artificial koids which have the 2^63 bit set. This is used for
           // things such as virtual threads.
           procs->SetProcessMetadata(
-              static_cast<uint32_t>(obj_id), base::Optional<uint32_t>(),
+              static_cast<uint32_t>(obj_id), std::optional<uint32_t>(),
               base::StringView(storage->GetString(name)), base::StringView());
           break;
         }
diff --git a/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.h b/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.h
index 4b4d610..671060e 100644
--- a/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.h
+++ b/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.h
@@ -73,8 +73,8 @@
 
     FuchsiaThreadInfo info;
     int64_t last_ts{0};
-    base::Optional<tables::SchedSliceTable::RowNumber> last_slice_row;
-    base::Optional<tables::ThreadStateTable::RowNumber> last_state_row;
+    std::optional<tables::SchedSliceTable::RowNumber> last_slice_row;
+    std::optional<tables::ThreadStateTable::RowNumber> last_state_row;
   };
 
   void SwitchFrom(Thread* thread,
diff --git a/src/trace_processor/importers/json/json_trace_parser.cc b/src/trace_processor/importers/json/json_trace_parser.cc
index 50cf243..b087963 100644
--- a/src/trace_processor/importers/json/json_trace_parser.cc
+++ b/src/trace_processor/importers/json/json_trace_parser.cc
@@ -18,10 +18,10 @@
 
 #include <cinttypes>
 #include <limits>
+#include <optional>
 #include <string>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/string_view.h"
 #include "src/trace_processor/importers/common/event_tracker.h"
@@ -39,16 +39,16 @@
 #if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
 namespace {
 
-base::Optional<uint64_t> MaybeExtractFlowIdentifier(const Json::Value& value,
-                                                    bool version2) {
+std::optional<uint64_t> MaybeExtractFlowIdentifier(const Json::Value& value,
+                                                   bool version2) {
   std::string id_key = (version2 ? "bind_id" : "id");
   if (!value.isMember(id_key))
-    return base::nullopt;
+    return std::nullopt;
   auto id = value[id_key];
   if (id.isNumeric())
     return id.asUInt64();
   if (!id.isString())
-    return base::nullopt;
+    return std::nullopt;
   const char* c_string = id.asCString();
   return base::CStringToUInt64(c_string, 16);
 }
@@ -87,8 +87,8 @@
     return;
   char phase = *ph.asCString();
 
-  base::Optional<uint32_t> opt_pid;
-  base::Optional<uint32_t> opt_tid;
+  std::optional<uint32_t> opt_pid;
+  std::optional<uint32_t> opt_tid;
 
   if (value.isMember("pid"))
     opt_pid = json::CoerceToUint32(value["pid"]);
@@ -132,8 +132,8 @@
     // tdur will only exist on 'X' events.
     row.thread_dur = json::CoerceToTs(value["tdur"]);
     // JSON traces don't report these counters as part of slices.
-    row.thread_instruction_count = base::nullopt;
-    row.thread_instruction_delta = base::nullopt;
+    row.thread_instruction_count = std::nullopt;
+    row.thread_instruction_delta = std::nullopt;
     return row;
   };
 
@@ -191,7 +191,7 @@
       break;
     }
     case 'X': {  // TRACE_EVENT (scoped event).
-      base::Optional<int64_t> opt_dur = json::CoerceToTs(value["dur"]);
+      std::optional<int64_t> opt_dur = json::CoerceToTs(value["dur"]);
       if (!opt_dur.has_value())
         return;
       TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
@@ -333,7 +333,7 @@
       }
       if (name == "process_name" && !value["args"]["name"].empty()) {
         const char* proc_name = value["args"]["name"].asCString();
-        procs->SetProcessMetadata(pid, base::nullopt, proc_name,
+        procs->SetProcessMetadata(pid, std::nullopt, proc_name,
                                   base::StringView());
         break;
       }
diff --git a/src/trace_processor/importers/json/json_trace_tokenizer.cc b/src/trace_processor/importers/json/json_trace_tokenizer.cc
index a385edf..12414f2 100644
--- a/src/trace_processor/importers/json/json_trace_tokenizer.cc
+++ b/src/trace_processor/importers/json/json_trace_tokenizer.cc
@@ -298,7 +298,7 @@
 
 base::Status ExtractValueForJsonKey(base::StringView dict,
                                     const std::string& key,
-                                    base::Optional<std::string>* value) {
+                                    std::optional<std::string>* value) {
   PERFETTO_DCHECK(dict.size() >= 2);
 
   const char* start = dict.data();
@@ -398,7 +398,7 @@
   if (state != kAfterDict)
     return base::ErrStatus("Failure parsing JSON: malformed dictionary");
 
-  *value = base::nullopt;
+  *value = std::nullopt;
   return base::OkStatus();
 }
 
@@ -531,16 +531,16 @@
         break;
     }
 
-    base::Optional<std::string> opt_raw_ts;
+    std::optional<std::string> opt_raw_ts;
     RETURN_IF_ERROR(ExtractValueForJsonKey(unparsed, "ts", &opt_raw_ts));
-    base::Optional<int64_t> opt_ts =
-        opt_raw_ts ? json::CoerceToTs(*opt_raw_ts) : base::nullopt;
+    std::optional<int64_t> opt_ts =
+        opt_raw_ts ? json::CoerceToTs(*opt_raw_ts) : std::nullopt;
     int64_t ts = 0;
     if (opt_ts.has_value()) {
       ts = opt_ts.value();
     } else {
       // Metadata events may omit ts. In all other cases error:
-      base::Optional<std::string> opt_raw_ph;
+      std::optional<std::string> opt_raw_ph;
       RETURN_IF_ERROR(ExtractValueForJsonKey(unparsed, "ph", &opt_raw_ph));
       if (!opt_raw_ph || *opt_raw_ph != "M") {
         context_->storage->IncrementStats(stats::json_tokenizer_failure);
diff --git a/src/trace_processor/importers/json/json_trace_tokenizer.h b/src/trace_processor/importers/json/json_trace_tokenizer.h
index 3713636..61f1d77 100644
--- a/src/trace_processor/importers/json/json_trace_tokenizer.h
+++ b/src/trace_processor/importers/json/json_trace_tokenizer.h
@@ -79,7 +79,7 @@
 // Visible for testing.
 base::Status ExtractValueForJsonKey(base::StringView dict,
                                     const std::string& key,
-                                    base::Optional<std::string>* value);
+                                    std::optional<std::string>* value);
 
 enum class ReadSystemLineRes {
   kFoundLine,
diff --git a/src/trace_processor/importers/json/json_trace_tokenizer_unittest.cc b/src/trace_processor/importers/json/json_trace_tokenizer_unittest.cc
index 051f52a..22a3885 100644
--- a/src/trace_processor/importers/json/json_trace_tokenizer_unittest.cc
+++ b/src/trace_processor/importers/json/json_trace_tokenizer_unittest.cc
@@ -226,7 +226,7 @@
 }
 
 TEST(JsonTraceTokenizerTest, ExtractValueForJsonKey) {
-  base::Optional<std::string> line;
+  std::optional<std::string> line;
 
   ASSERT_TRUE(ExtractValueForJsonKey(R"({"ts": 149029})", "ts", &line).ok());
   ASSERT_EQ(*line, "149029");
diff --git a/src/trace_processor/importers/json/json_utils.cc b/src/trace_processor/importers/json/json_utils.cc
index 432ddbe..be9492b 100644
--- a/src/trace_processor/importers/json/json_utils.cc
+++ b/src/trace_processor/importers/json/json_utils.cc
@@ -37,7 +37,7 @@
 #endif
 }
 
-base::Optional<int64_t> CoerceToTs(const Json::Value& value) {
+std::optional<int64_t> CoerceToTs(const Json::Value& value) {
   PERFETTO_DCHECK(IsJsonSupported());
 
 #if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
@@ -50,36 +50,36 @@
     case Json::stringValue:
       return CoerceToTs(value.asString());
     default:
-      return base::nullopt;
+      return std::nullopt;
   }
 #else
   perfetto::base::ignore_result(value);
-  return base::nullopt;
+  return std::nullopt;
 #endif
 }
 
-base::Optional<int64_t> CoerceToTs(const std::string& s) {
+std::optional<int64_t> CoerceToTs(const std::string& s) {
   PERFETTO_DCHECK(IsJsonSupported());
 
 #if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
   size_t lhs_end = std::min<size_t>(s.find('.'), s.size());
   size_t rhs_start = std::min<size_t>(lhs_end + 1, s.size());
-  base::Optional<int64_t> lhs = base::StringToInt64(s.substr(0, lhs_end));
-  base::Optional<double> rhs =
+  std::optional<int64_t> lhs = base::StringToInt64(s.substr(0, lhs_end));
+  std::optional<double> rhs =
       base::StringToDouble("0." + s.substr(rhs_start, std::string::npos));
   if ((!lhs.has_value() && lhs_end > 0) ||
       (!rhs.has_value() && rhs_start < s.size())) {
-    return base::nullopt;
+    return std::nullopt;
   }
   return lhs.value_or(0) * 1000 +
          static_cast<int64_t>(rhs.value_or(0) * 1000.0);
 #else
   perfetto::base::ignore_result(s);
-  return base::nullopt;
+  return std::nullopt;
 #endif
 }
 
-base::Optional<int64_t> CoerceToInt64(const Json::Value& value) {
+std::optional<int64_t> CoerceToInt64(const Json::Value& value) {
   PERFETTO_DCHECK(IsJsonSupported());
 
 #if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
@@ -94,36 +94,36 @@
       char* end;
       int64_t n = strtoll(s.c_str(), &end, 10);
       if (end != s.data() + s.size())
-        return base::nullopt;
+        return std::nullopt;
       return n;
     }
     default:
-      return base::nullopt;
+      return std::nullopt;
   }
 #else
   perfetto::base::ignore_result(value);
-  return base::nullopt;
+  return std::nullopt;
 #endif
 }
 
-base::Optional<uint32_t> CoerceToUint32(const Json::Value& value) {
+std::optional<uint32_t> CoerceToUint32(const Json::Value& value) {
   PERFETTO_DCHECK(IsJsonSupported());
 
 #if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
-  base::Optional<int64_t> result = CoerceToInt64(value);
+  std::optional<int64_t> result = CoerceToInt64(value);
   if (!result.has_value())
-    return base::nullopt;
+    return std::nullopt;
   int64_t n = result.value();
   if (n < 0 || n > std::numeric_limits<uint32_t>::max())
-    return base::nullopt;
+    return std::nullopt;
   return static_cast<uint32_t>(n);
 #else
   perfetto::base::ignore_result(value);
-  return base::nullopt;
+  return std::nullopt;
 #endif
 }
 
-base::Optional<Json::Value> ParseJsonString(base::StringView raw_string) {
+std::optional<Json::Value> ParseJsonString(base::StringView raw_string) {
   PERFETTO_DCHECK(IsJsonSupported());
 
 #if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
@@ -133,11 +133,11 @@
   Json::Value value;
   const char* begin = raw_string.data();
   return reader->parse(begin, begin + raw_string.size(), &value, nullptr)
-             ? base::make_optional(std::move(value))
-             : base::nullopt;
+             ? std::make_optional(std::move(value))
+             : std::nullopt;
 #else
   perfetto::base::ignore_result(raw_string);
-  return base::nullopt;
+  return std::nullopt;
 #endif
 }
 
diff --git a/src/trace_processor/importers/json/json_utils.h b/src/trace_processor/importers/json/json_utils.h
index 1cbcae8..b9d0762 100644
--- a/src/trace_processor/importers/json/json_utils.h
+++ b/src/trace_processor/importers/json/json_utils.h
@@ -18,8 +18,8 @@
 #define SRC_TRACE_PROCESSOR_IMPORTERS_JSON_JSON_UTILS_H_
 
 #include <stdint.h>
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 
 #include "src/trace_processor/importers/common/args_tracker.h"
@@ -40,14 +40,14 @@
 // build flags.
 bool IsJsonSupported();
 
-base::Optional<int64_t> CoerceToTs(const Json::Value& value);
-base::Optional<int64_t> CoerceToTs(const std::string& value);
-base::Optional<int64_t> CoerceToInt64(const Json::Value& value);
-base::Optional<uint32_t> CoerceToUint32(const Json::Value& value);
+std::optional<int64_t> CoerceToTs(const Json::Value& value);
+std::optional<int64_t> CoerceToTs(const std::string& value);
+std::optional<int64_t> CoerceToInt64(const Json::Value& value);
+std::optional<uint32_t> CoerceToUint32(const Json::Value& value);
 
 // Parses the given JSON string into a JSON::Value object.
 // This function should only be called if |IsJsonSupported()| returns true.
-base::Optional<Json::Value> ParseJsonString(base::StringView raw_string);
+std::optional<Json::Value> ParseJsonString(base::StringView raw_string);
 
 // Flattens the given Json::Value and adds each leaf node to the bound args
 // inserter. Note:
diff --git a/src/trace_processor/importers/memory_tracker/graph_processor.cc b/src/trace_processor/importers/memory_tracker/graph_processor.cc
index 85dc9ad..77e40a9 100644
--- a/src/trace_processor/importers/memory_tracker/graph_processor.cc
+++ b/src/trace_processor/importers/memory_tracker/graph_processor.cc
@@ -42,14 +42,14 @@
   }
 }
 
-base::Optional<uint64_t> GetSizeEntryOfNode(Node* node) {
+std::optional<uint64_t> GetSizeEntryOfNode(Node* node) {
   auto size_it = node->entries()->find(kSizeEntryName);
   if (size_it == node->entries()->end())
-    return base::nullopt;
+    return std::nullopt;
 
   PERFETTO_DCHECK(size_it->second.type == Node::Entry::Type::kUInt64);
   PERFETTO_DCHECK(size_it->second.units == Node::Entry::ScalarUnits::kBytes);
-  return base::Optional<uint64_t>(size_it->second.value_uint64);
+  return std::optional<uint64_t>(size_it->second.value_uint64);
 }
 
 }  // namespace
@@ -530,17 +530,17 @@
 }
 
 // static
-base::Optional<uint64_t> GraphProcessor::AggregateSizeForDescendantNode(
+std::optional<uint64_t> GraphProcessor::AggregateSizeForDescendantNode(
     Node* root,
     Node* descendant) {
   Edge* owns_edge = descendant->owns_edge();
   if (owns_edge && owns_edge->target()->IsDescendentOf(*root))
-    return base::make_optional(0UL);
+    return std::make_optional(0UL);
 
   if (descendant->children()->empty())
     return GetSizeEntryOfNode(descendant).value_or(0ul);
 
-  base::Optional<uint64_t> size;
+  std::optional<uint64_t> size;
   for (const auto& path_to_child : *descendant->children()) {
     auto c_size = AggregateSizeForDescendantNode(root, path_to_child.second);
     if (size) {
@@ -556,10 +556,10 @@
 // static
 void GraphProcessor::CalculateSizeForNode(Node* node) {
   // Get the size at the root node if it exists.
-  base::Optional<uint64_t> node_size = GetSizeEntryOfNode(node);
+  std::optional<uint64_t> node_size = GetSizeEntryOfNode(node);
 
   // Aggregate the size of all the child nodes.
-  base::Optional<uint64_t> aggregated_size;
+  std::optional<uint64_t> aggregated_size;
   for (const auto& path_to_child : *node->children()) {
     auto c_size = AggregateSizeForDescendantNode(node, path_to_child.second);
     if (aggregated_size) {
@@ -578,7 +578,7 @@
   // *aggregated_size);
 
   // Calculate the maximal size of an owner node.
-  base::Optional<uint64_t> max_owner_size;
+  std::optional<uint64_t> max_owner_size;
   for (auto* edge : *node->owned_by_edges()) {
     auto o_size = GetSizeEntryOfNode(edge->source());
     if (max_owner_size) {
@@ -625,7 +625,7 @@
 // static
 void GraphProcessor::CalculateNodeSubSizes(Node* node) {
   // Completely skip nodes with undefined size.
-  base::Optional<uint64_t> size_opt = GetSizeEntryOfNode(node);
+  std::optional<uint64_t> size_opt = GetSizeEntryOfNode(node);
   if (!size_opt)
     return;
 
@@ -669,7 +669,7 @@
 // static
 void GraphProcessor::CalculateNodeOwnershipCoefficient(Node* node) {
   // Completely skip nodes with undefined size.
-  base::Optional<uint64_t> size_opt = GetSizeEntryOfNode(node);
+  std::optional<uint64_t> size_opt = GetSizeEntryOfNode(node);
   if (!size_opt)
     return;
 
@@ -744,7 +744,7 @@
 // static
 void GraphProcessor::CalculateNodeCumulativeOwnershipCoefficient(Node* node) {
   // Completely skip nodes with undefined size.
-  base::Optional<uint64_t> size_opt = GetSizeEntryOfNode(node);
+  std::optional<uint64_t> size_opt = GetSizeEntryOfNode(node);
   if (!size_opt)
     return;
 
@@ -771,7 +771,7 @@
 void GraphProcessor::CalculateNodeEffectiveSize(Node* node) {
   // Completely skip nodes with undefined size. As a result, each node will
   // have defined effective size if and only if it has defined size.
-  base::Optional<uint64_t> size_opt = GetSizeEntryOfNode(node);
+  std::optional<uint64_t> size_opt = GetSizeEntryOfNode(node);
   if (!size_opt) {
     node->entries()->erase(kEffectiveSizeEntryName);
     return;
diff --git a/src/trace_processor/importers/memory_tracker/graph_processor_unittest.cc b/src/trace_processor/importers/memory_tracker/graph_processor_unittest.cc
index 4275b36..2a96ee7 100644
--- a/src/trace_processor/importers/memory_tracker/graph_processor_unittest.cc
+++ b/src/trace_processor/importers/memory_tracker/graph_processor_unittest.cc
@@ -71,8 +71,8 @@
     GraphProcessor::PropagateNumericsAndDiagnosticsRecursively(node);
   }
 
-  base::Optional<uint64_t> AggregateSizeForDescendantNode(Node* root,
-                                                          Node* descendant) {
+  std::optional<uint64_t> AggregateSizeForDescendantNode(Node* root,
+                                                         Node* descendant) {
     return GraphProcessor::AggregateSizeForDescendantNode(root, descendant);
   }
 
diff --git a/src/trace_processor/importers/proto/BUILD.gn b/src/trace_processor/importers/proto/BUILD.gn
index 07bdd19..b52254d 100644
--- a/src/trace_processor/importers/proto/BUILD.gn
+++ b/src/trace_processor/importers/proto/BUILD.gn
@@ -34,8 +34,6 @@
     "memory_tracker_snapshot_parser.h",
     "metadata_minimal_module.cc",
     "metadata_minimal_module.h",
-    "metadata_tracker.cc",
-    "metadata_tracker.h",
     "network_trace_module.cc",
     "network_trace_module.h",
     "packet_analyzer.cc",
@@ -238,6 +236,7 @@
     "active_chrome_processes_tracker_unittest.cc",
     "heap_graph_tracker_unittest.cc",
     "heap_profile_tracker_unittest.cc",
+    "network_trace_module_unittest.cc",
     "perf_sample_tracker_unittest.cc",
     "proto_trace_parser_unittest.cc",
   ]
diff --git a/src/trace_processor/importers/proto/active_chrome_processes_tracker.cc b/src/trace_processor/importers/proto/active_chrome_processes_tracker.cc
index 1c20836..a689cec 100644
--- a/src/trace_processor/importers/proto/active_chrome_processes_tracker.cc
+++ b/src/trace_processor/importers/proto/active_chrome_processes_tracker.cc
@@ -31,8 +31,8 @@
   for (auto it = process_data_.GetIterator(); it; ++it) {
     UniquePid upid = it.key();
     const auto& process_data = it.value();
-    base::Optional<int64_t> last_loss_moment;
-    base::Optional<int64_t> next_no_loss_moment;
+    std::optional<int64_t> last_loss_moment;
+    std::optional<int64_t> next_no_loss_moment;
     for (int64_t metadata_ts : process_data.metadata_timestamps) {
       // Looks for a matching process descriptor in the [t - 0.2s, t + 0.2s]
       // window. The window size is somewhat arbitrary, and can be changed in
@@ -60,7 +60,7 @@
           // trace.
           next_no_loss_moment = *global_metadata_it;
         } else {
-          next_no_loss_moment = base::nullopt;
+          next_no_loss_moment = std::nullopt;
         }
       }
     }
diff --git a/src/trace_processor/importers/proto/active_chrome_processes_tracker.h b/src/trace_processor/importers/proto/active_chrome_processes_tracker.h
index 3dd1499..b4ebdc1 100644
--- a/src/trace_processor/importers/proto/active_chrome_processes_tracker.h
+++ b/src/trace_processor/importers/proto/active_chrome_processes_tracker.h
@@ -17,9 +17,9 @@
 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ACTIVE_CHROME_PROCESSES_TRACKER_H_
 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ACTIVE_CHROME_PROCESSES_TRACKER_H_
 
+#include <optional>
 #include <set>
 #include <vector>
-#include "perfetto/ext/base/optional.h"
 
 #include "perfetto/ext/base/flat_hash_map.h"
 #include "src/trace_processor/storage/trace_storage.h"
@@ -30,9 +30,9 @@
 
 struct ProcessWithDataLoss {
   UniquePid upid;
-  // If not nullopt, the process data is reliable from this point until
+  // If not std::nullopt, the process data is reliable from this point until
   // the end of the trace.
-  base::Optional<int64_t> reliable_from;
+  std::optional<int64_t> reliable_from;
 };
 
 // Tracks ActiveProcesses metadata packets from ChromeTrackEvent,
diff --git a/src/trace_processor/importers/proto/active_chrome_processes_tracker_unittest.cc b/src/trace_processor/importers/proto/active_chrome_processes_tracker_unittest.cc
index 8917eb5..19a04c2 100644
--- a/src/trace_processor/importers/proto/active_chrome_processes_tracker_unittest.cc
+++ b/src/trace_processor/importers/proto/active_chrome_processes_tracker_unittest.cc
@@ -45,8 +45,8 @@
   tracker.AddActiveProcessMetadata(/*timestamp=*/10, /*upid=*/1);
   tracker.AddActiveProcessMetadata(/*timestamp=*/10, /*upid=*/2);
   EXPECT_THAT(tracker.GetProcessesWithDataLoss(),
-              UnorderedElementsAre(ProcessWithDataLoss{1, base::nullopt},
-                                   ProcessWithDataLoss{2, base::nullopt}));
+              UnorderedElementsAre(ProcessWithDataLoss{1, std::nullopt},
+                                   ProcessWithDataLoss{2, std::nullopt}));
 }
 
 TEST(ActiveChromeProcessesTrackerTest, InexactMatch) {
@@ -104,7 +104,7 @@
   // The second process has data loss till the end of the trace.
   EXPECT_THAT(tracker.GetProcessesWithDataLoss(),
               UnorderedElementsAre(ProcessWithDataLoss{1, 15},
-                                   ProcessWithDataLoss{2, base::nullopt}));
+                                   ProcessWithDataLoss{2, std::nullopt}));
 }
 
 }  // namespace
diff --git a/src/trace_processor/importers/proto/android_camera_event_module.h b/src/trace_processor/importers/proto/android_camera_event_module.h
index 8c0453f..88e7476 100644
--- a/src/trace_processor/importers/proto/android_camera_event_module.h
+++ b/src/trace_processor/importers/proto/android_camera_event_module.h
@@ -18,9 +18,9 @@
 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_CAMERA_EVENT_MODULE_H_
 
 #include <cstdint>
+#include <optional>
 #include <unordered_map>
 
-#include "perfetto/ext/base/optional.h"
 #include "protos/perfetto/trace/trace_packet.pbzero.h"
 #include "src/trace_processor/importers/common/parser_types.h"
 #include "src/trace_processor/importers/proto/proto_importer_module.h"
diff --git a/src/trace_processor/importers/proto/android_probes_parser.cc b/src/trace_processor/importers/proto/android_probes_parser.cc
index 6d37b9c..754f30a 100644
--- a/src/trace_processor/importers/proto/android_probes_parser.cc
+++ b/src/trace_processor/importers/proto/android_probes_parser.cc
@@ -16,15 +16,16 @@
 
 #include "src/trace_processor/importers/proto/android_probes_parser.h"
 
-#include "perfetto/ext/base/optional.h"
+#include <optional>
+
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/traced/sys_stats_counters.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
 #include "src/trace_processor/importers/common/async_track_set_tracker.h"
 #include "src/trace_processor/importers/common/clock_tracker.h"
 #include "src/trace_processor/importers/common/event_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/importers/common/process_tracker.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
 #include "src/trace_processor/importers/syscalls/syscall_tracker.h"
 #include "src/trace_processor/types/tcp_state.h"
 #include "src/trace_processor/types/trace_processor_context.h"
@@ -344,19 +345,19 @@
     int32_t cur_mode = static_cast<int32_t>(game_pkg.current_mode());
 
     bool is_standard_mode = false;
-    base::Optional<double> standard_downscale;
-    base::Optional<int32_t> standard_angle;
-    base::Optional<double> standard_fps;
+    std::optional<double> standard_downscale;
+    std::optional<int32_t> standard_angle;
+    std::optional<double> standard_fps;
 
     bool is_performance_mode = false;
-    base::Optional<double> perf_downscale;
-    base::Optional<int32_t> perf_angle;
-    base::Optional<double> perf_fps;
+    std::optional<double> perf_downscale;
+    std::optional<int32_t> perf_angle;
+    std::optional<double> perf_fps;
 
     bool is_battery_mode = false;
-    base::Optional<double> battery_downscale;
-    base::Optional<int32_t> battery_angle;
-    base::Optional<double> battery_fps;
+    std::optional<double> battery_downscale;
+    std::optional<int32_t> battery_angle;
+    std::optional<double> battery_fps;
 
     for (auto mode_it = game_pkg.game_mode_info(); mode_it; ++mode_it) {
       protos::pbzero::AndroidGameInterventionList_GameModeInfo::Decoder
@@ -407,7 +408,7 @@
   for (auto it = properties.values(); it; ++it) {
     protos::pbzero::AndroidSystemProperty::PropertyValue::Decoder kv(*it);
     base::StringView name(kv.name());
-    base::Optional<StringId> mapped_name_id;
+    std::optional<StringId> mapped_name_id;
 
     if (name == "debug.tracing.device_state") {
       auto state = kv.value();
@@ -423,7 +424,7 @@
                name == "debug.tracing.mcc" || name == "debug.tracing.mnc") {
       StringId name_id = context_->storage->InternString(
           name.substr(strlen("debug.tracing.")));
-      base::Optional<int32_t> state =
+      std::optional<int32_t> state =
           base::StringToInt32(kv.value().ToStdString());
       if (state) {
         TrackId track =
@@ -438,7 +439,7 @@
       mapped_name_id = plug_type_id_;
     }
     if (mapped_name_id) {
-      base::Optional<int32_t> state =
+      std::optional<int32_t> state =
           base::StringToInt32(kv.value().ToStdString());
       if (state) {
         TrackId track =
diff --git a/src/trace_processor/importers/proto/android_probes_tracker.h b/src/trace_processor/importers/proto/android_probes_tracker.h
index e5e2469..72ccae2 100644
--- a/src/trace_processor/importers/proto/android_probes_tracker.h
+++ b/src/trace_processor/importers/proto/android_probes_tracker.h
@@ -17,9 +17,9 @@
 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_PROBES_TRACKER_H_
 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_PROBES_TRACKER_H_
 
+#include <optional>
 #include <set>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 
 #include "src/trace_processor/storage/trace_storage.h"
@@ -66,12 +66,12 @@
     seen_packages_.emplace(std::move(package_name));
   }
 
-  base::Optional<TrackId> GetPowerRailTrack(uint32_t index) {
+  std::optional<TrackId> GetPowerRailTrack(uint32_t index) {
     if (index >= power_rail_tracks_.size())
-      return base::nullopt;
+      return std::nullopt;
     TrackId track_id = power_rail_tracks_[index];
-    return track_id == kInvalidTrackId ? base::nullopt
-                                       : base::make_optional(track_id);
+    return track_id == kInvalidTrackId ? std::nullopt
+                                       : std::make_optional(track_id);
   }
 
   void SetPowerRailTrack(uint32_t index, TrackId track_id) {
@@ -80,12 +80,12 @@
     power_rail_tracks_[index] = track_id;
   }
 
-  base::Optional<EnergyConsumerSpecs> GetEnergyBreakdownDescriptor(
+  std::optional<EnergyConsumerSpecs> GetEnergyBreakdownDescriptor(
       int32_t consumer_id) {
     auto it = energy_consumer_descriptors_.find(consumer_id);
     // Didn't receive the descriptor
     if (it == energy_consumer_descriptors_.end()) {
-      return base::nullopt;
+      return std::nullopt;
     }
     return it->second;
   }
@@ -105,14 +105,14 @@
         EnergyConsumerSpecs{name, type, ordinal};
   }
 
-  base::Optional<EntityStateDescriptor> GetEntityStateDescriptor(
+  std::optional<EntityStateDescriptor> GetEntityStateDescriptor(
       int32_t entity_id,
       int32_t state_id) {
     uint64_t id = EntityStateKey(entity_id, state_id);
     auto it = entity_state_descriptors_.find(id);
     // Didn't receive the descriptor
     if (it == entity_state_descriptors_.end()) {
-      return base::nullopt;
+      return std::nullopt;
     }
     return it->second;
   }
diff --git a/src/trace_processor/importers/proto/atoms.descriptor b/src/trace_processor/importers/proto/atoms.descriptor
index 1ef00c0..daeacb7 100644
--- a/src/trace_processor/importers/proto/atoms.descriptor
+++ b/src/trace_processor/importers/proto/atoms.descriptor
Binary files differ
diff --git a/src/trace_processor/importers/proto/chrome_string_lookup.h b/src/trace_processor/importers/proto/chrome_string_lookup.h
index 23f8eca..c1446e5 100644
--- a/src/trace_processor/importers/proto/chrome_string_lookup.h
+++ b/src/trace_processor/importers/proto/chrome_string_lookup.h
@@ -19,9 +19,9 @@
 
 #include <map>
 
+#include <optional>
 #include "src/trace_processor/storage/trace_storage.h"
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 
 namespace perfetto {
diff --git a/src/trace_processor/importers/proto/content_analyzer.cc b/src/trace_processor/importers/proto/content_analyzer.cc
index a225f09..0123c44 100644
--- a/src/trace_processor/importers/proto/content_analyzer.cc
+++ b/src/trace_processor/importers/proto/content_analyzer.cc
@@ -70,7 +70,7 @@
         path_ids;
     for (auto sample = annotated_map.value().GetIterator(); sample; ++sample) {
       std::string path_string;
-      base::Optional<tables::ExperimentalProtoPathTable::Id> previous_path_id;
+      std::optional<tables::ExperimentalProtoPathTable::Id> previous_path_id;
       util::SizeProfileComputer::FieldPath path;
       for (const auto& field : sample.key()) {
         if (field.has_field_name()) {
diff --git a/src/trace_processor/importers/proto/frame_timeline_event_parser.cc b/src/trace_processor/importers/proto/frame_timeline_event_parser.cc
index 0b3e84e..9afec02 100644
--- a/src/trace_processor/importers/proto/frame_timeline_event_parser.cc
+++ b/src/trace_processor/importers/proto/frame_timeline_event_parser.cc
@@ -302,7 +302,7 @@
     actual_row.jank_tag = jank_tag_none_id_;
   }
 
-  base::Optional<SliceId> opt_slice_id = context_->slice_tracker->BeginTyped(
+  std::optional<SliceId> opt_slice_id = context_->slice_tracker->BeginTyped(
       context_->storage->mutable_actual_frame_timeline_slice_table(),
       actual_row,
       [this, token, jank_type, present_type, prediction_type,
@@ -508,7 +508,7 @@
       is_buffer = context_->storage->InternString("No");
   }
 
-  base::Optional<SliceId> opt_slice_id = context_->slice_tracker->BeginTyped(
+  std::optional<SliceId> opt_slice_id = context_->slice_tracker->BeginTyped(
       context_->storage->mutable_actual_frame_timeline_slice_table(),
       actual_row,
       [this, jank_type, present_type, token, layer_name_id, display_frame_token,
diff --git a/src/trace_processor/importers/proto/gpu_event_parser.cc b/src/trace_processor/importers/proto/gpu_event_parser.cc
index 377b5eb..56bc165 100644
--- a/src/trace_processor/importers/proto/gpu_event_parser.cc
+++ b/src/trace_processor/importers/proto/gpu_event_parser.cc
@@ -280,17 +280,17 @@
   }
   ++gpu_hw_queue_counter_;
 }
-base::Optional<std::string> GpuEventParser::FindDebugName(
+std::optional<std::string> GpuEventParser::FindDebugName(
     int32_t vk_object_type,
     uint64_t vk_handle) const {
   auto map = debug_marker_names_.find(vk_object_type);
   if (map == debug_marker_names_.end()) {
-    return base::nullopt;
+    return std::nullopt;
   }
 
   auto name = map->second.find(vk_handle);
   if (name == map->second.end()) {
-    return base::nullopt;
+    return std::nullopt;
   } else {
     return name->second;
   }
diff --git a/src/trace_processor/importers/proto/gpu_event_parser.h b/src/trace_processor/importers/proto/gpu_event_parser.h
index b79b65f..e2eaac8 100644
--- a/src/trace_processor/importers/proto/gpu_event_parser.h
+++ b/src/trace_processor/importers/proto/gpu_event_parser.h
@@ -17,9 +17,9 @@
 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GPU_EVENT_PARSER_H_
 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GPU_EVENT_PARSER_H_
 
+#include <optional>
 #include <vector>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_writer.h"
 #include "perfetto/protozero/field.h"
 #include "protos/perfetto/trace/android/gpu_mem_event.pbzero.h"
@@ -82,8 +82,8 @@
   void InsertGpuTrack(
       const protos::pbzero::
           GpuRenderStageEvent_Specifications_Description_Decoder& hw_queue);
-  base::Optional<std::string> FindDebugName(int32_t vk_object_type,
-                                            uint64_t vk_handle) const;
+  std::optional<std::string> FindDebugName(int32_t vk_object_type,
+                                           uint64_t vk_handle) const;
   const StringId ParseRenderSubpasses(
       const protos::pbzero::GpuRenderStageEvent_Decoder& event) const;
 
@@ -94,7 +94,7 @@
   // For GpuRenderStageEvent
   const StringId description_id_;
   const StringId gpu_render_stage_scope_id_;
-  std::vector<perfetto::base::Optional<TrackId>> gpu_hw_queue_ids_;
+  std::vector<std::optional<TrackId>> gpu_hw_queue_ids_;
   size_t gpu_hw_queue_counter_ = 0;
   // Map of stage ID -> pair(stage name, stage description)
   std::vector<std::pair<StringId, StringId>> gpu_render_stage_ids_;
diff --git a/src/trace_processor/importers/proto/graphics_frame_event_parser.cc b/src/trace_processor/importers/proto/graphics_frame_event_parser.cc
index aa6742e..11808a4 100644
--- a/src/trace_processor/importers/proto/graphics_frame_event_parser.cc
+++ b/src/trace_processor/importers/proto/graphics_frame_event_parser.cc
@@ -154,7 +154,7 @@
       row.acquire_to_latch_time = latch_ts - acquire_ts;
       row.latch_to_present_time = timestamp - latch_ts;
     }
-    base::Optional<SliceId> opt_slice_id =
+    std::optional<SliceId> opt_slice_id =
         context_->slice_tracker->ScopedTyped(graphics_frame_slice_table, row);
     if (event.type() == GraphicsFrameEvent::DEQUEUE) {
       if (opt_slice_id) {
diff --git a/src/trace_processor/importers/proto/graphics_frame_event_parser.h b/src/trace_processor/importers/proto/graphics_frame_event_parser.h
index 957e6ad..2d37612 100644
--- a/src/trace_processor/importers/proto/graphics_frame_event_parser.h
+++ b/src/trace_processor/importers/proto/graphics_frame_event_parser.h
@@ -17,9 +17,9 @@
 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GRAPHICS_FRAME_EVENT_PARSER_H_
 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GRAPHICS_FRAME_EVENT_PARSER_H_
 
+#include <optional>
 #include <vector>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_writer.h"
 #include "perfetto/protozero/field.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
diff --git a/src/trace_processor/importers/proto/heap_graph_module.cc b/src/trace_processor/importers/proto/heap_graph_module.cc
index 0fe7506..ad2b806 100644
--- a/src/trace_processor/importers/proto/heap_graph_module.cc
+++ b/src/trace_processor/importers/proto/heap_graph_module.cc
@@ -239,7 +239,7 @@
 
     StringId kind = context_->storage->InternString(
         HeapGraphTypeKindToString(entry.kind()));
-    base::Optional<uint64_t> location_id;
+    std::optional<uint64_t> location_id;
     if (entry.has_location_id())
       location_id = entry.location_id();
 
@@ -289,7 +289,7 @@
 }
 
 void HeapGraphModule::DeobfuscateClass(
-    base::Optional<StringId> package_name_id,
+    std::optional<StringId> package_name_id,
     StringId obfuscated_class_name_id,
     const protos::pbzero::ObfuscatedClass::Decoder& cls) {
   auto* heap_graph_tracker = HeapGraphTracker::GetOrCreate(context_);
@@ -320,7 +320,7 @@
   auto* heap_graph_tracker = HeapGraphTracker::GetOrCreate(context_);
   protos::pbzero::DeobfuscationMapping::Decoder deobfuscation_mapping(
       blob.data, blob.size);
-  base::Optional<StringId> package_name_id;
+  std::optional<StringId> package_name_id;
   if (deobfuscation_mapping.package_name().size > 0) {
     package_name_id = context_->storage->string_pool().GetId(
         deobfuscation_mapping.package_name());
@@ -340,7 +340,7 @@
       // TODO(b/153552977): Remove this work-around for legacy traces.
       // For traces without location information, deobfuscate all matching
       // classes.
-      DeobfuscateClass(base::nullopt, *obfuscated_class_name_id, cls);
+      DeobfuscateClass(std::nullopt, *obfuscated_class_name_id, cls);
       if (package_name_id) {
         DeobfuscateClass(package_name_id, *obfuscated_class_name_id, cls);
       }
diff --git a/src/trace_processor/importers/proto/heap_graph_module.h b/src/trace_processor/importers/proto/heap_graph_module.h
index 502eab1..42665ef 100644
--- a/src/trace_processor/importers/proto/heap_graph_module.h
+++ b/src/trace_processor/importers/proto/heap_graph_module.h
@@ -42,7 +42,7 @@
  private:
   void ParseHeapGraph(uint32_t seq_id, int64_t ts, protozero::ConstBytes);
   void ParseDeobfuscationMapping(protozero::ConstBytes);
-  void DeobfuscateClass(base::Optional<StringPool::Id> package_name_id,
+  void DeobfuscateClass(std::optional<StringPool::Id> package_name_id,
                         StringPool::Id obfuscated_class_id,
                         const protos::pbzero::ObfuscatedClass::Decoder& cls);
 
diff --git a/src/trace_processor/importers/proto/heap_graph_tracker.cc b/src/trace_processor/importers/proto/heap_graph_tracker.cc
index 39e1418..e337113 100644
--- a/src/trace_processor/importers/proto/heap_graph_tracker.cc
+++ b/src/trace_processor/importers/proto/heap_graph_tracker.cc
@@ -16,12 +16,13 @@
 
 #include "src/trace_processor/importers/proto/heap_graph_tracker.h"
 
+#include <optional>
+
 #include "perfetto/base/flat_set.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_splitter.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "src/trace_processor/importers/proto/profiler_util.h"
-#include "src/trace_processor/tables/profiler_tables.h"
+#include "src/trace_processor/tables/profiler_tables_py.h"
 
 namespace perfetto {
 namespace trace_processor {
@@ -42,7 +43,7 @@
 void ForReferenceSet(TraceStorage* storage,
                      ObjectTable::ConstRowReference object,
                      F fn) {
-  base::Optional<uint32_t> reference_set_id = object.reference_set_id();
+  std::optional<uint32_t> reference_set_id = object.reference_set_id();
   if (!reference_set_id)
     return;
 
@@ -62,13 +63,13 @@
       *storage->heap_graph_class_table().FindById(object.type_id());
 
   StringId kind = cls_row_ref.kind();
-  base::Optional<StringId> weakref_kind =
+  std::optional<StringId> weakref_kind =
       storage->string_pool().GetId("KIND_WEAK_REFERENCE");
-  base::Optional<StringId> softref_kind =
+  std::optional<StringId> softref_kind =
       storage->string_pool().GetId("KIND_SOFT_REFERENCE");
-  base::Optional<StringId> finalizerref_kind =
+  std::optional<StringId> finalizerref_kind =
       storage->string_pool().GetId("KIND_FINALIZER_REFERENCE");
-  base::Optional<StringId> phantomref_kind =
+  std::optional<StringId> phantomref_kind =
       storage->string_pool().GetId("KIND_PHANTOM_REFERENCE");
 
   if ((weakref_kind && kind == *weakref_kind) ||
@@ -94,7 +95,7 @@
 
 struct ClassDescriptor {
   StringId name;
-  base::Optional<StringId> location;
+  std::optional<StringId> location;
 
   bool operator<(const ClassDescriptor& other) const {
     return std::tie(name, location) < std::tie(other.name, other.location);
@@ -109,16 +110,16 @@
   return {type_row_ref.name(), type_row_ref.location()};
 }
 
-base::Optional<ObjectTable::Id> GetReferredObj(const TraceStorage& storage,
-                                               uint32_t ref_set_id,
-                                               const std::string& field_name) {
+std::optional<ObjectTable::Id> GetReferredObj(const TraceStorage& storage,
+                                              uint32_t ref_set_id,
+                                              const std::string& field_name) {
   const auto& refs_tbl = storage.heap_graph_reference_table();
 
   auto refs_it = refs_tbl.FilterToIterator(
       {refs_tbl.reference_set_id().eq(ref_set_id),
        refs_tbl.field_name().eq(NullTermStringView(field_name))});
   if (!refs_it) {
-    return {};
+    return std::nullopt;
   }
   return refs_it.owned_id();
 }
@@ -225,7 +226,7 @@
   }
 }
 
-base::Optional<base::StringView> GetStaticClassTypeName(base::StringView type) {
+std::optional<base::StringView> GetStaticClassTypeName(base::StringView type) {
   static const base::StringView kJavaClassTemplate("java.lang.Class<");
   if (!type.empty() && type.at(type.size() - 1) == '>' &&
       type.substr(0, kJavaClassTemplate.size()) == kJavaClassTemplate) {
@@ -316,10 +317,10 @@
                                             sequence_state->current_ts,
                                             -1,
                                             0,
-                                            /*reference_set_id=*/base::nullopt,
+                                            /*reference_set_id=*/std::nullopt,
                                             /*reachable=*/0,
                                             {},
-                                            /*root_type=*/base::nullopt,
+                                            /*root_type=*/std::nullopt,
                                             /*root_distance*/ -1});
     bool inserted;
     std::tie(ptr, inserted) = sequence_state->object_id_to_db_row.Insert(
@@ -335,7 +336,7 @@
   auto* ptr = sequence_state->type_id_to_db_row.Find(type_id);
   if (!ptr) {
     auto id_and_row =
-        class_table->Insert({StringId(), base::nullopt, base::nullopt});
+        class_table->Insert({StringId(), std::nullopt, std::nullopt});
     bool inserted;
     std::tie(ptr, inserted) = sequence_state->type_id_to_db_row.Insert(
         type_id, id_and_row.row_number);
@@ -377,7 +378,7 @@
   for (size_t i = 0; i < obj.referred_objects.size(); ++i) {
     uint64_t owned_object_id = obj.referred_objects[i];
     // This is true for unset reference fields.
-    base::Optional<ObjectTable::RowReference> owned_row_ref;
+    std::optional<ObjectTable::RowReference> owned_row_ref;
     if (owned_object_id != 0)
       owned_row_ref = GetOrInsertObject(&sequence_state, owned_object_id);
 
@@ -385,11 +386,11 @@
         storage_->mutable_heap_graph_reference_table()->Insert(
             {reference_set_id,
              owner_id,
-             owned_row_ref ? base::make_optional(owned_row_ref->id())
-                           : base::nullopt,
+             owned_row_ref ? std::make_optional(owned_row_ref->id())
+                           : std::nullopt,
              {},
              {},
-             /*deobfuscated_field_name=*/base::nullopt});
+             /*deobfuscated_field_name=*/std::nullopt});
     if (!obj.field_name_ids.empty()) {
       sequence_state.references_for_field_name_id[obj.field_name_ids[i]]
           .push_back(ref_id_and_row.row_number);
@@ -431,7 +432,7 @@
 void HeapGraphTracker::AddInternedType(uint32_t seq_id,
                                        uint64_t intern_id,
                                        StringId strid,
-                                       base::Optional<uint64_t> location_id,
+                                       std::optional<uint64_t> location_id,
                                        uint64_t object_size,
                                        std::vector<uint64_t> field_name_ids,
                                        uint64_t superclass_id,
@@ -534,7 +535,7 @@
   for (const auto& p : sequence_state.interned_types) {
     uint64_t id = p.first;
     const InternedType& interned_type = p.second;
-    base::Optional<StringId> location_name;
+    std::optional<StringId> location_name;
     if (interned_type.location_id) {
       auto it = sequence_state.interned_location_names.find(
           *interned_type.location_id);
@@ -622,9 +623,9 @@
     base::StringView normalized_type =
         NormalizeTypeName(storage_->GetString(interned_type.name));
 
-    base::Optional<StringId> class_package;
+    std::optional<StringId> class_package;
     if (location_name) {
-      base::Optional<std::string> package_name =
+      std::optional<std::string> package_name =
           PackageFromLocation(storage_, storage_->GetString(*location_name));
       if (package_name) {
         class_package = storage_->InternString(base::StringView(*package_name));
@@ -677,10 +678,10 @@
   sequence_state_.erase(seq_id);
 }
 
-base::Optional<ObjectTable::Id> HeapGraphTracker::GetReferenceByFieldName(
+std::optional<ObjectTable::Id> HeapGraphTracker::GetReferenceByFieldName(
     ObjectTable::Id obj,
     StringId field) {
-  base::Optional<ObjectTable::Id> referred;
+  std::optional<ObjectTable::Id> referred;
   auto obj_row_ref = *storage_->heap_graph_object_table().FindById(obj);
   ForReferenceSet(storage_, obj_row_ref,
                   [&](ReferenceTable::RowReference ref) -> bool {
@@ -732,16 +733,16 @@
          objects_tbl.graph_sample_ts().eq(seq.current_ts)});
     for (; obj_it; ++obj_it) {
       ObjectTable::Id cleaner_obj_id = obj_it.id();
-      base::Optional<ObjectTable::Id> referent_id =
+      std::optional<ObjectTable::Id> referent_id =
           GetReferenceByFieldName(cleaner_obj_id, referent_str_id_);
-      base::Optional<ObjectTable::Id> thunk_id =
+      std::optional<ObjectTable::Id> thunk_id =
           GetReferenceByFieldName(cleaner_obj_id, cleaner_thunk_str_id_);
 
       if (!referent_id || !thunk_id) {
         continue;
       }
 
-      base::Optional<ObjectTable::Id> next_id =
+      std::optional<ObjectTable::Id> next_id =
           GetReferenceByFieldName(cleaner_obj_id, cleaner_next_str_id_);
       if (next_id.has_value() && *next_id == cleaner_obj_id) {
         // sun.misc.Cleaner.next points to the sun.misc.Cleaner: this means
@@ -753,7 +754,7 @@
   }
 
   for (const auto& cleaner : cleaners) {
-    base::Optional<ObjectTable::Id> this0 =
+    std::optional<ObjectTable::Id> this0 =
         GetReferenceByFieldName(cleaner.thunk, cleaner_thunk_this0_str_id_);
     if (!this0) {
       continue;
@@ -844,14 +845,14 @@
     ClassTable::Id type_id = object_row_ref.type_id();
 
     auto type_row_ref = *storage->heap_graph_class_table().FindById(type_id);
-    base::Optional<StringId> opt_class_name_id =
+    std::optional<StringId> opt_class_name_id =
         type_row_ref.deobfuscated_name();
     if (!opt_class_name_id) {
       opt_class_name_id = type_row_ref.name();
     }
     PERFETTO_CHECK(opt_class_name_id);
     StringId class_name_id = *opt_class_name_id;
-    base::Optional<StringId> root_type = object_row_ref.root_type();
+    std::optional<StringId> root_type = object_row_ref.root_type();
     if (root_type) {
       class_name_id = storage->InternString(base::StringView(
           storage->GetString(class_name_id).ToStdString() + " [" +
@@ -938,7 +939,7 @@
 
   std::unique_ptr<tables::ExperimentalFlamegraphNodesTable> tbl(
       new tables::ExperimentalFlamegraphNodesTable(
-          storage_->mutable_string_pool(), nullptr));
+          storage_->mutable_string_pool()));
 
   auto it = roots_.find(std::make_pair(current_upid, current_ts));
   if (it == roots_.end()) {
@@ -957,7 +958,7 @@
       alloc_row.cumulative_count = 1;
       alloc_row.size = 1;
       alloc_row.cumulative_size = 1;
-      alloc_row.parent_id = base::nullopt;
+      alloc_row.parent_id = std::nullopt;
       tbl->Insert(alloc_row);
       return tbl;
     }
@@ -994,7 +995,7 @@
   for (size_t i = 1; i < init_path.nodes.size(); ++i) {
     const PathFromRoot::Node& node = init_path.nodes[i];
     PERFETTO_CHECK(node.parent_id < i);
-    base::Optional<FlamegraphId> parent_id;
+    std::optional<FlamegraphId> parent_id;
     if (node.parent_id != 0)
       parent_id = node_to_id[node.parent_id];
     const uint32_t depth = node.depth;
diff --git a/src/trace_processor/importers/proto/heap_graph_tracker.h b/src/trace_processor/importers/proto/heap_graph_tracker.h
index 6fd4fda..c2f184f 100644
--- a/src/trace_processor/importers/proto/heap_graph_tracker.h
+++ b/src/trace_processor/importers/proto/heap_graph_tracker.h
@@ -18,11 +18,11 @@
 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_HEAP_GRAPH_TRACKER_H_
 
 #include <map>
+#include <optional>
 #include <set>
 #include <utility>
 #include <vector>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 
 #include "protos/perfetto/trace/profiling/heap_graph.pbzero.h"
@@ -64,7 +64,7 @@
                       tables::HeapGraphObjectTable::RowReference,
                       PathFromRoot* path);
 
-base::Optional<base::StringView> GetStaticClassTypeName(base::StringView type);
+std::optional<base::StringView> GetStaticClassTypeName(base::StringView type);
 size_t NumberOfArrays(base::StringView type);
 NormalizedType GetNormalizedType(base::StringView type);
 base::StringView NormalizeTypeName(base::StringView type);
@@ -85,7 +85,7 @@
 
     // If this object is an instance of `libcore.util.NativeAllocationRegistry`,
     // this is the value of its `size` field.
-    base::Optional<int64_t> native_allocation_registry_size;
+    std::optional<int64_t> native_allocation_registry_size;
   };
 
   struct SourceRoot {
@@ -108,7 +108,7 @@
   void AddInternedType(uint32_t seq_id,
                        uint64_t intern_id,
                        StringId strid,
-                       base::Optional<uint64_t> location_id,
+                       std::optional<uint64_t> location_id,
                        uint64_t object_size,
                        std::vector<uint64_t> field_name_ids,
                        uint64_t superclass_id,
@@ -128,7 +128,7 @@
   ~HeapGraphTracker() override;
 
   const std::vector<tables::HeapGraphClassTable::RowNumber>* RowsForType(
-      base::Optional<StringId> package_name,
+      std::optional<StringId> package_name,
       StringId type_name) const {
     auto it = class_to_rows_.find(std::make_pair(package_name, type_name));
     if (it == class_to_rows_.end())
@@ -156,7 +156,7 @@
   };
   struct InternedType {
     StringId name;
-    base::Optional<uint64_t> location_id;
+    std::optional<uint64_t> location_id;
     uint64_t object_size;
     std::vector<uint64_t> field_name_ids;
     uint64_t superclass_id;
@@ -192,7 +192,7 @@
     std::map<tables::HeapGraphClassTable::Id,
              std::vector<tables::HeapGraphObjectTable::RowNumber>>
         deferred_reference_objects_for_type_;
-    base::Optional<uint64_t> prev_index;
+    std::optional<uint64_t> prev_index;
     // For most objects, we need not store the size in the object's message
     // itself, because all instances of the type have the same type. In this
     // case, we defer setting self_size in the table until we process the class
@@ -220,7 +220,7 @@
   bool IsTruncated(UniquePid upid, int64_t ts);
 
   // Returns the object pointed to by `field` in `obj`.
-  base::Optional<tables::HeapGraphObjectTable::Id> GetReferenceByFieldName(
+  std::optional<tables::HeapGraphObjectTable::Id> GetReferenceByFieldName(
       tables::HeapGraphObjectTable::Id obj,
       StringId field);
 
@@ -234,14 +234,14 @@
   TraceStorage* const storage_;
   std::map<uint32_t, SequenceState> sequence_state_;
 
-  std::map<std::pair<base::Optional<StringId>, StringId>,
+  std::map<std::pair<std::optional<StringId>, StringId>,
            std::vector<tables::HeapGraphClassTable::RowNumber>>
       class_to_rows_;
   base::FlatHashMap<StringId,
                     std::vector<tables::HeapGraphReferenceTable::RowNumber>>
       field_to_rows_;
 
-  std::map<std::pair<base::Optional<StringId>, StringId>, StringId>
+  std::map<std::pair<std::optional<StringId>, StringId>, StringId>
       deobfuscation_mapping_;
   std::map<std::pair<UniquePid, int64_t>,
            std::set<tables::HeapGraphObjectTable::RowNumber>>
diff --git a/src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc b/src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc
index 491082a..15be4ac 100644
--- a/src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc
+++ b/src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc
@@ -174,7 +174,7 @@
   const auto& class_table = context.storage->heap_graph_class_table();
   size_t count_bitmaps = 0;
   for (uint32_t obj_row = 0; obj_row < objs_table.row_count(); ++obj_row) {
-    base::Optional<uint32_t> class_row =
+    std::optional<uint32_t> class_row =
         class_table.id().IndexOf(objs_table.type_id()[obj_row]);
     ASSERT_TRUE(class_row.has_value());
     if (context.storage->string_pool().Get(class_table.name()[*class_row]) ==
diff --git a/src/trace_processor/importers/proto/heap_profile_tracker.h b/src/trace_processor/importers/proto/heap_profile_tracker.h
index 03b1d7b..5ed5394 100644
--- a/src/trace_processor/importers/proto/heap_profile_tracker.h
+++ b/src/trace_processor/importers/proto/heap_profile_tracker.h
@@ -17,10 +17,10 @@
 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_HEAP_PROFILE_TRACKER_H_
 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_HEAP_PROFILE_TRACKER_H_
 
+#include <optional>
 #include <set>
 #include <unordered_map>
 
-#include "perfetto/ext/base/optional.h"
 #include "src/trace_processor/importers/proto/stack_profile_tracker.h"
 #include "src/trace_processor/storage/trace_storage.h"
 
@@ -112,7 +112,7 @@
              tables::HeapProfileAllocationTable::Row>
         free_correction;
 
-    base::Optional<uint64_t> prev_index;
+    std::optional<uint64_t> prev_index;
   };
   std::map<uint32_t, SequenceState> sequence_state_;
   TraceProcessorContext* const context_;
diff --git a/src/trace_processor/importers/proto/heap_profile_tracker_unittest.cc b/src/trace_processor/importers/proto/heap_profile_tracker_unittest.cc
index 0ac2608..558ad91 100644
--- a/src/trace_processor/importers/proto/heap_profile_tracker_unittest.cc
+++ b/src/trace_processor/importers/proto/heap_profile_tracker_unittest.cc
@@ -174,17 +174,17 @@
   EXPECT_EQ(depth[0], 0u);
   EXPECT_EQ(depth[1], 1u);
 
-  EXPECT_EQ(parent_id[0], base::nullopt);
+  EXPECT_EQ(parent_id[0], std::nullopt);
   EXPECT_EQ(parent_id[1], CallsiteId{0});
 
   EXPECT_EQ(frame_id[0], FrameId{0});
   EXPECT_EQ(frame_id[1], FrameId{0});
 }
 
-base::Optional<CallsiteId> FindCallstack(const TraceStorage& storage,
-                                         int64_t depth,
-                                         base::Optional<CallsiteId> parent,
-                                         FrameId frame_id) {
+std::optional<CallsiteId> FindCallstack(const TraceStorage& storage,
+                                        int64_t depth,
+                                        std::optional<CallsiteId> parent,
+                                        FrameId frame_id) {
   const auto& callsites = storage.stack_profile_callsite_table();
   for (uint32_t i = 0; i < callsites.row_count(); ++i) {
     if (callsites.depth()[i] == depth && callsites.parent_id()[i] == parent &&
@@ -192,7 +192,7 @@
       return callsites.id()[i];
     }
   }
-  return base::nullopt;
+  return std::nullopt;
 }
 
 TEST(HeapProfileTrackerTest, SourceMappingPath) {
@@ -224,7 +224,7 @@
   spt->AddMapping(0, mapping);
   hpt->CommitAllocations(kDefaultSequence, spt.get(), nullptr);
   auto foo_bar_id = context.storage->string_pool().GetId("/foo/bar");
-  ASSERT_NE(foo_bar_id, base::nullopt);
+  ASSERT_NE(foo_bar_id, std::nullopt);
   EXPECT_THAT(context.storage->stack_profile_mapping_table().name()[0],
               *foo_bar_id);
 }
@@ -331,12 +331,12 @@
   hpt->CommitAllocations(kDefaultSequence, spt.get(), nullptr);
 
   for (size_t i = 0; i < base::ArraySize(callstacks); ++i) {
-    base::Optional<CallsiteId> parent;
+    std::optional<CallsiteId> parent;
     const SequenceStackProfileTracker::SourceCallstack& callstack =
         callstacks[i];
     for (size_t depth = 0; depth < callstack.size(); ++depth) {
       auto frame_id = spt->GetDatabaseFrameIdForTesting(callstack[depth]);
-      base::Optional<CallsiteId> self = FindCallstack(
+      std::optional<CallsiteId> self = FindCallstack(
           *context.storage, static_cast<int64_t>(depth), parent, frame_id);
       ASSERT_TRUE(self.has_value());
       parent = self;
diff --git a/src/trace_processor/importers/proto/memory_tracker_snapshot_parser.cc b/src/trace_processor/importers/proto/memory_tracker_snapshot_parser.cc
index 3c1683f..c4eeeff 100644
--- a/src/trace_processor/importers/proto/memory_tracker_snapshot_parser.cc
+++ b/src/trace_processor/importers/proto/memory_tracker_snapshot_parser.cc
@@ -20,7 +20,7 @@
 #include "protos/perfetto/trace/memory_graph.pbzero.h"
 #include "src/trace_processor/containers/string_pool.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
-#include "src/trace_processor/tables/memory_tables.h"
+#include "src/trace_processor/tables/memory_tables_py.h"
 
 namespace perfetto {
 namespace trace_processor {
@@ -228,17 +228,17 @@
     ProcessMemorySnapshotId& proc_snapshot_row_id,
     IdNodeMap& id_node_map) {
   EmitMemorySnapshotNodeRowsRecursively(root_node_graph, std::string(),
-                                        base::nullopt, proc_snapshot_row_id,
+                                        std::nullopt, proc_snapshot_row_id,
                                         id_node_map);
 }
 
 void MemoryTrackerSnapshotParser::EmitMemorySnapshotNodeRowsRecursively(
     GlobalNodeGraph::Node& node,
     const std::string& path,
-    base::Optional<tables::MemorySnapshotNodeTable::Id> parent_node_row_id,
+    std::optional<tables::MemorySnapshotNodeTable::Id> parent_node_row_id,
     ProcessMemorySnapshotId& proc_snapshot_row_id,
     IdNodeMap& id_node_map) {
-  base::Optional<tables::MemorySnapshotNodeTable::Id> node_id;
+  std::optional<tables::MemorySnapshotNodeTable::Id> node_id;
   // Skip emitting the root node into the tables - it is not a real node.
   if (!path.empty()) {
     node_id = EmitNode(node, path, parent_node_row_id, proc_snapshot_row_id,
@@ -257,11 +257,11 @@
   }
 }
 
-base::Optional<tables::MemorySnapshotNodeTable::Id>
+std::optional<tables::MemorySnapshotNodeTable::Id>
 MemoryTrackerSnapshotParser::EmitNode(
     const GlobalNodeGraph::Node& node,
     const std::string& path,
-    base::Optional<tables::MemorySnapshotNodeTable::Id> parent_node_row_id,
+    std::optional<tables::MemorySnapshotNodeTable::Id> parent_node_row_id,
     ProcessMemorySnapshotId& proc_snapshot_row_id,
     IdNodeMap& id_node_map) {
   tables::MemorySnapshotNodeTable::Row node_row;
diff --git a/src/trace_processor/importers/proto/memory_tracker_snapshot_parser.h b/src/trace_processor/importers/proto/memory_tracker_snapshot_parser.h
index 32119c2..deec274 100644
--- a/src/trace_processor/importers/proto/memory_tracker_snapshot_parser.h
+++ b/src/trace_processor/importers/proto/memory_tracker_snapshot_parser.h
@@ -90,7 +90,7 @@
   void EmitMemorySnapshotNodeRowsRecursively(
       GlobalNodeGraph::Node& node,
       const std::string&,
-      base::Optional<tables::MemorySnapshotNodeTable::Id> parent_node_row_id,
+      std::optional<tables::MemorySnapshotNodeTable::Id> parent_node_row_id,
       ProcessMemorySnapshotId& proc_snapshot_row_id,
       IdNodeMap& id_node_map);
 
@@ -99,10 +99,10 @@
   // ProcessMemorySnapshotId |proc_snapshot_row_id|. Generates map of
   // MemoryAllocatorNodeId and MemorySnapshotNodeTable::Id |id_node_map| which
   // is used at time of filling out of MemorySnapshotEdgeTable.
-  base::Optional<tables::MemorySnapshotNodeTable::Id> EmitNode(
+  std::optional<tables::MemorySnapshotNodeTable::Id> EmitNode(
       const GlobalNodeGraph::Node& node,
       const std::string& path,
-      base::Optional<tables::MemorySnapshotNodeTable::Id> parent_node_row_id,
+      std::optional<tables::MemorySnapshotNodeTable::Id> parent_node_row_id,
       ProcessMemorySnapshotId& proc_snapshot_row_id,
       IdNodeMap& id_node_map);
 
diff --git a/src/trace_processor/importers/proto/metadata_minimal_module.cc b/src/trace_processor/importers/proto/metadata_minimal_module.cc
index d29b3d3..099cdac 100644
--- a/src/trace_processor/importers/proto/metadata_minimal_module.cc
+++ b/src/trace_processor/importers/proto/metadata_minimal_module.cc
@@ -17,7 +17,7 @@
 #include "src/trace_processor/importers/proto/metadata_minimal_module.h"
 
 #include "perfetto/ext/base/base64.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/types/trace_processor_context.h"
 
 #include "protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.h"
diff --git a/src/trace_processor/importers/proto/metadata_module.cc b/src/trace_processor/importers/proto/metadata_module.cc
index 81a4ce6..3374043 100644
--- a/src/trace_processor/importers/proto/metadata_module.cc
+++ b/src/trace_processor/importers/proto/metadata_module.cc
@@ -18,10 +18,10 @@
 
 #include "perfetto/ext/base/base64.h"
 #include "perfetto/ext/base/uuid.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/importers/common/slice_tracker.h"
 #include "src/trace_processor/importers/common/track_tracker.h"
 #include "src/trace_processor/importers/proto/config.descriptor.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
 #include "src/trace_processor/util/descriptors.h"
 #include "src/trace_processor/util/protozero_to_text.h"
 
diff --git a/src/trace_processor/importers/proto/network_trace_module.cc b/src/trace_processor/importers/proto/network_trace_module.cc
index ab56358..321152e 100644
--- a/src/trace_processor/importers/proto/network_trace_module.cc
+++ b/src/trace_processor/importers/proto/network_trace_module.cc
@@ -17,7 +17,6 @@
 #include "src/trace_processor/importers/proto/network_trace_module.h"
 
 #include "perfetto/ext/base/string_writer.h"
-#include "protos/perfetto/trace/android/network_trace.pbzero.h"
 #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
 #include "protos/perfetto/trace/trace_packet.pbzero.h"
 #include "src/trace_processor/importers/common/async_track_set_tracker.h"
@@ -61,7 +60,8 @@
       net_arg_local_port_(context->storage->InternString("local_port")),
       net_arg_remote_port_(context->storage->InternString("remote_port")),
       net_ipproto_tcp_(context->storage->InternString("IPPROTO_TCP")),
-      net_ipproto_udp_(context->storage->InternString("IPPROTO_UDP")) {
+      net_ipproto_udp_(context->storage->InternString("IPPROTO_UDP")),
+      packet_count_(context->storage->InternString("packet_count")) {
   RegisterForField(TracePacket::kNetworkPacketFieldNumber, context);
   RegisterForField(TracePacket::kNetworkPacketBundleFieldNumber, context);
 }
@@ -132,14 +132,17 @@
     case TracePacket::kNetworkPacketFieldNumber:
       ParseNetworkPacketEvent(ts, decoder.network_packet());
       return;
+    case TracePacket::kNetworkPacketBundleFieldNumber:
+      ParseNetworkPacketBundle(ts, decoder.network_packet_bundle());
+      return;
   }
 }
 
-void NetworkTraceModule::ParseNetworkPacketEvent(int64_t ts, ConstBytes blob) {
-  using protos::pbzero::NetworkPacketEvent;
-  using protos::pbzero::TrafficDirection;
-  NetworkPacketEvent::Decoder evt(blob);
-
+void NetworkTraceModule::ParseGenericEvent(
+    int64_t ts,
+    int64_t dur,
+    protos::pbzero::NetworkPacketEvent::Decoder& evt,
+    std::function<void(ArgsTracker::BoundInserter*)> extra_args) {
   // Tracks are per interface and per direction.
   const char* track_suffix =
       evt.direction() == TrafficDirection::DIR_INGRESS  ? " Received"
@@ -154,7 +157,7 @@
   StringId title_id = kNullStringId;
   if (evt.uid() > 0) {
     const auto& package_list = context_->storage->package_list_table();
-    base::Optional<uint32_t> pkg_row = package_list.uid().IndexOf(evt.uid());
+    std::optional<uint32_t> pkg_row = package_list.uid().IndexOf(evt.uid());
     if (pkg_row) {
       title_id = package_list.package_name()[*pkg_row];
     }
@@ -167,12 +170,11 @@
   }
 
   TrackId track_id = context_->async_track_set_tracker->Scoped(
-      context_->async_track_set_tracker->InternGlobalTrackSet(name_id), ts, 0);
+      context_->async_track_set_tracker->InternGlobalTrackSet(name_id), ts,
+      dur);
 
   context_->slice_tracker->Scoped(
-      ts, track_id, name_id, title_id, 0, [&](ArgsTracker::BoundInserter* i) {
-        i->AddArg(net_arg_length_, Variadic::Integer(evt.length()));
-
+      ts, track_id, name_id, title_id, dur, [&](ArgsTracker::BoundInserter* i) {
         StringId ip_proto;
         if (evt.ip_proto() == kIpprotoTcp) {
           ip_proto = net_ipproto_tcp_;
@@ -197,9 +199,30 @@
 
         i->AddArg(net_arg_local_port_, Variadic::Integer(evt.local_port()));
         i->AddArg(net_arg_remote_port_, Variadic::Integer(evt.remote_port()));
+        extra_args(i);
       });
 }
 
+void NetworkTraceModule::ParseNetworkPacketEvent(int64_t ts, ConstBytes blob) {
+  NetworkPacketEvent::Decoder event(blob);
+  ParseGenericEvent(ts, /*dur=*/0, event, [&](ArgsTracker::BoundInserter* i) {
+    i->AddArg(net_arg_length_, Variadic::Integer(event.length()));
+  });
+}
+
+void NetworkTraceModule::ParseNetworkPacketBundle(int64_t ts, ConstBytes blob) {
+  NetworkPacketBundle::Decoder event(blob);
+  NetworkPacketEvent::Decoder ctx(event.ctx());
+  int64_t dur = static_cast<int64_t>(event.total_duration());
+
+  // Any bundle that makes it through tokenization must be aggregated bundles
+  // with total packets/total length.
+  ParseGenericEvent(ts, dur, ctx, [&](ArgsTracker::BoundInserter* i) {
+    i->AddArg(net_arg_length_, Variadic::UnsignedInteger(event.total_length()));
+    i->AddArg(packet_count_, Variadic::UnsignedInteger(event.total_packets()));
+  });
+}
+
 void NetworkTraceModule::PushPacketBufferForSort(int64_t timestamp,
                                                  PacketSequenceState* state) {
   std::vector<uint8_t> v = packet_buffer_.SerializeAsArray();
diff --git a/src/trace_processor/importers/proto/network_trace_module.h b/src/trace_processor/importers/proto/network_trace_module.h
index 843f055..e83ce7b 100644
--- a/src/trace_processor/importers/proto/network_trace_module.h
+++ b/src/trace_processor/importers/proto/network_trace_module.h
@@ -20,7 +20,9 @@
 #include <cstdint>
 
 #include "perfetto/protozero/scattered_heap_buffer.h"
+#include "protos/perfetto/trace/android/network_trace.pbzero.h"
 #include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "src/trace_processor/importers/common/args_tracker.h"
 #include "src/trace_processor/importers/common/parser_types.h"
 #include "src/trace_processor/importers/proto/proto_importer_module.h"
 #include "src/trace_processor/storage/trace_storage.h"
@@ -52,7 +54,14 @@
                             uint32_t field_id) override;
 
  private:
+  void ParseGenericEvent(
+      int64_t ts,
+      int64_t dur,
+      protos::pbzero::NetworkPacketEvent::Decoder& evt,
+      std::function<void(ArgsTracker::BoundInserter*)> extra_args);
+
   void ParseNetworkPacketEvent(int64_t ts, protozero::ConstBytes blob);
+  void ParseNetworkPacketBundle(int64_t ts, protozero::ConstBytes blob);
 
   // Helper to simplify pushing a TracePacket to the sorter. The caller fills in
   // the packet buffer and uses this to push for sorting and reset the buffer.
@@ -69,6 +78,7 @@
   const StringId net_arg_remote_port_;
   const StringId net_ipproto_tcp_;
   const StringId net_ipproto_udp_;
+  const StringId packet_count_;
 };
 
 }  // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/network_trace_module_unittest.cc b/src/trace_processor/importers/proto/network_trace_module_unittest.cc
new file mode 100644
index 0000000..56118c5
--- /dev/null
+++ b/src/trace_processor/importers/proto/network_trace_module_unittest.cc
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/importers/proto/network_trace_module.h"
+
+#include "src/trace_processor/importers/common/args_tracker.h"
+#include "src/trace_processor/importers/common/args_translation_table.h"
+#include "src/trace_processor/importers/common/async_track_set_tracker.h"
+#include "src/trace_processor/importers/common/global_args_tracker.h"
+#include "src/trace_processor/importers/common/slice_tracker.h"
+#include "src/trace_processor/importers/common/slice_translation_table.h"
+#include "src/trace_processor/importers/common/track_tracker.h"
+#include "src/trace_processor/importers/proto/proto_trace_parser.h"
+#include "src/trace_processor/importers/proto/proto_trace_reader.h"
+#include "src/trace_processor/sorter/trace_sorter.h"
+#include "src/trace_processor/types/trace_processor_context.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace {
+using ::perfetto::protos::pbzero::TrafficDirection;
+
+class NetworkTraceModuleTest : public testing::Test {
+ public:
+  NetworkTraceModuleTest() {
+    context_.storage.reset(new TraceStorage());
+    storage_ = context_.storage.get();
+
+    context_.track_tracker.reset(new TrackTracker(&context_));
+    context_.slice_tracker.reset(new SliceTracker(&context_));
+    context_.args_tracker.reset(new ArgsTracker(&context_));
+    context_.global_args_tracker.reset(new GlobalArgsTracker(storage_));
+    context_.slice_translation_table.reset(new SliceTranslationTable(storage_));
+    context_.args_translation_table.reset(new ArgsTranslationTable(storage_));
+    context_.async_track_set_tracker.reset(new AsyncTrackSetTracker(&context_));
+    context_.sorter.reset(new TraceSorter(
+        &context_, std::make_unique<ProtoTraceParser>(&context_),
+        TraceSorter::SortingMode::kFullSort));
+  }
+
+  util::Status TokenizeAndParse() {
+    context_.chunk_reader.reset(new ProtoTraceReader(&context_));
+
+    trace_->Finalize();
+    std::vector<uint8_t> v = trace_.SerializeAsArray();
+    trace_.Reset();
+
+    auto status = context_.chunk_reader->Parse(
+        TraceBlobView(TraceBlob::CopyFrom(v.data(), v.size())));
+    context_.sorter->ExtractEventsForced();
+    context_.slice_tracker->FlushPendingSlices();
+    context_.args_tracker->Flush();
+    return status;
+  }
+
+  bool HasArg(ArgSetId set_id, base::StringView key, Variadic value) {
+    StringId key_id = storage_->InternString(key);
+    const auto& args = storage_->arg_table();
+    RowMap rm = args.FilterToRowMap({args.arg_set_id().eq(set_id)});
+    bool found = false;
+    for (auto it = rm.IterateRows(); it; it.Next()) {
+      if (args.key()[it.index()] == key_id) {
+        EXPECT_EQ(args.flat_key()[it.index()], key_id);
+        if (storage_->GetArgValue(it.index()) == value) {
+          found = true;
+          break;
+        }
+      }
+    }
+    return found;
+  }
+
+ protected:
+  protozero::HeapBuffered<protos::pbzero::Trace> trace_;
+  TraceProcessorContext context_;
+  TraceStorage* storage_;
+};
+
+TEST_F(NetworkTraceModuleTest, ParseAndFormatPacket) {
+  NetworkTraceModule module(&context_);
+
+  auto* packet = trace_->add_packet();
+  packet->set_timestamp(123);
+
+  auto* event = packet->set_network_packet();
+  event->set_direction(TrafficDirection::DIR_EGRESS);
+  event->set_length(72);
+  event->set_uid(1010);
+  event->set_tag(0x407);
+  event->set_local_port(5100);
+  event->set_remote_port(443);
+  event->set_tcp_flags(0b10010);
+  event->set_ip_proto(6);
+  event->set_interface("wlan");
+
+  ASSERT_TRUE(TokenizeAndParse().ok());
+
+  const auto& slices = storage_->slice_table();
+  ASSERT_EQ(slices.row_count(), 1u);
+  EXPECT_EQ(slices.ts()[0], 123);
+
+  EXPECT_TRUE(HasArg(1u, "packet_length", Variadic::Integer(72)));
+  EXPECT_TRUE(HasArg(1u, "local_port", Variadic::Integer(5100)));
+  EXPECT_TRUE(HasArg(1u, "remote_port", Variadic::Integer(443)));
+  EXPECT_TRUE(HasArg(1u, "packet_transport",
+                     Variadic::String(storage_->InternString("IPPROTO_TCP"))));
+  EXPECT_TRUE(HasArg(1u, "socket_tag",
+                     Variadic::String(storage_->InternString("0x407"))));
+  EXPECT_TRUE(HasArg(1u, "packet_tcp_flags",
+                     Variadic::String(storage_->InternString(".s..a..."))));
+}
+
+TEST_F(NetworkTraceModuleTest, TokenizeAndParsePerPacketBundle) {
+  NetworkTraceModule module(&context_);
+
+  auto* packet = trace_->add_packet();
+  packet->set_timestamp(123);
+
+  protozero::PackedVarInt timestamps;
+  timestamps.Append(0);
+  timestamps.Append(10);
+
+  protozero::PackedVarInt lengths;
+  lengths.Append(72);
+  lengths.Append(100);
+
+  auto* event = packet->set_network_packet_bundle();
+  event->set_packet_timestamps(timestamps);
+  event->set_packet_lengths(lengths);
+
+  auto* ctx = event->set_ctx();
+  ctx->set_uid(456);
+
+  ASSERT_TRUE(TokenizeAndParse().ok());
+
+  const auto& slices = storage_->slice_table();
+  ASSERT_EQ(slices.row_count(), 2u);
+  EXPECT_EQ(slices.ts()[0], 123);
+  EXPECT_EQ(slices.ts()[1], 133);
+
+  EXPECT_TRUE(HasArg(1u, "packet_length", Variadic::Integer(72)));
+  EXPECT_TRUE(HasArg(2u, "packet_length", Variadic::Integer(100)));
+}
+
+TEST_F(NetworkTraceModuleTest, TokenizeAndParseAggregateBundle) {
+  NetworkTraceModule module(&context_);
+
+  auto* packet = trace_->add_packet();
+  packet->set_timestamp(123);
+
+  auto* event = packet->set_network_packet_bundle();
+  event->set_total_packets(2);
+  event->set_total_duration(10);
+  event->set_total_length(172);
+
+  auto* ctx = event->set_ctx();
+  ctx->set_uid(456);
+
+  ASSERT_TRUE(TokenizeAndParse().ok());
+
+  const auto& slices = storage_->slice_table();
+  ASSERT_EQ(slices.row_count(), 1u);
+  EXPECT_EQ(slices.ts()[0], 123);
+  EXPECT_EQ(slices.dur()[0], 10);
+
+  EXPECT_TRUE(HasArg(1u, "packet_length", Variadic::UnsignedInteger(172)));
+  EXPECT_TRUE(HasArg(1u, "packet_count", Variadic::UnsignedInteger(2)));
+}
+
+}  // namespace
+}  // namespace trace_processor
+}  // namespace perfetto
diff --git a/src/trace_processor/importers/proto/packet_sequence_state_generation.h b/src/trace_processor/importers/proto/packet_sequence_state_generation.h
index c3dda05..9c7aa5a 100644
--- a/src/trace_processor/importers/proto/packet_sequence_state_generation.h
+++ b/src/trace_processor/importers/proto/packet_sequence_state_generation.h
@@ -17,9 +17,9 @@
 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PACKET_SEQUENCE_STATE_GENERATION_H_
 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PACKET_SEQUENCE_STATE_GENERATION_H_
 
+#include <optional>
 #include <unordered_map>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/trace_processor/ref_counted.h"
 #include "src/trace_processor/util/interned_message_view.h"
 
@@ -106,7 +106,7 @@
   PacketSequenceState* state_;
   size_t generation_index_;
   InternedFieldMap interned_data_;
-  base::Optional<InternedMessageView> trace_packet_defaults_;
+  std::optional<InternedMessageView> trace_packet_defaults_;
 };
 
 }  // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/perf_sample_tracker.cc b/src/trace_processor/importers/proto/perf_sample_tracker.cc
index aad2013..0105985 100644
--- a/src/trace_processor/importers/proto/perf_sample_tracker.cc
+++ b/src/trace_processor/importers/proto/perf_sample_tracker.cc
@@ -135,7 +135,7 @@
   if (cpu_it != seq_state->per_cpu.end())
     return {seq_state->perf_session_id, cpu_it->second.timebase_track_id};
 
-  base::Optional<PerfSampleDefaults::Decoder> perf_defaults;
+  std::optional<PerfSampleDefaults::Decoder> perf_defaults;
   if (nullable_defaults && nullable_defaults->has_perf_sample_defaults()) {
     perf_defaults.emplace(nullable_defaults->perf_sample_defaults());
   }
diff --git a/src/trace_processor/importers/proto/perf_sample_tracker_unittest.cc b/src/trace_processor/importers/proto/perf_sample_tracker_unittest.cc
index 61819a9..7515a04 100644
--- a/src/trace_processor/importers/proto/perf_sample_tracker_unittest.cc
+++ b/src/trace_processor/importers/proto/perf_sample_tracker_unittest.cc
@@ -213,10 +213,10 @@
 
   EXPECT_NE(stream.perf_session_id, stream2.perf_session_id);
 
-  base::Optional<int64_t> shard_count = context.storage->GetIndexedStats(
+  std::optional<int64_t> shard_count = context.storage->GetIndexedStats(
       stats::perf_process_shard_count,
       static_cast<int>(stream.perf_session_id));
-  base::Optional<int64_t> chosen_shard = context.storage->GetIndexedStats(
+  std::optional<int64_t> chosen_shard = context.storage->GetIndexedStats(
       stats::perf_chosen_process_shard,
       static_cast<int>(stream.perf_session_id));
 
@@ -225,10 +225,10 @@
   ASSERT_TRUE(chosen_shard.has_value());
   EXPECT_EQ(chosen_shard.value(), 7);
 
-  base::Optional<int64_t> shard_count2 = context.storage->GetIndexedStats(
+  std::optional<int64_t> shard_count2 = context.storage->GetIndexedStats(
       stats::perf_process_shard_count,
       static_cast<int>(stream.perf_session_id));
-  base::Optional<int64_t> chosen_shard2 = context.storage->GetIndexedStats(
+  std::optional<int64_t> chosen_shard2 = context.storage->GetIndexedStats(
       stats::perf_chosen_process_shard,
       static_cast<int>(stream.perf_session_id));
 
diff --git a/src/trace_processor/importers/proto/profile_module.cc b/src/trace_processor/importers/proto/profile_module.cc
index 6294782..c337869 100644
--- a/src/trace_processor/importers/proto/profile_module.cc
+++ b/src/trace_processor/importers/proto/profile_module.cc
@@ -34,7 +34,7 @@
 #include "src/trace_processor/sorter/trace_sorter.h"
 #include "src/trace_processor/storage/stats.h"
 #include "src/trace_processor/storage/trace_storage.h"
-#include "src/trace_processor/tables/profiler_tables.h"
+#include "src/trace_processor/tables/profiler_tables_py.h"
 #include "src/trace_processor/types/trace_processor_context.h"
 #include "src/trace_processor/util/stack_traces_util.h"
 
@@ -251,7 +251,7 @@
       sequence_state->state()->sequence_stack_profile_tracker();
   ProfilePacketInternLookup intern_lookup(sequence_state);
   uint64_t callstack_iid = sample.callstack_iid();
-  base::Optional<CallsiteId> cs_id =
+  std::optional<CallsiteId> cs_id =
       stack_tracker.FindOrInsertCallstack(callstack_iid, &intern_lookup);
 
   // A failed lookup of the interned callstack can mean either:
@@ -285,7 +285,7 @@
   StringPool::Id cpu_mode_id =
       storage->InternString(ProfilePacketUtils::StringifyCpuMode(cpu_mode));
 
-  base::Optional<StringPool::Id> unwind_error_id;
+  std::optional<StringPool::Id> unwind_error_id;
   if (sample.has_unwind_error()) {
     auto unwind_error =
         static_cast<Profiling::StackUnwindError>(sample.unwind_error());
diff --git a/src/trace_processor/importers/proto/profile_packet_utils.h b/src/trace_processor/importers/proto/profile_packet_utils.h
index 683348c..64b2c50 100644
--- a/src/trace_processor/importers/proto/profile_packet_utils.h
+++ b/src/trace_processor/importers/proto/profile_packet_utils.h
@@ -16,8 +16,8 @@
 
 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROFILE_PACKET_UTILS_H_
 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROFILE_PACKET_UTILS_H_
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 #include "src/trace_processor/importers/proto/packet_sequence_state.h"
 #include "src/trace_processor/importers/proto/stack_profile_tracker.h"
@@ -133,7 +133,7 @@
       : seq_state_(seq_state) {}
   ~ProfilePacketInternLookup() override;
 
-  base::Optional<base::StringView> GetString(
+  std::optional<base::StringView> GetString(
       SequenceStackProfileTracker::SourceStringId iid,
       SequenceStackProfileTracker::InternedStringType type) const override {
     protos::pbzero::InternedString::Decoder* decoder = nullptr;
@@ -155,37 +155,37 @@
         break;
     }
     if (!decoder)
-      return base::nullopt;
+      return std::nullopt;
     return base::StringView(reinterpret_cast<const char*>(decoder->str().data),
                             decoder->str().size);
   }
 
-  base::Optional<SequenceStackProfileTracker::SourceMapping> GetMapping(
+  std::optional<SequenceStackProfileTracker::SourceMapping> GetMapping(
       SequenceStackProfileTracker::SourceMappingId iid) const override {
     auto* decoder = seq_state_->LookupInternedMessage<
         protos::pbzero::InternedData::kMappingsFieldNumber,
         protos::pbzero::Mapping>(iid);
     if (!decoder)
-      return base::nullopt;
+      return std::nullopt;
     return ProfilePacketUtils::MakeSourceMapping(*decoder);
   }
 
-  base::Optional<SequenceStackProfileTracker::SourceFrame> GetFrame(
+  std::optional<SequenceStackProfileTracker::SourceFrame> GetFrame(
       SequenceStackProfileTracker::SourceFrameId iid) const override {
     auto* decoder = seq_state_->LookupInternedMessage<
         protos::pbzero::InternedData::kFramesFieldNumber,
         protos::pbzero::Frame>(iid);
     if (!decoder)
-      return base::nullopt;
+      return std::nullopt;
     return ProfilePacketUtils::MakeSourceFrame(*decoder);
   }
 
-  base::Optional<SequenceStackProfileTracker::SourceCallstack> GetCallstack(
+  std::optional<SequenceStackProfileTracker::SourceCallstack> GetCallstack(
       SequenceStackProfileTracker::SourceCallstackId iid) const override {
     auto* interned_message_view = seq_state_->GetInternedMessageView(
         protos::pbzero::InternedData::kCallstacksFieldNumber, iid);
     if (!interned_message_view)
-      return base::nullopt;
+      return std::nullopt;
     protos::pbzero::Callstack::Decoder decoder(
         interned_message_view->message().data(),
         interned_message_view->message().length());
diff --git a/src/trace_processor/importers/proto/profiler_util.cc b/src/trace_processor/importers/proto/profiler_util.cc
index 315eb45..79a5448 100644
--- a/src/trace_processor/importers/proto/profiler_util.cc
+++ b/src/trace_processor/importers/proto/profiler_util.cc
@@ -15,8 +15,8 @@
  */
 
 #include "src/trace_processor/importers/proto/profiler_util.h"
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "src/trace_processor/storage/trace_storage.h"
 
@@ -29,32 +29,32 @@
 // * /data/app/~~[randomStringA]/[packageName]-[randomStringB]/base.apk
 // The latter is newer (R+), and was added to avoid leaking package names via
 // mountinfo of incremental apk mounts.
-base::Optional<base::StringView> PackageFromApp(base::StringView location) {
+std::optional<base::StringView> PackageFromApp(base::StringView location) {
   location = location.substr(base::StringView("/data/app/").size());
   size_t start = 0;
   if (location.at(0) == '~') {
     size_t slash = location.find('/');
     if (slash == base::StringView::npos) {
-      return base::nullopt;
+      return std::nullopt;
     }
     start = slash + 1;
   }
   size_t end = location.find('/', start + 1);
   if (end == base::StringView::npos) {
-    return base::nullopt;
+    return std::nullopt;
   }
   location = location.substr(start, end);
   size_t minus = location.find('-');
   if (minus == base::StringView::npos) {
-    return base::nullopt;
+    return std::nullopt;
   }
   return location.substr(0, minus);
 }
 
 }  // namespace
 
-base::Optional<std::string> PackageFromLocation(TraceStorage* storage,
-                                                base::StringView location) {
+std::optional<std::string> PackageFromLocation(TraceStorage* storage,
+                                               base::StringView location) {
   // List of some hardcoded apps that do not follow the scheme used in
   // PackageFromApp. Ask for yours to be added.
   //
@@ -146,12 +146,12 @@
   // Deal with paths to /data/app/...
 
   auto extract_package =
-      [storage](base::StringView path) -> base::Optional<std::string> {
+      [storage](base::StringView path) -> std::optional<std::string> {
     auto package = PackageFromApp(path);
     if (!package) {
       PERFETTO_DLOG("Failed to parse %s", path.ToStdString().c_str());
       storage->IncrementStats(stats::deobfuscate_location_parse_error);
-      return base::nullopt;
+      return std::nullopt;
     }
     return package->ToStdString();
   };
@@ -176,7 +176,7 @@
     return extract_package(data_app_path);
   }
 
-  return base::nullopt;
+  return std::nullopt;
 }
 
 std::string FullyQualifiedDeobfuscatedName(
diff --git a/src/trace_processor/importers/proto/profiler_util.h b/src/trace_processor/importers/proto/profiler_util.h
index 6e9ca99..cbf8ad1 100644
--- a/src/trace_processor/importers/proto/profiler_util.h
+++ b/src/trace_processor/importers/proto/profiler_util.h
@@ -17,9 +17,9 @@
 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROFILER_UTIL_H_
 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROFILER_UTIL_H_
 
+#include <optional>
 #include <string>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 #include "src/trace_processor/storage/trace_storage.h"
 
@@ -32,8 +32,8 @@
     protos::pbzero::ObfuscatedClass::Decoder& cls,
     protos::pbzero::ObfuscatedMember::Decoder& member);
 
-base::Optional<std::string> PackageFromLocation(TraceStorage* storage,
-                                                base::StringView location);
+std::optional<std::string> PackageFromLocation(TraceStorage* storage,
+                                               base::StringView location);
 
 }  // namespace trace_processor
 }  // namespace perfetto
diff --git a/src/trace_processor/importers/proto/proto_importer_module.h b/src/trace_processor/importers/proto/proto_importer_module.h
index 3ff56aa..cc2c3a2 100644
--- a/src/trace_processor/importers/proto/proto_importer_module.h
+++ b/src/trace_processor/importers/proto/proto_importer_module.h
@@ -17,8 +17,9 @@
 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_IMPORTER_MODULE_H_
 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_IMPORTER_MODULE_H_
 
+#include <optional>
+
 #include "perfetto/base/status.h"
-#include "perfetto/ext/base/optional.h"
 #include "src/trace_processor/importers/common/trace_parser.h"
 
 namespace perfetto {
@@ -54,8 +55,8 @@
   // Allow auto conversion from util::Status to Handled / Error result.
   ModuleResult(base::Status status)
       : ignored_(false),
-        error_(status.ok() ? base::nullopt
-                           : base::make_optional(status.message())) {}
+        error_(status.ok() ? std::nullopt
+                           : std::make_optional(status.message())) {}
 
   // Constructs a result that indicates the module ignored the packet and is
   // deferring the handling of the packet to other modules.
@@ -88,7 +89,7 @@
       : ignored_(false), error_(error) {}
 
   bool ignored_;
-  base::Optional<std::string> error_;
+  std::optional<std::string> error_;
 };
 
 // Base class for modules.
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.cc b/src/trace_processor/importers/proto/proto_trace_parser.cc
index 600b886..fa1ffd6 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser.cc
@@ -30,12 +30,12 @@
 
 #include "src/trace_processor/importers/common/args_tracker.h"
 #include "src/trace_processor/importers/common/event_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/importers/common/parser_types.h"
 #include "src/trace_processor/importers/common/process_tracker.h"
 #include "src/trace_processor/importers/common/slice_tracker.h"
 #include "src/trace_processor/importers/common/track_tracker.h"
 #include "src/trace_processor/importers/ftrace/ftrace_module.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
 #include "src/trace_processor/importers/proto/packet_sequence_state.h"
 #include "src/trace_processor/importers/proto/track_event_module.h"
 #include "src/trace_processor/storage/metadata.h"
diff --git a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
index 5b907a3..7ed4723 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
@@ -25,13 +25,13 @@
 #include "src/trace_processor/importers/common/clock_tracker.h"
 #include "src/trace_processor/importers/common/event_tracker.h"
 #include "src/trace_processor/importers/common/flow_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/importers/common/process_tracker.h"
 #include "src/trace_processor/importers/common/slice_tracker.h"
 #include "src/trace_processor/importers/common/track_tracker.h"
 #include "src/trace_processor/importers/ftrace/sched_event_tracker.h"
 #include "src/trace_processor/importers/proto/additional_modules.h"
 #include "src/trace_processor/importers/proto/default_modules.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
 #include "src/trace_processor/importers/proto/proto_trace_parser.h"
 #include "src/trace_processor/importers/proto/stack_profile_tracker.h"
 #include "src/trace_processor/sorter/trace_sorter.h"
@@ -140,9 +140,9 @@
                     int32_t next_prio));
 
   MOCK_METHOD3(PushCounter,
-               base::Optional<CounterId>(int64_t timestamp,
-                                         double value,
-                                         TrackId track_id));
+               std::optional<CounterId>(int64_t timestamp,
+                                        double value,
+                                        TrackId track_id));
 };
 
 class MockProcessTracker : public ProcessTracker {
@@ -152,7 +152,7 @@
 
   MOCK_METHOD4(SetProcessMetadata,
                UniquePid(uint32_t pid,
-                         base::Optional<uint32_t> ppid,
+                         std::optional<uint32_t> ppid,
                          base::StringView process_name,
                          base::StringView cmdline));
 
@@ -195,29 +195,29 @@
       : SliceTracker(context) {}
 
   MOCK_METHOD5(Begin,
-               base::Optional<SliceId>(int64_t timestamp,
-                                       TrackId track_id,
-                                       StringId cat,
-                                       StringId name,
-                                       SetArgsCallback args_callback));
+               std::optional<SliceId>(int64_t timestamp,
+                                      TrackId track_id,
+                                      StringId cat,
+                                      StringId name,
+                                      SetArgsCallback args_callback));
   MOCK_METHOD5(End,
-               base::Optional<SliceId>(int64_t timestamp,
-                                       TrackId track_id,
-                                       StringId cat,
-                                       StringId name,
-                                       SetArgsCallback args_callback));
+               std::optional<SliceId>(int64_t timestamp,
+                                      TrackId track_id,
+                                      StringId cat,
+                                      StringId name,
+                                      SetArgsCallback args_callback));
   MOCK_METHOD6(Scoped,
-               base::Optional<SliceId>(int64_t timestamp,
-                                       TrackId track_id,
-                                       StringId cat,
-                                       StringId name,
-                                       int64_t duration,
-                                       SetArgsCallback args_callback));
+               std::optional<SliceId>(int64_t timestamp,
+                                      TrackId track_id,
+                                      StringId cat,
+                                      StringId name,
+                                      int64_t duration,
+                                      SetArgsCallback args_callback));
   MOCK_METHOD4(StartSlice,
-               base::Optional<SliceId>(int64_t timestamp,
-                                       TrackId track_id,
-                                       SetArgsCallback args_callback,
-                                       std::function<SliceId()> inserter));
+               std::optional<SliceId>(int64_t timestamp,
+                                      TrackId track_id,
+                                      SetArgsCallback args_callback,
+                                      std::function<SliceId()> inserter));
 };
 
 class ProtoTraceParserTest : public ::testing::Test {
@@ -243,7 +243,7 @@
     slice_ = new NiceMock<MockSliceTracker>(&context_);
     context_.slice_tracker.reset(slice_);
     context_.slice_translation_table.reset(new SliceTranslationTable(storage_));
-    clock_ = new ClockTracker(context_.storage.get());
+    clock_ = new ClockTracker(&context_);
     context_.clock_tracker.reset(clock_);
     context_.flow_tracker.reset(new FlowTracker(&context_));
     context_.sorter.reset(new TraceSorter(&context_, CreateParser(),
diff --git a/src/trace_processor/importers/proto/proto_trace_reader.cc b/src/trace_processor/importers/proto/proto_trace_reader.cc
index cb0567b..f947c0f 100644
--- a/src/trace_processor/importers/proto/proto_trace_reader.cc
+++ b/src/trace_processor/importers/proto/proto_trace_reader.cc
@@ -16,11 +16,11 @@
 
 #include "src/trace_processor/importers/proto/proto_trace_reader.h"
 
+#include <optional>
 #include <string>
 
 #include "perfetto/base/build_config.h"
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/ext/base/utils.h"
 #include "perfetto/protozero/proto_decoder.h"
@@ -28,9 +28,9 @@
 #include "perfetto/trace_processor/status.h"
 #include "src/trace_processor/importers/common/clock_tracker.h"
 #include "src/trace_processor/importers/common/event_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/importers/common/track_tracker.h"
 #include "src/trace_processor/importers/ftrace/ftrace_module.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
 #include "src/trace_processor/importers/proto/packet_analyzer.h"
 #include "src/trace_processor/importers/proto/packet_sequence_state.h"
 #include "src/trace_processor/importers/proto/proto_incremental_state.h"
@@ -365,7 +365,7 @@
   uint32_t snapshot_id = context_->clock_tracker->AddSnapshot(clock_timestamps);
 
   // Add the all the clock snapshots to the clock snapshot table.
-  base::Optional<int64_t> trace_ts_for_check;
+  std::optional<int64_t> trace_ts_for_check;
   for (const auto& clock_timestamp : clock_timestamps) {
     // If the clock is incremental, we need to use 0 to map correctly to
     // |absolute_timestamp|.
@@ -398,8 +398,8 @@
   return util::OkStatus();
 }
 
-base::Optional<StringId> ProtoTraceReader::GetBuiltinClockNameOrNull(
-    uint64_t clock_id) {
+std::optional<StringId> ProtoTraceReader::GetBuiltinClockNameOrNull(
+    int64_t clock_id) {
   switch (clock_id) {
     case protos::pbzero::ClockSnapshot::Clock::REALTIME:
       return context_->storage->InternString("REALTIME");
@@ -414,7 +414,7 @@
     case protos::pbzero::ClockSnapshot::Clock::BOOTTIME:
       return context_->storage->InternString("BOOTTIME");
     default:
-      return base::nullopt;
+      return std::nullopt;
   }
 }
 
diff --git a/src/trace_processor/importers/proto/proto_trace_reader.h b/src/trace_processor/importers/proto/proto_trace_reader.h
index 471503a..1c554a6 100644
--- a/src/trace_processor/importers/proto/proto_trace_reader.h
+++ b/src/trace_processor/importers/proto/proto_trace_reader.h
@@ -75,7 +75,7 @@
                          TraceBlobView interned_data);
   void ParseTraceConfig(ConstBytes);
 
-  base::Optional<StringId> GetBuiltinClockNameOrNull(uint64_t clock_id);
+  std::optional<StringId> GetBuiltinClockNameOrNull(int64_t clock_id);
 
   PacketSequenceState* GetIncrementalStateForPacketSequence(
       uint32_t sequence_id) {
diff --git a/src/trace_processor/importers/proto/stack_profile_tracker.cc b/src/trace_processor/importers/proto/stack_profile_tracker.cc
index cfe90d2..fa1969b 100644
--- a/src/trace_processor/importers/proto/stack_profile_tracker.cc
+++ b/src/trace_processor/importers/proto/stack_profile_tracker.cc
@@ -46,7 +46,7 @@
   string_map_.emplace(id, str.ToStdString());
 }
 
-base::Optional<MappingId> SequenceStackProfileTracker::AddMapping(
+std::optional<MappingId> SequenceStackProfileTracker::AddMapping(
     SourceMappingId id,
     const SourceMapping& mapping,
     const InternLookup* intern_lookup) {
@@ -69,7 +69,7 @@
   if (!opt_build_id) {
     context_->storage->IncrementStats(stats::stackprofile_invalid_string_id);
     PERFETTO_DLOG("Invalid string.");
-    return base::nullopt;
+    return std::nullopt;
   }
   const StringId raw_build_id = opt_build_id.value();
   NullTermStringView raw_build_id_str =
@@ -101,7 +101,7 @@
 
   tables::StackProfileMappingTable* mappings =
       context_->storage->mutable_stack_profile_mapping_table();
-  base::Optional<MappingId> cur_id;
+  std::optional<MappingId> cur_id;
   auto it = mapping_idx_.find(row);
   if (it != mapping_idx_.end()) {
     cur_id = it->second;
@@ -136,16 +136,16 @@
   return cur_id;
 }
 
-base::Optional<FrameId> SequenceStackProfileTracker::AddFrame(
+std::optional<FrameId> SequenceStackProfileTracker::AddFrame(
     SourceFrameId id,
     const SourceFrame& frame,
     const InternLookup* intern_lookup) {
-  base::Optional<std::string> opt_name = FindOrInsertString(
+  std::optional<std::string> opt_name = FindOrInsertString(
       frame.name_id, intern_lookup, InternedStringType::kFunctionName);
   if (!opt_name) {
     context_->storage->IncrementStats(stats::stackprofile_invalid_string_id);
     PERFETTO_DLOG("Invalid string.");
-    return base::nullopt;
+    return std::nullopt;
   }
   const std::string& name = *opt_name;
   const StringId str_id =
@@ -154,7 +154,7 @@
   auto opt_mapping = FindOrInsertMapping(frame.mapping_id, intern_lookup);
   if (!opt_mapping) {
     context_->storage->IncrementStats(stats::stackprofile_invalid_mapping_id);
-    return base::nullopt;
+    return std::nullopt;
   }
   MappingId mapping_id = *opt_mapping;
   const auto& mappings = context_->storage->stack_profile_mapping_table();
@@ -167,7 +167,7 @@
 
   auto* frames = context_->storage->mutable_stack_profile_frame_table();
 
-  base::Optional<FrameId> cur_id;
+  std::optional<FrameId> cur_id;
   auto it = frame_idx_.find(row);
   if (it != frame_idx_.end()) {
     cur_id = it->second;
@@ -192,7 +192,7 @@
           mapping_id, static_cast<uint64_t>(row.rel_pc), *cur_id);
       if (base::Contains(name, '.')) {
         // Java frames always contain a '.'
-        base::Optional<std::string> package =
+        std::optional<std::string> package =
             PackageFromLocation(context_->storage.get(), mapping_name);
         if (package) {
           NameInPackage nip{str_id, context_->storage->InternString(
@@ -212,19 +212,19 @@
   return cur_id;
 }
 
-base::Optional<CallsiteId> SequenceStackProfileTracker::AddCallstack(
+std::optional<CallsiteId> SequenceStackProfileTracker::AddCallstack(
     SourceCallstackId id,
     const SourceCallstack& frame_ids,
     const InternLookup* intern_lookup) {
   if (frame_ids.empty())
-    return base::nullopt;
+    return std::nullopt;
 
-  base::Optional<CallsiteId> parent_id;
+  std::optional<CallsiteId> parent_id;
   for (uint32_t depth = 0; depth < frame_ids.size(); ++depth) {
     auto opt_frame_id = FindOrInsertFrame(frame_ids[depth], intern_lookup);
     if (!opt_frame_id) {
       context_->storage->IncrementStats(stats::stackprofile_invalid_frame_id);
-      return base::nullopt;
+      return std::nullopt;
     }
     FrameId frame_id = *opt_frame_id;
 
@@ -256,7 +256,7 @@
   return it->second;
 }
 
-base::Optional<StringId> SequenceStackProfileTracker::FindAndInternString(
+std::optional<StringId> SequenceStackProfileTracker::FindAndInternString(
     SourceStringId id,
     const InternLookup* intern_lookup,
     SequenceStackProfileTracker::InternedStringType type) {
@@ -270,7 +270,7 @@
   return context_->storage->InternString(base::StringView(*opt_str));
 }
 
-base::Optional<std::string> SequenceStackProfileTracker::FindOrInsertString(
+std::optional<std::string> SequenceStackProfileTracker::FindOrInsertString(
     SourceStringId id,
     const InternLookup* intern_lookup,
     SequenceStackProfileTracker::InternedStringType type) {
@@ -285,20 +285,20 @@
         context_->storage->IncrementStats(
             stats::stackprofile_invalid_string_id);
         PERFETTO_DLOG("Invalid string.");
-        return base::nullopt;
+        return std::nullopt;
       }
       return str->ToStdString();
     }
-    return base::nullopt;
+    return std::nullopt;
   }
 
   return it->second;
 }
 
-base::Optional<MappingId> SequenceStackProfileTracker::FindOrInsertMapping(
+std::optional<MappingId> SequenceStackProfileTracker::FindOrInsertMapping(
     SourceMappingId mapping_id,
     const InternLookup* intern_lookup) {
-  base::Optional<MappingId> res;
+  std::optional<MappingId> res;
   auto it = mapping_ids_.find(mapping_id);
   if (it == mapping_ids_.end()) {
     if (intern_lookup) {
@@ -315,10 +315,10 @@
   return res;
 }
 
-base::Optional<FrameId> SequenceStackProfileTracker::FindOrInsertFrame(
+std::optional<FrameId> SequenceStackProfileTracker::FindOrInsertFrame(
     SourceFrameId frame_id,
     const InternLookup* intern_lookup) {
-  base::Optional<FrameId> res;
+  std::optional<FrameId> res;
   auto it = frame_ids_.find(frame_id);
   if (it == frame_ids_.end()) {
     if (intern_lookup) {
@@ -337,10 +337,10 @@
   return res;
 }
 
-base::Optional<CallsiteId> SequenceStackProfileTracker::FindOrInsertCallstack(
+std::optional<CallsiteId> SequenceStackProfileTracker::FindOrInsertCallstack(
     SourceCallstackId callstack_id,
     const InternLookup* intern_lookup) {
-  base::Optional<CallsiteId> res;
+  std::optional<CallsiteId> res;
   auto it = callstack_ids_.find(callstack_id);
   if (it == callstack_ids_.end()) {
     auto interned_callstack = intern_lookup->GetCallstack(callstack_id);
diff --git a/src/trace_processor/importers/proto/stack_profile_tracker.h b/src/trace_processor/importers/proto/stack_profile_tracker.h
index fb5e728..a29d3c1 100644
--- a/src/trace_processor/importers/proto/stack_profile_tracker.h
+++ b/src/trace_processor/importers/proto/stack_profile_tracker.h
@@ -18,11 +18,11 @@
 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_STACK_PROFILE_TRACKER_H_
 
 #include <deque>
+#include <optional>
 #include <unordered_map>
 
-#include "perfetto/ext/base/optional.h"
 #include "src/trace_processor/storage/trace_storage.h"
-#include "src/trace_processor/tables/profiler_tables.h"
+#include "src/trace_processor/tables/profiler_tables_py.h"
 
 #include "protos/perfetto/trace/profiling/profile_common.pbzero.h"
 #include "protos/perfetto/trace/profiling/profile_packet.pbzero.h"
@@ -201,12 +201,12 @@
    public:
     virtual ~InternLookup();
 
-    virtual base::Optional<base::StringView> GetString(
+    virtual std::optional<base::StringView> GetString(
         SourceStringId,
         InternedStringType) const = 0;
-    virtual base::Optional<SourceMapping> GetMapping(SourceMappingId) const = 0;
-    virtual base::Optional<SourceFrame> GetFrame(SourceFrameId) const = 0;
-    virtual base::Optional<SourceCallstack> GetCallstack(
+    virtual std::optional<SourceMapping> GetMapping(SourceMappingId) const = 0;
+    virtual std::optional<SourceFrame> GetFrame(SourceFrameId) const = 0;
+    virtual std::optional<SourceCallstack> GetCallstack(
         SourceCallstackId) const = 0;
   };
 
@@ -214,14 +214,14 @@
   ~SequenceStackProfileTracker();
 
   void AddString(SourceStringId, base::StringView);
-  base::Optional<MappingId> AddMapping(
+  std::optional<MappingId> AddMapping(
       SourceMappingId,
       const SourceMapping&,
       const InternLookup* intern_lookup = nullptr);
-  base::Optional<FrameId> AddFrame(SourceFrameId,
-                                   const SourceFrame&,
-                                   const InternLookup* intern_lookup = nullptr);
-  base::Optional<CallsiteId> AddCallstack(
+  std::optional<FrameId> AddFrame(SourceFrameId,
+                                  const SourceFrame&,
+                                  const InternLookup* intern_lookup = nullptr);
+  std::optional<CallsiteId> AddCallstack(
       SourceCallstackId,
       const SourceCallstack&,
       const InternLookup* intern_lookup = nullptr);
@@ -238,21 +238,20 @@
   // This is to support both ProfilePackets that contain the interned data
   // (for Android Q) and where the interned data is kept globally in
   // InternedData (for versions newer than Q).
-  base::Optional<StringId> FindAndInternString(
+  std::optional<StringId> FindAndInternString(SourceStringId,
+                                              const InternLookup* intern_lookup,
+                                              InternedStringType type);
+  std::optional<std::string> FindOrInsertString(
       SourceStringId,
       const InternLookup* intern_lookup,
       InternedStringType type);
-  base::Optional<std::string> FindOrInsertString(
-      SourceStringId,
-      const InternLookup* intern_lookup,
-      InternedStringType type);
-  base::Optional<MappingId> FindOrInsertMapping(
+  std::optional<MappingId> FindOrInsertMapping(
       SourceMappingId,
       const InternLookup* intern_lookup);
-  base::Optional<FrameId> FindOrInsertFrame(SourceFrameId,
-                                            const InternLookup* intern_lookup);
+  std::optional<FrameId> FindOrInsertFrame(SourceFrameId,
+                                           const InternLookup* intern_lookup);
 
-  base::Optional<CallsiteId> FindOrInsertCallstack(
+  std::optional<CallsiteId> FindOrInsertCallstack(
       SourceCallstackId,
       const InternLookup* intern_lookup);
 
diff --git a/src/trace_processor/importers/proto/statsd_module.cc b/src/trace_processor/importers/proto/statsd_module.cc
index 555ccaa..472506c 100644
--- a/src/trace_processor/importers/proto/statsd_module.cc
+++ b/src/trace_processor/importers/proto/statsd_module.cc
@@ -146,7 +146,7 @@
                                      size_t size,
                                      const char* name) {
   pool_.AddFromFileDescriptorSet(data, size);
-  base::Optional<uint32_t> opt_idx = pool_.FindDescriptorIdx(name);
+  std::optional<uint32_t> opt_idx = pool_.FindDescriptorIdx(name);
   if (opt_idx.has_value()) {
     descriptor_ = &pool_.descriptors()[opt_idx.value()];
   }
@@ -195,7 +195,7 @@
 
   AsyncTrackSetTracker::TrackSetId track_set = InternAsyncTrackSetId();
   TrackId track = context_->async_track_set_tracker->Scoped(track_set, ts, 0);
-  base::Optional<SliceId> opt_slice =
+  std::optional<SliceId> opt_slice =
       context_->slice_tracker->Scoped(ts, track, kNullStringId, atom_name, 0);
   if (!opt_slice) {
     return;
diff --git a/src/trace_processor/importers/proto/statsd_module.h b/src/trace_processor/importers/proto/statsd_module.h
index e5157d2..999a339 100644
--- a/src/trace_processor/importers/proto/statsd_module.h
+++ b/src/trace_processor/importers/proto/statsd_module.h
@@ -18,9 +18,9 @@
 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_STATSD_MODULE_H_
 
 #include <cstdint>
+#include <optional>
 
 #include "perfetto/ext/base/flat_hash_map.h"
-#include "perfetto/ext/base/optional.h"
 #include "protos/perfetto/trace/trace_packet.pbzero.h"
 #include "src/trace_processor/importers/common/async_track_set_tracker.h"
 #include "src/trace_processor/importers/common/trace_parser.h"
@@ -76,7 +76,7 @@
   base::FlatHashMap<uint32_t, StringId> atom_names_;
   PoolAndDescriptor pool_;
   util::ProtoToArgsParser args_parser_;
-  base::Optional<AsyncTrackSetTracker::TrackSetId> track_set_id_;
+  std::optional<AsyncTrackSetTracker::TrackSetId> track_set_id_;
 };
 
 }  // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/system_probes_parser.cc b/src/trace_processor/importers/proto/system_probes_parser.cc
index a16ca4a..da175fa 100644
--- a/src/trace_processor/importers/proto/system_probes_parser.cc
+++ b/src/trace_processor/importers/proto/system_probes_parser.cc
@@ -23,9 +23,9 @@
 #include "perfetto/ext/traced/sys_stats_counters.h"
 #include "perfetto/protozero/proto_decoder.h"
 #include "src/trace_processor/importers/common/event_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/importers/common/process_tracker.h"
 #include "src/trace_processor/importers/common/system_info_tracker.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
 #include "src/trace_processor/importers/syscalls/syscall_tracker.h"
 #include "src/trace_processor/storage/metadata.h"
 #include "src/trace_processor/types/trace_processor_context.h"
@@ -48,7 +48,7 @@
 
 namespace {
 
-base::Optional<int> VersionStringToSdkVersion(const std::string& version) {
+std::optional<int> VersionStringToSdkVersion(const std::string& version) {
   // TODO(lalitm): remove this when the SDK version polling saturates
   // S/T traces in practice.
   if (base::StartsWith(version, "T") || base::StartsWith(version, "S")) {
@@ -82,21 +82,21 @@
   }
   // If we reached this point, we don't know how to parse this version
   // so just return null.
-  return base::nullopt;
+  return std::nullopt;
 }
 
-base::Optional<int> FingerprintToSdkVersion(const std::string& fingerprint) {
+std::optional<int> FingerprintToSdkVersion(const std::string& fingerprint) {
   // Try to parse the SDK version from the fingerprint.
   // Examples of fingerprints:
   // google/shamu/shamu:7.0/NBD92F/3753956:userdebug/dev-keys
   // google/coral/coral:12/SP1A.210812.015/7679548:userdebug/dev-keys
   size_t colon = fingerprint.find(':');
   if (colon == std::string::npos)
-    return base::nullopt;
+    return std::nullopt;
 
   size_t slash = fingerprint.find('/', colon);
   if (slash == std::string::npos)
-    return base::nullopt;
+    return std::nullopt;
 
   std::string version = fingerprint.substr(colon + 1, slash - (colon + 1));
   return VersionStringToSdkVersion(version);
@@ -600,7 +600,7 @@
 
   // If we have the SDK version in the trace directly just use that.
   // Otherwise, try and parse it from the fingerprint.
-  base::Optional<int64_t> opt_sdk_version;
+  std::optional<int64_t> opt_sdk_version;
   if (packet.has_android_sdk_version()) {
     opt_sdk_version = static_cast<int64_t>(packet.android_sdk_version());
   } else if (packet.has_android_build_fingerprint()) {
diff --git a/src/trace_processor/importers/proto/track_event_parser.cc b/src/trace_processor/importers/proto/track_event_parser.cc
index ab74bb1..2373f70 100644
--- a/src/trace_processor/importers/proto/track_event_parser.cc
+++ b/src/trace_processor/importers/proto/track_event_parser.cc
@@ -17,10 +17,10 @@
 #include "src/trace_processor/importers/proto/track_event_parser.h"
 
 #include <iostream>
+#include <optional>
 #include <string>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_writer.h"
 #include "perfetto/trace_processor/status.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
@@ -175,7 +175,7 @@
   return result;
 }
 
-base::Optional<base::Status> MaybeParseUnsymbolizedSourceLocation(
+std::optional<base::Status> MaybeParseUnsymbolizedSourceLocation(
     std::string prefix,
     const protozero::Field& field,
     util::ProtoToArgsParser::Delegate& delegate) {
@@ -185,7 +185,7 @@
   if (!decoder) {
     // Lookup failed fall back on default behaviour which will just put
     // the iid into the args table.
-    return base::nullopt;
+    return std::nullopt;
   }
   // Interned mapping_id loses it's meaning when the sequence ends. So we need
   // to get an id from stack_profile_mapping table.
@@ -196,7 +196,7 @@
           ->sequence_stack_profile_tracker()
           .FindOrInsertMapping(decoder->mapping_id(), &intern_lookup);
   if (!mapping_id) {
-    return base::nullopt;
+    return std::nullopt;
   }
   delegate.AddUnsignedInteger(
       util::ProtoToArgsParser::Key(prefix + ".mapping_id"), mapping_id->value);
@@ -205,7 +205,7 @@
   return base::OkStatus();
 }
 
-base::Optional<base::Status> MaybeParseSourceLocation(
+std::optional<base::Status> MaybeParseSourceLocation(
     std::string prefix,
     const protozero::Field& field,
     util::ProtoToArgsParser::Delegate& delegate) {
@@ -214,7 +214,7 @@
   if (!decoder) {
     // Lookup failed fall back on default behaviour which will just put
     // the source_location_iid into the args table.
-    return base::nullopt;
+    return std::nullopt;
   }
 
   delegate.AddString(util::ProtoToArgsParser::Key(prefix + ".file_name"),
@@ -426,7 +426,7 @@
     //      TrackEvent types), or
     //   b) a default track.
     if (track_uuid_) {
-      base::Optional<TrackId> opt_track_id =
+      std::optional<TrackId> opt_track_id =
           track_event_tracker_->GetDescriptorTrack(track_uuid_, name_id_,
                                                    packet_sequence_id_);
       if (!opt_track_id) {
@@ -581,7 +581,7 @@
             track_id_ = context_->track_tracker
                             ->GetOrCreateLegacyChromeGlobalInstantTrack();
             legacy_passthrough_utid_ = utid_;
-            utid_ = base::nullopt;
+            utid_ = std::nullopt;
             break;
           case LegacyEvent::SCOPE_PROCESS:
             if (!upid_) {
@@ -593,7 +593,7 @@
                 context_->track_tracker->InternLegacyChromeProcessInstantTrack(
                     *upid_);
             legacy_passthrough_utid_ = utid_;
-            utid_ = base::nullopt;
+            utid_ = std::nullopt;
             break;
         }
         break;
@@ -697,9 +697,9 @@
     PERFETTO_DCHECK(track_uuid_it);
     PERFETTO_DCHECK(index < TrackEventData::kMaxNumExtraCounters);
 
-    base::Optional<TrackId> track_id = track_event_tracker_->GetDescriptorTrack(
+    std::optional<TrackId> track_id = track_event_tracker_->GetDescriptorTrack(
         *track_uuid_it, kNullStringId, packet_sequence_id_);
-    base::Optional<uint32_t> counter_row =
+    std::optional<uint32_t> counter_row =
         storage_->counter_track_table().id().IndexOf(*track_id);
 
     double value = event_data_->extra_counter_values[index];
@@ -757,12 +757,12 @@
     }
 
     tables::SliceTable::RowReference slice_ref = *opt_thread_slice_ref;
-    base::Optional<int64_t> tts = slice_ref.thread_ts();
+    std::optional<int64_t> tts = slice_ref.thread_ts();
     if (tts) {
       PERFETTO_DCHECK(thread_timestamp_);
       slice_ref.set_thread_dur(*thread_timestamp_ - *tts);
     }
-    base::Optional<int64_t> tic = slice_ref.thread_instruction_count();
+    std::optional<int64_t> tic = slice_ref.thread_instruction_count();
     if (tic) {
       PERFETTO_DCHECK(event_data_->thread_instruction_count);
       slice_ref.set_thread_instruction_delta(
@@ -800,7 +800,7 @@
     return util::OkStatus();
   }
 
-  base::Optional<uint64_t> GetLegacyEventId() {
+  std::optional<uint64_t> GetLegacyEventId() {
     if (legacy_event_.has_unscoped_id())
       return legacy_event_.unscoped_id();
     // TODO(andrewbb): Catapult doesn't support global_id and local_id on flow
@@ -808,7 +808,7 @@
     // to be some callsites supplying local_id in chromium), but we would have
     // to consider the process ID for local IDs and use a separate ID scope for
     // global_id and unscoped_id.
-    return base::nullopt;
+    return std::nullopt;
   }
 
   util::Status ParseFlowEventV1(char phase) {
@@ -902,7 +902,7 @@
     // up nested underneath their parent slices.
     int64_t duration_ns = 0;
     int64_t tidelta = 0;
-    base::Optional<tables::SliceTable::Id> opt_slice_id;
+    std::optional<tables::SliceTable::Id> opt_slice_id;
     auto args_inserter = [this, phase](BoundInserter* inserter) {
       ParseTrackEventArgs(inserter);
       // For legacy MARK event, add phase for JSON exporter.
@@ -1364,9 +1364,9 @@
     row.category = category_id_;
     row.name = name_id_;
     row.thread_ts = thread_timestamp_;
-    row.thread_dur = base::nullopt;
+    row.thread_dur = std::nullopt;
     row.thread_instruction_count = thread_instruction_count_;
-    row.thread_instruction_delta = base::nullopt;
+    row.thread_instruction_delta = std::nullopt;
     return row;
   }
 
@@ -1388,15 +1388,15 @@
   StringId name_id_;
   uint64_t track_uuid_;
   TrackId track_id_;
-  base::Optional<UniqueTid> utid_;
-  base::Optional<UniqueTid> upid_;
-  base::Optional<int64_t> thread_timestamp_;
-  base::Optional<int64_t> thread_instruction_count_;
+  std::optional<UniqueTid> utid_;
+  std::optional<UniqueTid> upid_;
+  std::optional<int64_t> thread_timestamp_;
+  std::optional<int64_t> thread_instruction_count_;
   // All events in legacy JSON require a thread ID, but for some types of
   // events (e.g. async events or process/global-scoped instants), we don't
   // store it in the slice/track model. To pass the utid through to the json
   // export, we store it in an arg.
-  base::Optional<UniqueTid> legacy_passthrough_utid_;
+  std::optional<UniqueTid> legacy_passthrough_utid_;
 
   uint32_t packet_sequence_id_;
 };
@@ -1550,7 +1550,7 @@
                                   util::ProtoToArgsParser::Delegate& delegate) {
         AddActiveProcess(delegate.packet_timestamp(), field.as_int32());
         // Fallthrough so that the parser adds pid as a regular arg.
-        return base::nullopt;
+        return std::nullopt;
       });
 
   for (uint16_t index : kReflectFields) {
diff --git a/src/trace_processor/importers/proto/track_event_tokenizer.cc b/src/trace_processor/importers/proto/track_event_tokenizer.cc
index 314d205..6b655f4 100644
--- a/src/trace_processor/importers/proto/track_event_tokenizer.cc
+++ b/src/trace_processor/importers/proto/track_event_tokenizer.cc
@@ -19,9 +19,9 @@
 #include "perfetto/base/logging.h"
 #include "perfetto/trace_processor/trace_blob_view.h"
 #include "src/trace_processor/importers/common/clock_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/importers/common/process_tracker.h"
 #include "src/trace_processor/importers/common/track_tracker.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
 #include "src/trace_processor/importers/proto/packet_sequence_state.h"
 #include "src/trace_processor/importers/proto/proto_trace_reader.h"
 #include "src/trace_processor/importers/proto/track_event_tracker.h"
@@ -327,7 +327,7 @@
       return;
     }
 
-    base::Optional<double> value;
+    std::optional<double> value;
     if (event.has_counter_value()) {
       value = track_event_tracker_->ConvertToAbsoluteCounterValue(
           track_uuid, packet.trusted_packet_sequence_id(),
@@ -408,7 +408,7 @@
           "Ignoring TrackEvent with more extra_{double_,}counter_values than "
           "TrackEventData::kMaxNumExtraCounters");
     }
-    base::Optional<double> abs_value =
+    std::optional<double> abs_value =
         track_event_tracker_->ConvertToAbsoluteCounterValue(
             *track_uuid_it, trusted_packet_sequence_id,
             static_cast<double>(*value_it));
diff --git a/src/trace_processor/importers/proto/track_event_tracker.cc b/src/trace_processor/importers/proto/track_event_tracker.cc
index f460614..7591028 100644
--- a/src/trace_processor/importers/proto/track_event_tracker.cc
+++ b/src/trace_processor/importers/proto/track_event_tracker.cc
@@ -180,11 +180,11 @@
   return thread_tracks_[utid] = InsertThreadTrack(utid);
 }
 
-base::Optional<TrackId> TrackEventTracker::GetDescriptorTrack(
+std::optional<TrackId> TrackEventTracker::GetDescriptorTrack(
     uint64_t uuid,
     StringId event_name,
-    base::Optional<uint32_t> packet_sequence_id) {
-  base::Optional<TrackId> track_id =
+    std::optional<uint32_t> packet_sequence_id) {
+  std::optional<TrackId> track_id =
       GetDescriptorTrackImpl(uuid, packet_sequence_id);
   if (!track_id || event_name.is_null())
     return track_id;
@@ -208,19 +208,19 @@
   return track_id;
 }
 
-base::Optional<TrackId> TrackEventTracker::GetDescriptorTrackImpl(
+std::optional<TrackId> TrackEventTracker::GetDescriptorTrackImpl(
     uint64_t uuid,
-    base::Optional<uint32_t> packet_sequence_id) {
+    std::optional<uint32_t> packet_sequence_id) {
   auto it = descriptor_tracks_.find(uuid);
   if (it != descriptor_tracks_.end())
     return it->second;
 
-  base::Optional<ResolvedDescriptorTrack> resolved_track =
+  std::optional<ResolvedDescriptorTrack> resolved_track =
       ResolveDescriptorTrack(uuid, nullptr);
   if (!resolved_track)
-    return base::nullopt;
+    return std::nullopt;
 
-  // The reservation must exist as |resolved_track| would have been nullopt
+  // The reservation must exist as |resolved_track| would have been std::nullopt
   // otherwise.
   auto reserved_it = reserved_descriptor_tracks_.find(uuid);
   PERFETTO_CHECK(reserved_it != reserved_descriptor_tracks_.end());
@@ -229,7 +229,7 @@
 
   // We resolve parent_id here to ensure that it's going to be smaller
   // than the id of the child.
-  base::Optional<TrackId> parent_id;
+  std::optional<TrackId> parent_id;
   if (reservation.parent_uuid != 0) {
     parent_id = GetDescriptorTrackImpl(reservation.parent_uuid);
   }
@@ -321,7 +321,7 @@
   PERFETTO_FATAL("For GCC");
 }
 
-base::Optional<TrackEventTracker::ResolvedDescriptorTrack>
+std::optional<TrackEventTracker::ResolvedDescriptorTrack>
 TrackEventTracker::ResolveDescriptorTrack(
     uint64_t uuid,
     std::vector<uint64_t>* descendent_uuids) {
@@ -331,7 +331,7 @@
 
   auto reservation_it = reserved_descriptor_tracks_.find(uuid);
   if (reservation_it == reserved_descriptor_tracks_.end())
-    return base::nullopt;
+    return std::nullopt;
 
   // Resolve process and thread id for tracks produced from within a pid
   // namespace.
@@ -353,16 +353,16 @@
       reservation.pid = *opt_resolved_pid;
   }
 
-  base::Optional<ResolvedDescriptorTrack> resolved_track =
+  std::optional<ResolvedDescriptorTrack> resolved_track =
       ResolveDescriptorTrackImpl(uuid, reservation, descendent_uuids);
   if (!resolved_track) {
-    return base::nullopt;
+    return std::nullopt;
   }
   resolved_descriptor_tracks_[uuid] = *resolved_track;
   return resolved_track;
 }
 
-base::Optional<TrackEventTracker::ResolvedDescriptorTrack>
+std::optional<TrackEventTracker::ResolvedDescriptorTrack>
 TrackEventTracker::ResolveDescriptorTrackImpl(
     uint64_t uuid,
     const DescriptorTrackReservation& reservation,
@@ -370,7 +370,7 @@
   static constexpr size_t kMaxAncestors = 10;
 
   // Try to resolve any parent tracks recursively, too.
-  base::Optional<ResolvedDescriptorTrack> parent_resolved_track;
+  std::optional<ResolvedDescriptorTrack> parent_resolved_track;
   if (reservation.parent_uuid) {
     // Input data may contain loops or extremely long ancestor track chains. To
     // avoid stack overflow in these situations, we keep track of the ancestors
@@ -387,7 +387,7 @@
           "Too many ancestors in parent_track_uuid hierarchy at track %" PRIu64
           " with parent %" PRIu64,
           uuid, reservation.parent_uuid);
-      return base::nullopt;
+      return std::nullopt;
     }
 
     if (std::find(descendent_uuids->begin(), descendent_uuids->end(),
@@ -396,7 +396,7 @@
           "Loop detected in parent_track_uuid hierarchy at track %" PRIu64
           " with parent %" PRIu64,
           uuid, reservation.parent_uuid);
-      return base::nullopt;
+      return std::nullopt;
     }
 
     parent_resolved_track =
@@ -429,7 +429,7 @@
                     *reservation.pid, *reservation.tid, old_uuid, uuid,
                     reservation.min_timestamp);
 
-      utid = context_->process_tracker->StartNewThread(base::nullopt,
+      utid = context_->process_tracker->StartNewThread(std::nullopt,
                                                        *reservation.tid);
 
       // Associate the new thread with its process.
@@ -462,7 +462,7 @@
                     reservation.min_timestamp);
 
       upid = context_->process_tracker->StartNewProcess(
-          base::nullopt, base::nullopt, *reservation.pid, kNullStringId,
+          std::nullopt, std::nullopt, *reservation.pid, kNullStringId,
           ThreadNamePriority::kTrackDescriptor);
 
       descriptor_uuids_by_upid_[upid] = uuid;
@@ -505,7 +505,7 @@
           "Loop detected in parent_track_uuid hierarchy at track %" PRIu64
           " with parent %" PRIu64,
           uuid, kDefaultDescriptorTrackUuid);
-      return base::nullopt;
+      return std::nullopt;
     }
 
     // This track will be implicitly a child of the default global track.
@@ -518,7 +518,7 @@
 TrackId TrackEventTracker::GetOrCreateDefaultDescriptorTrack() {
   // If the default track was already reserved (e.g. because a producer emitted
   // a descriptor for it) or created, resolve and return it.
-  base::Optional<TrackId> track_id =
+  std::optional<TrackId> track_id =
       GetDescriptorTrack(kDefaultDescriptorTrackUuid);
   if (track_id)
     return *track_id;
@@ -529,7 +529,7 @@
   return *GetDescriptorTrack(kDefaultDescriptorTrackUuid);
 }
 
-base::Optional<double> TrackEventTracker::ConvertToAbsoluteCounterValue(
+std::optional<double> TrackEventTracker::ConvertToAbsoluteCounterValue(
     uint64_t counter_track_uuid,
     uint32_t packet_sequence_id,
     double value) {
@@ -537,14 +537,14 @@
   if (reservation_it == reserved_descriptor_tracks_.end()) {
     PERFETTO_DLOG("Unknown counter track with uuid %" PRIu64,
                   counter_track_uuid);
-    return base::nullopt;
+    return std::nullopt;
   }
 
   DescriptorTrackReservation& reservation = reservation_it->second;
   if (!reservation.is_counter) {
     PERFETTO_DLOG("Track with uuid %" PRIu64 " is not a counter track",
                   counter_track_uuid);
-    return base::nullopt;
+    return std::nullopt;
   }
 
   if (reservation.unit_multiplier > 0)
@@ -558,7 +558,7 @@
           " got:%" PRIu32 ")",
           counter_track_uuid, reservation.packet_sequence_id,
           packet_sequence_id);
-      return base::nullopt;
+      return std::nullopt;
     }
 
     reservation.latest_value += value;
diff --git a/src/trace_processor/importers/proto/track_event_tracker.h b/src/trace_processor/importers/proto/track_event_tracker.h
index 58db962..2eb7092 100644
--- a/src/trace_processor/importers/proto/track_event_tracker.h
+++ b/src/trace_processor/importers/proto/track_event_tracker.h
@@ -102,21 +102,21 @@
   // each |uuid| resolves and inserts the track (and its parent tracks,
   // following the parent_uuid chain recursively) based on reservations made for
   // the |uuid|. If the track is a child track and doesn't have a name yet,
-  // updates the track's name to event_name. Returns nullopt if no track for a
-  // descriptor with this |uuid| has been reserved.
+  // updates the track's name to event_name. Returns std::nullopt if no track
+  // for a descriptor with this |uuid| has been reserved.
   // TODO(lalitm): this method needs to be split up and moved back to
   // TrackTracker.
-  base::Optional<TrackId> GetDescriptorTrack(
+  std::optional<TrackId> GetDescriptorTrack(
       uint64_t uuid,
       StringId event_name = kNullStringId,
-      base::Optional<uint32_t> packet_sequence_id = base::nullopt);
+      std::optional<uint32_t> packet_sequence_id = std::nullopt);
 
   // Converts the given counter value to an absolute value in the unit of the
   // counter, applying incremental delta encoding or unit multipliers as
   // necessary. If the counter uses incremental encoding, |packet_sequence_id|
-  // must match the one in its track reservation. Returns base::nullopt if the
+  // must match the one in its track reservation. Returns std::nullopt if the
   // counter track is unknown or an invalid |packet_sequence_id| was passed.
-  base::Optional<double> ConvertToAbsoluteCounterValue(
+  std::optional<double> ConvertToAbsoluteCounterValue(
       uint64_t counter_track_uuid,
       uint32_t packet_sequence_id,
       double value);
@@ -144,15 +144,15 @@
     range_of_interest_start_us_ = range_of_interest_start_us;
   }
 
-  base::Optional<int64_t> range_of_interest_start_us() const {
+  std::optional<int64_t> range_of_interest_start_us() const {
     return range_of_interest_start_us_;
   }
 
  private:
   struct DescriptorTrackReservation {
     uint64_t parent_uuid = 0;
-    base::Optional<uint32_t> pid;
-    base::Optional<uint32_t> tid;
+    std::optional<uint32_t> pid;
+    std::optional<uint32_t> tid;
     int64_t min_timestamp = 0;  // only set if |pid| and/or |tid| is set.
     StringId name = kNullStringId;
     bool use_separate_track = false;
@@ -220,14 +220,14 @@
     UniquePid upid_;
   };
 
-  base::Optional<TrackId> GetDescriptorTrackImpl(
+  std::optional<TrackId> GetDescriptorTrackImpl(
       uint64_t uuid,
-      base::Optional<uint32_t> packet_sequence_id = base::nullopt);
+      std::optional<uint32_t> packet_sequence_id = std::nullopt);
   TrackId CreateTrackFromResolved(const ResolvedDescriptorTrack&);
-  base::Optional<ResolvedDescriptorTrack> ResolveDescriptorTrack(
+  std::optional<ResolvedDescriptorTrack> ResolveDescriptorTrack(
       uint64_t uuid,
       std::vector<uint64_t>* descendent_uuids);
-  base::Optional<ResolvedDescriptorTrack> ResolveDescriptorTrackImpl(
+  std::optional<ResolvedDescriptorTrack> ResolveDescriptorTrackImpl(
       uint64_t uuid,
       const DescriptorTrackReservation&,
       std::vector<uint64_t>* descendent_uuids);
@@ -261,7 +261,7 @@
 
   const StringId default_descriptor_track_name_ = kNullStringId;
 
-  base::Optional<int64_t> range_of_interest_start_us_;
+  std::optional<int64_t> range_of_interest_start_us_;
 
   TraceProcessorContext* const context_;
 };
diff --git a/src/trace_processor/importers/proto/translation_table_module.h b/src/trace_processor/importers/proto/translation_table_module.h
index a180335..a318e60 100644
--- a/src/trace_processor/importers/proto/translation_table_module.h
+++ b/src/trace_processor/importers/proto/translation_table_module.h
@@ -18,8 +18,8 @@
 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_TRANSLATION_TABLE_MODULE_H_
 
 #include <cstdint>
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
 #include "protos/perfetto/trace/trace_packet.pbzero.h"
 #include "src/trace_processor/importers/proto/proto_importer_module.h"
 #include "src/trace_processor/types/trace_processor_context.h"
diff --git a/src/trace_processor/importers/syscalls/syscall_tracker_unittest.cc b/src/trace_processor/importers/syscalls/syscall_tracker_unittest.cc
index 67ef441..cc0117d 100644
--- a/src/trace_processor/importers/syscalls/syscall_tracker_unittest.cc
+++ b/src/trace_processor/importers/syscalls/syscall_tracker_unittest.cc
@@ -34,17 +34,17 @@
   virtual ~MockSliceTracker() = default;
 
   MOCK_METHOD5(Begin,
-               base::Optional<SliceId>(int64_t timestamp,
-                                       TrackId track_id,
-                                       StringId cat,
-                                       StringId name,
-                                       SetArgsCallback args_callback));
+               std::optional<SliceId>(int64_t timestamp,
+                                      TrackId track_id,
+                                      StringId cat,
+                                      StringId name,
+                                      SetArgsCallback args_callback));
   MOCK_METHOD5(End,
-               base::Optional<SliceId>(int64_t timestamp,
-                                       TrackId track_id,
-                                       StringId cat,
-                                       StringId name,
-                                       SetArgsCallback args_callback));
+               std::optional<SliceId>(int64_t timestamp,
+                                      TrackId track_id,
+                                      StringId cat,
+                                      StringId name,
+                                      SetArgsCallback args_callback));
 };
 
 class SyscallTrackerTest : public ::testing::Test {
@@ -68,9 +68,9 @@
   StringId begin_name = kNullStringId;
   StringId end_name = kNullStringId;
   EXPECT_CALL(*slice_tracker, Begin(100, track, kNullStringId, _, _))
-      .WillOnce(DoAll(SaveArg<3>(&begin_name), Return(base::nullopt)));
+      .WillOnce(DoAll(SaveArg<3>(&begin_name), Return(std::nullopt)));
   EXPECT_CALL(*slice_tracker, End(110, track, kNullStringId, _, _))
-      .WillOnce(DoAll(SaveArg<3>(&end_name), Return(base::nullopt)));
+      .WillOnce(DoAll(SaveArg<3>(&end_name), Return(std::nullopt)));
 
   SyscallTracker* syscall_tracker = SyscallTracker::GetOrCreate(&context);
   syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 57 /*sys_read*/);
@@ -84,9 +84,9 @@
   StringId begin_name = kNullStringId;
   StringId end_name = kNullStringId;
   EXPECT_CALL(*slice_tracker, Begin(100, track, kNullStringId, _, _))
-      .WillOnce(DoAll(SaveArg<3>(&begin_name), Return(base::nullopt)));
+      .WillOnce(DoAll(SaveArg<3>(&begin_name), Return(std::nullopt)));
   EXPECT_CALL(*slice_tracker, End(110, track, kNullStringId, _, _))
-      .WillOnce(DoAll(SaveArg<3>(&end_name), Return(base::nullopt)));
+      .WillOnce(DoAll(SaveArg<3>(&end_name), Return(std::nullopt)));
 
   SyscallTracker* syscall_tracker = SyscallTracker::GetOrCreate(&context);
   syscall_tracker->SetArchitecture(kAarch64);
@@ -101,9 +101,9 @@
   StringId begin_name = kNullStringId;
   StringId end_name = kNullStringId;
   EXPECT_CALL(*slice_tracker, Begin(100, track, kNullStringId, _, _))
-      .WillOnce(DoAll(SaveArg<3>(&begin_name), Return(base::nullopt)));
+      .WillOnce(DoAll(SaveArg<3>(&begin_name), Return(std::nullopt)));
   EXPECT_CALL(*slice_tracker, End(110, track, kNullStringId, _, _))
-      .WillOnce(DoAll(SaveArg<3>(&end_name), Return(base::nullopt)));
+      .WillOnce(DoAll(SaveArg<3>(&end_name), Return(std::nullopt)));
 
   SyscallTracker* syscall_tracker = SyscallTracker::GetOrCreate(&context);
   syscall_tracker->SetArchitecture(kX86_64);
diff --git a/src/trace_processor/importers/systrace/systrace_line_parser.cc b/src/trace_processor/importers/systrace/systrace_line_parser.cc
index 150124c..958cb7e 100644
--- a/src/trace_processor/importers/systrace/systrace_line_parser.cc
+++ b/src/trace_processor/importers/systrace/systrace_line_parser.cc
@@ -64,7 +64,7 @@
       ThreadNamePriority::kFtrace);
 
   if (!line.tgid_str.empty() && line.tgid_str != "-----") {
-    base::Optional<uint32_t> tgid = base::StringToUInt32(line.tgid_str);
+    std::optional<uint32_t> tgid = base::StringToUInt32(line.tgid_str);
     if (tgid) {
       context_->process_tracker->UpdateThread(line.pid, tgid.value());
     }
@@ -116,7 +116,7 @@
         line.ts, line.pid, line.args_str.c_str());
   } else if (line.event_name == "sched_waking") {
     auto comm = args["comm"];
-    base::Optional<uint32_t> wakee_pid = base::StringToUInt32(args["pid"]);
+    std::optional<uint32_t> wakee_pid = base::StringToUInt32(args["pid"]);
     if (!wakee_pid.has_value()) {
       return util::Status("Could not convert wakee_pid");
     }
@@ -129,8 +129,8 @@
         line.ts, wakee_utid, utid);
 
   } else if (line.event_name == "cpu_frequency") {
-    base::Optional<uint32_t> event_cpu = base::StringToUInt32(args["cpu_id"]);
-    base::Optional<double> new_state = base::StringToDouble(args["state"]);
+    std::optional<uint32_t> event_cpu = base::StringToUInt32(args["cpu_id"]);
+    std::optional<double> new_state = base::StringToDouble(args["state"]);
     if (!event_cpu.has_value()) {
       return util::Status("Could not convert event cpu");
     }
@@ -142,8 +142,8 @@
         cpufreq_name_id_, event_cpu.value());
     context_->event_tracker->PushCounter(line.ts, new_state.value(), track);
   } else if (line.event_name == "cpu_idle") {
-    base::Optional<uint32_t> event_cpu = base::StringToUInt32(args["cpu_id"]);
-    base::Optional<double> new_state = base::StringToDouble(args["state"]);
+    std::optional<uint32_t> event_cpu = base::StringToUInt32(args["cpu_id"]);
+    std::optional<double> new_state = base::StringToDouble(args["state"]);
     if (!event_cpu.has_value()) {
       return util::Status("Could not convert event cpu");
     }
@@ -261,7 +261,7 @@
       return util::Status("sched_blocked_reason: could not parse io_wait");
     }
     ThreadStateTracker::GetOrCreate(context_)->PushBlockedReason(
-        wakee_utid, static_cast<bool>(*io_wait), base::nullopt);
+        wakee_utid, static_cast<bool>(*io_wait), std::nullopt);
   } else if (line.event_name == "rss_stat") {
     // Format: rss_stat: size=8437760 member=1 curr=1 mm_id=2824390453
     auto size = base::StringToInt64(args["size"]);
@@ -274,9 +274,9 @@
     if (!member.has_value()) {
       return util::Status("rss_stat: could not parse member");
     }
-    base::Optional<bool> curr;
+    std::optional<bool> curr;
     if (!opt_curr.has_value()) {
-      curr = base::make_optional(static_cast<bool>(*opt_curr));
+      curr = std::make_optional(static_cast<bool>(*opt_curr));
     }
     rss_stat_tracker_.ParseRssStat(line.ts, line.pid, *size, *member, curr,
                                    mm_id);
diff --git a/src/trace_processor/importers/systrace/systrace_line_tokenizer.cc b/src/trace_processor/importers/systrace/systrace_line_tokenizer.cc
index e7fa5e8..054bc3e 100644
--- a/src/trace_processor/importers/systrace/systrace_line_tokenizer.cc
+++ b/src/trace_processor/importers/systrace/systrace_line_tokenizer.cc
@@ -78,19 +78,19 @@
   line->event_name = matches[5].str();
   line->args_str = SubstrTrim(matches.suffix());
 
-  base::Optional<uint32_t> maybe_pid = base::StringToUInt32(pid_str);
+  std::optional<uint32_t> maybe_pid = base::StringToUInt32(pid_str);
   if (!maybe_pid.has_value()) {
     return util::Status("Could not convert pid " + pid_str);
   }
   line->pid = maybe_pid.value();
 
-  base::Optional<uint32_t> maybe_cpu = base::StringToUInt32(cpu_str);
+  std::optional<uint32_t> maybe_cpu = base::StringToUInt32(cpu_str);
   if (!maybe_cpu.has_value()) {
     return util::Status("Could not convert cpu " + cpu_str);
   }
   line->cpu = maybe_cpu.value();
 
-  base::Optional<double> maybe_ts = base::StringToDouble(ts_str);
+  std::optional<double> maybe_ts = base::StringToDouble(ts_str);
   if (!maybe_ts.has_value()) {
     return util::Status("Could not convert ts");
   }
diff --git a/src/trace_processor/importers/systrace/systrace_parser.cc b/src/trace_processor/importers/systrace/systrace_parser.cc
index 538278d..ac16506 100644
--- a/src/trace_processor/importers/systrace/systrace_parser.cc
+++ b/src/trace_processor/importers/systrace/systrace_parser.cc
@@ -16,7 +16,8 @@
 
 #include "src/trace_processor/importers/systrace/systrace_parser.h"
 
-#include "perfetto/ext/base/optional.h"
+#include <optional>
+
 #include "perfetto/ext/base/string_utils.h"
 #include "src/trace_processor/importers/common/async_track_set_tracker.h"
 #include "src/trace_processor/importers/common/event_tracker.h"
diff --git a/src/trace_processor/importers/systrace/systrace_trace_parser.cc b/src/trace_processor/importers/systrace/systrace_trace_parser.cc
index 167b3c3..d908d17 100644
--- a/src/trace_processor/importers/systrace/systrace_trace_parser.cc
+++ b/src/trace_processor/importers/systrace/systrace_trace_parser.cc
@@ -143,9 +143,9 @@
                    tokens.size() >= 10) {
           // Format is:
           // user pid ppid vsz rss wchan pc s name my cmd line
-          const base::Optional<uint32_t> pid =
+          const std::optional<uint32_t> pid =
               base::StringToUInt32(tokens[1].ToStdString());
-          const base::Optional<uint32_t> ppid =
+          const std::optional<uint32_t> ppid =
               base::StringToUInt32(tokens[2].ToStdString());
           base::StringView name = tokens[8];
           // Command line may contain spaces, merge all remaining tokens:
@@ -163,9 +163,9 @@
                    tokens.size() >= 4) {
           // Format is:
           // username pid tid my cmd line
-          const base::Optional<uint32_t> tgid =
+          const std::optional<uint32_t> tgid =
               base::StringToUInt32(tokens[1].ToStdString());
-          const base::Optional<uint32_t> tid =
+          const std::optional<uint32_t> tid =
               base::StringToUInt32(tokens[2].ToStdString());
           // Command line may contain spaces, merge all remaining tokens:
           const char* cmd_start = tokens[3].data();
diff --git a/src/trace_processor/iterator_impl.h b/src/trace_processor/iterator_impl.h
index 272d13e..0c8b372 100644
--- a/src/trace_processor/iterator_impl.h
+++ b/src/trace_processor/iterator_impl.h
@@ -20,11 +20,11 @@
 #include <sqlite3.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "perfetto/base/build_config.h"
 #include "perfetto/base/export.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/trace_processor/basic_types.h"
 #include "perfetto/trace_processor/iterator.h"
 #include "perfetto/trace_processor/status.h"
@@ -87,7 +87,7 @@
     int ret = sqlite3_step(*stmt_);
     if (PERFETTO_UNLIKELY(ret != SQLITE_ROW && ret != SQLITE_DONE)) {
       status_ = base::ErrStatus("%s", sqlite_utils::FormatErrorMessage(
-                                          stmt_.get(), base::nullopt, db_, ret)
+                                          stmt_.get(), std::nullopt, db_, ret)
                                           .c_message());
       stmt_.reset();
       return false;
diff --git a/src/trace_processor/metrics/metrics.cc b/src/trace_processor/metrics/metrics.cc
index c713532..34c7863 100644
--- a/src/trace_processor/metrics/metrics.cc
+++ b/src/trace_processor/metrics/metrics.cc
@@ -631,9 +631,9 @@
     if (sqlite3_value_type(argv[i]) != SQLITE_TEXT)
       return base::ErrStatus("RUN_METRIC: all keys must be strings");
 
-    base::Optional<std::string> key_str = sqlite_utils::SqlValueToString(
+    std::optional<std::string> key_str = sqlite_utils::SqlValueToString(
         sqlite_utils::SqliteValueToSqlValue(argv[i]));
-    base::Optional<std::string> value_str = sqlite_utils::SqlValueToString(
+    std::optional<std::string> value_str = sqlite_utils::SqlValueToString(
         sqlite_utils::SqliteValueToSqlValue(argv[i + 1]));
 
     if (!value_str) {
diff --git a/src/trace_processor/metrics/metrics.h b/src/trace_processor/metrics/metrics.h
index 72a10f2..16e004c 100644
--- a/src/trace_processor/metrics/metrics.h
+++ b/src/trace_processor/metrics/metrics.h
@@ -46,12 +46,12 @@
   // Optional because not all protos need to have a field associated with them
   // in the root proto; most files will be just be run using RUN_METRIC by
   // other files.
-  base::Optional<std::string> proto_field_name;
+  std::optional<std::string> proto_field_name;
 
   // The table name which will be created by the SQL below to read the proto
   // bytes from.
   // Should only be set when |proto_field_name| is set.
-  base::Optional<std::string> output_table_name;
+  std::optional<std::string> output_table_name;
 
   // The SQL run by this metric.
   std::string sql;
diff --git a/src/trace_processor/metrics/metrics_unittest.cc b/src/trace_processor/metrics/metrics_unittest.cc
index 29f8f6d..6ba25e2 100644
--- a/src/trace_processor/metrics/metrics_unittest.cc
+++ b/src/trace_processor/metrics/metrics_unittest.cc
@@ -77,7 +77,7 @@
   DescriptorPool pool;
   ProtoDescriptor descriptor("file.proto", ".perfetto.protos",
                              ".perfetto.protos.TestProto",
-                             ProtoDescriptor::Type::kMessage, base::nullopt);
+                             ProtoDescriptor::Type::kMessage, std::nullopt);
   descriptor.AddField(FieldDescriptor(
       "int_value", 1, FieldDescriptorProto::TYPE_INT64, "", false));
 
@@ -100,7 +100,7 @@
   DescriptorPool pool;
   ProtoDescriptor descriptor("file.proto", ".perfetto.protos",
                              ".perfetto.protos.TestProto",
-                             ProtoDescriptor::Type::kMessage, base::nullopt);
+                             ProtoDescriptor::Type::kMessage, std::nullopt);
   descriptor.AddField(FieldDescriptor(
       "double_value", 1, FieldDescriptorProto::TYPE_DOUBLE, "", false));
 
@@ -123,7 +123,7 @@
   DescriptorPool pool;
   ProtoDescriptor descriptor("file.proto", ".perfetto.protos",
                              ".perfetto.protos.TestProto",
-                             ProtoDescriptor::Type::kMessage, base::nullopt);
+                             ProtoDescriptor::Type::kMessage, std::nullopt);
   descriptor.AddField(FieldDescriptor(
       "string_value", 1, FieldDescriptorProto::TYPE_STRING, "", false));
 
@@ -149,13 +149,13 @@
   DescriptorPool pool;
   ProtoDescriptor nested("file.proto", ".perfetto.protos",
                          ".perfetto.protos.TestProto.NestedProto",
-                         ProtoDescriptor::Type::kMessage, base::nullopt);
+                         ProtoDescriptor::Type::kMessage, std::nullopt);
   nested.AddField(FieldDescriptor("nested_int_value", 1,
                                   FieldDescriptorProto::TYPE_INT64, "", false));
 
   ProtoDescriptor descriptor("file.proto", ".perfetto.protos",
                              ".perfetto.protos.TestProto",
-                             ProtoDescriptor::Type::kMessage, base::nullopt);
+                             ProtoDescriptor::Type::kMessage, std::nullopt);
   auto field =
       FieldDescriptor("nested_value", 1, FieldDescriptorProto::TYPE_MESSAGE,
                       ".perfetto.protos.TestProto.NestedProto", false);
@@ -197,7 +197,7 @@
   DescriptorPool pool;
   ProtoDescriptor descriptor("file.proto", ".perfetto.protos",
                              ".perfetto.protos.TestProto",
-                             ProtoDescriptor::Type::kMessage, base::nullopt);
+                             ProtoDescriptor::Type::kMessage, std::nullopt);
   descriptor.AddField(FieldDescriptor(
       "rep_int_value", 1, FieldDescriptorProto::TYPE_INT64, "", true));
 
@@ -235,7 +235,7 @@
   DescriptorPool pool;
   ProtoDescriptor enum_descriptor("file.proto", ".perfetto.protos",
                                   ".perfetto.protos.TestEnum",
-                                  ProtoDescriptor::Type::kEnum, base::nullopt);
+                                  ProtoDescriptor::Type::kEnum, std::nullopt);
   enum_descriptor.AddEnumValue(1, "FIRST");
   enum_descriptor.AddEnumValue(2, "SECOND");
   enum_descriptor.AddEnumValue(3, "THIRD");
@@ -243,7 +243,7 @@
 
   ProtoDescriptor descriptor("file.proto", ".perfetto.protos",
                              ".perfetto.protos.TestMessage",
-                             ProtoDescriptor::Type::kMessage, base::nullopt);
+                             ProtoDescriptor::Type::kMessage, std::nullopt);
   FieldDescriptor enum_field("enum_value", 1, FieldDescriptorProto::TYPE_ENUM,
                              ".perfetto.protos.TestEnum", false);
   enum_field.set_resolved_type_name(".perfetto.protos.TestEnum");
diff --git a/src/trace_processor/metrics/sql/android/android_startup.sql b/src/trace_processor/metrics/sql/android/android_startup.sql
index 950089f..50da014 100644
--- a/src/trace_processor/metrics/sql/android/android_startup.sql
+++ b/src/trace_processor/metrics/sql/android/android_startup.sql
@@ -305,57 +305,63 @@
       FROM (
         SELECT 'dex2oat running during launch' AS slow_cause
         WHERE
-          DUR_OF_PROCESS_RUNNING_CONCURRENT_TO_LAUNCH(launches.startup_id, '*dex2oat64') > 20e6
+          DUR_OF_PROCESS_RUNNING_CONCURRENT_TO_LAUNCH(launches.startup_id, '*dex2oat64') > 0
 
         UNION ALL
         SELECT 'installd running during launch' AS slow_cause
         WHERE
-          DUR_OF_PROCESS_RUNNING_CONCURRENT_TO_LAUNCH(launches.startup_id, '*installd') > 150e6
+          DUR_OF_PROCESS_RUNNING_CONCURRENT_TO_LAUNCH(launches.startup_id, '*installd') > 0
 
         UNION ALL
         SELECT 'Main Thread - Time spent in Running state'
           AS slow_cause
-        WHERE MAIN_THREAD_TIME_FOR_LAUNCH_AND_STATE(launches.startup_id, 'Running') > 150e6
+        WHERE
+          MAIN_THREAD_TIME_FOR_LAUNCH_AND_STATE(launches.startup_id, 'Running') > launches.dur * 0.8
 
         UNION ALL
         SELECT 'Main Thread - Time spent in Runnable state'
           AS slow_cause
-        WHERE MAIN_THREAD_TIME_FOR_LAUNCH_IN_RUNNABLE_STATE(launches.startup_id) > 100e6
+        WHERE
+          MAIN_THREAD_TIME_FOR_LAUNCH_IN_RUNNABLE_STATE(launches.startup_id) > launches.dur * 0.15
 
         UNION ALL
         SELECT 'Main Thread - Time spent in interruptible sleep state'
           AS slow_cause
-        WHERE MAIN_THREAD_TIME_FOR_LAUNCH_AND_STATE(launches.startup_id, 'S') > 250e6
+        WHERE MAIN_THREAD_TIME_FOR_LAUNCH_AND_STATE(launches.startup_id, 'S') > 2900e6
 
         UNION ALL
         SELECT 'Main Thread - Time spent in Blocking I/O'
-        WHERE MAIN_THREAD_TIME_FOR_LAUNCH_STATE_AND_IO_WAIT(launches.startup_id, 'D*', TRUE) > 300e6
+        WHERE MAIN_THREAD_TIME_FOR_LAUNCH_STATE_AND_IO_WAIT(launches.startup_id, 'D*', TRUE) > 155e6
 
         UNION ALL
         SELECT 'Time spent in OpenDexFilesFromOat*'
           AS slow_cause
-        WHERE ANDROID_SUM_DUR_FOR_STARTUP_AND_SLICE(launches.startup_id, 'OpenDexFilesFromOat*') > 1e6
+        WHERE
+          ANDROID_SUM_DUR_FOR_STARTUP_AND_SLICE(launches.startup_id, 'OpenDexFilesFromOat*')
+            > launches.dur * 0.2
 
         UNION ALL
         SELECT 'Time spent in bindApplication'
           AS slow_cause
-        WHERE ANDROID_SUM_DUR_FOR_STARTUP_AND_SLICE(launches.startup_id, 'bindApplication') > 10e6
+        WHERE ANDROID_SUM_DUR_FOR_STARTUP_AND_SLICE(launches.startup_id, 'bindApplication') > 1250e6
 
         UNION ALL
         SELECT 'Time spent in view inflation'
           AS slow_cause
-        WHERE ANDROID_SUM_DUR_FOR_STARTUP_AND_SLICE(launches.startup_id, 'inflate') > 600e6
+        WHERE ANDROID_SUM_DUR_FOR_STARTUP_AND_SLICE(launches.startup_id, 'inflate') > 450e6
 
         UNION ALL
         SELECT 'Time spent in ResourcesManager#getResources'
           AS slow_cause
         WHERE ANDROID_SUM_DUR_FOR_STARTUP_AND_SLICE(
-          launches.startup_id, 'ResourcesManager#getResources') > 10e6
+          launches.startup_id, 'ResourcesManager#getResources') > 130e6
 
         UNION ALL
         SELECT 'Time spent verifying classes'
           AS slow_cause
-        WHERE ANDROID_SUM_DUR_FOR_STARTUP_AND_SLICE(launches.startup_id, 'VerifyClass*') > 10e6
+        WHERE
+          ANDROID_SUM_DUR_FOR_STARTUP_AND_SLICE(launches.startup_id, 'VerifyClass*')
+            > launches.dur * 0.15
 
         UNION ALL
         SELECT 'Potential CPU contention with '
@@ -371,7 +377,7 @@
           launches.startup_id,
           'Running',
           'Jit thread pool'
-        ) > 120e6
+        ) > 100e6
 
         UNION ALL
         SELECT 'Main Thread - Lock contention'
@@ -379,7 +385,7 @@
         WHERE ANDROID_SUM_DUR_ON_MAIN_THREAD_FOR_STARTUP_AND_SLICE(
           launches.startup_id,
           'Lock contention on*'
-        ) > 25e6
+        ) > launches.dur * 0.2
 
         UNION ALL
         SELECT 'Main Thread - Monitor contention'
@@ -387,7 +393,7 @@
         WHERE ANDROID_SUM_DUR_ON_MAIN_THREAD_FOR_STARTUP_AND_SLICE(
           launches.startup_id,
           'Lock contention on a monitor*'
-        ) > 40e6
+        ) > launches.dur * 0.15
 
         UNION ALL
         SELECT 'GC Activity'
@@ -399,21 +405,21 @@
           SELECT COUNT(1)
           FROM ANDROID_SLICES_FOR_STARTUP_AND_SLICE_NAME(launches.startup_id, 'JIT compiling*')
           WHERE thread_name = 'Jit thread pool'
-        ) > 40
+        ) > 65
 
         UNION ALL
         SELECT 'Broadcast dispatched count'
         WHERE COUNT_SLICES_CONCURRENT_TO_LAUNCH(
           launches.startup_id,
           'Broadcast dispatched*'
-        ) > 10
+        ) > 15
 
         UNION ALL
         SELECT 'Broadcast received count'
         WHERE COUNT_SLICES_CONCURRENT_TO_LAUNCH(
           launches.startup_id,
           'broadcastReceiveReg*'
-        ) > 10
+        ) > 50
 
         UNION ALL
         SELECT 'No baseline or cloud profiles'
diff --git a/src/trace_processor/prelude/functions/create_function_internal.h b/src/trace_processor/prelude/functions/create_function_internal.h
index 83c0723..1f77459 100644
--- a/src/trace_processor/prelude/functions/create_function_internal.h
+++ b/src/trace_processor/prelude/functions/create_function_internal.h
@@ -18,10 +18,10 @@
 #define SRC_TRACE_PROCESSOR_PRELUDE_FUNCTIONS_CREATE_FUNCTION_INTERNAL_H_
 
 #include <sqlite3.h>
+#include <optional>
 #include <string>
 
 #include "perfetto/base/status.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/trace_processor/basic_types.h"
 #include "src/trace_processor/util/sql_argument.h"
diff --git a/src/trace_processor/prelude/functions/create_view_function.cc b/src/trace_processor/prelude/functions/create_view_function.cc
index e93e8c7..3989de4 100644
--- a/src/trace_processor/prelude/functions/create_view_function.cc
+++ b/src/trace_processor/prelude/functions/create_view_function.cc
@@ -381,7 +381,7 @@
     table_->SetErrorMessage(sqlite3_mprintf(
         "%s: SQLite error while stepping statement: %s",
         table_->prototype_.function_name.c_str(),
-        sqlite_utils::FormatErrorMessage(stmt_, base::nullopt, table_->db_, ret)
+        sqlite_utils::FormatErrorMessage(stmt_, std::nullopt, table_->db_, ret)
             .c_message()));
     return ret;
   }
diff --git a/src/trace_processor/prelude/functions/stack_functions.cc b/src/trace_processor/prelude/functions/stack_functions.cc
index 0774d1d..2f8730b 100644
--- a/src/trace_processor/prelude/functions/stack_functions.cc
+++ b/src/trace_processor/prelude/functions/stack_functions.cc
@@ -21,12 +21,12 @@
 #include <cstring>
 #include <deque>
 #include <iterator>
+#include <optional>
 #include <type_traits>
 #include <vector>
 
 #include "perfetto/base/logging.h"
 #include "perfetto/base/status.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/protozero/scattered_heap_buffer.h"
 #include "perfetto/trace_processor/basic_types.h"
 #include "perfetto/trace_processor/status.h"
diff --git a/src/trace_processor/prelude/functions/utils.h b/src/trace_processor/prelude/functions/utils.h
index b92de3c..c4c5392 100644
--- a/src/trace_processor/prelude/functions/utils.h
+++ b/src/trace_processor/prelude/functions/utils.h
@@ -255,7 +255,7 @@
   uint32_t arg_set_id = static_cast<uint32_t>(sqlite3_value_int(argv[0]));
   const char* key = reinterpret_cast<const char*>(sqlite3_value_text(argv[1]));
 
-  base::Optional<Variadic> opt_value;
+  std::optional<Variadic> opt_value;
   RETURN_IF_ERROR(storage->ExtractArg(arg_set_id, key, &opt_value));
 
   if (!opt_value)
diff --git a/src/trace_processor/prelude/operators/span_join_operator.cc b/src/trace_processor/prelude/operators/span_join_operator.cc
index 61aa3b6..7d4ccb8 100644
--- a/src/trace_processor/prelude/operators/span_join_operator.cc
+++ b/src/trace_processor/prelude/operators/span_join_operator.cc
@@ -43,7 +43,7 @@
   return name == kTsColumnName || name == kDurColumnName;
 }
 
-base::Optional<std::string> HasDuplicateColumns(
+std::optional<std::string> HasDuplicateColumns(
     const std::vector<SqliteTable::Column>& cols) {
   std::set<std::string> names;
   for (const auto& col : cols) {
@@ -51,7 +51,7 @@
       return col.name();
     names.insert(col.name());
   }
-  return base::nullopt;
+  return std::nullopt;
 }
 
 std::string OpToString(int op) {
diff --git a/src/trace_processor/prelude/table_functions/ancestor.cc b/src/trace_processor/prelude/table_functions/ancestor.cc
index 4399397..c1656d9 100644
--- a/src/trace_processor/prelude/table_functions/ancestor.cc
+++ b/src/trace_processor/prelude/table_functions/ancestor.cc
@@ -209,13 +209,13 @@
 }
 
 // static
-base::Optional<std::vector<tables::SliceTable::RowNumber>>
+std::optional<std::vector<tables::SliceTable::RowNumber>>
 Ancestor::GetAncestorSlices(const tables::SliceTable& slices,
                             SliceId slice_id) {
   std::vector<tables::SliceTable::RowNumber> ret;
   auto status = GetAncestors(slices, slice_id, ret);
   if (!status.ok())
-    return base::nullopt;
+    return std::nullopt;
   return std::move(ret);  // -Wreturn-std-move-in-c++11
 }
 
diff --git a/src/trace_processor/prelude/table_functions/ancestor.h b/src/trace_processor/prelude/table_functions/ancestor.h
index 4b3ffec..c625f16 100644
--- a/src/trace_processor/prelude/table_functions/ancestor.h
+++ b/src/trace_processor/prelude/table_functions/ancestor.h
@@ -16,10 +16,12 @@
 
 #ifndef SRC_TRACE_PROCESSOR_PRELUDE_TABLE_FUNCTIONS_ANCESTOR_H_
 #define SRC_TRACE_PROCESSOR_PRELUDE_TABLE_FUNCTIONS_ANCESTOR_H_
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
 #include "src/trace_processor/prelude/table_functions/table_function.h"
 #include "src/trace_processor/storage/trace_storage.h"
+#include "src/trace_processor/tables/profiler_tables.h"
+#include "src/trace_processor/tables/slice_tables.h"
 
 namespace perfetto {
 namespace trace_processor {
@@ -73,9 +75,9 @@
                             std::unique_ptr<Table>& table_return) override;
 
   // Returns a vector of rows numbers which are ancestors of |slice_id|.
-  // Returns base::nullopt if an invalid |slice_id| is given. This is used by
+  // Returns std::nullopt if an invalid |slice_id| is given. This is used by
   // ConnectedFlow to traverse flow indirectly connected flow events.
-  static base::Optional<std::vector<tables::SliceTable::RowNumber>>
+  static std::optional<std::vector<tables::SliceTable::RowNumber>>
   GetAncestorSlices(const tables::SliceTable& slices, SliceId slice_id);
 
  private:
diff --git a/src/trace_processor/prelude/table_functions/connected_flow.h b/src/trace_processor/prelude/table_functions/connected_flow.h
index faf3f71..c05e25e 100644
--- a/src/trace_processor/prelude/table_functions/connected_flow.h
+++ b/src/trace_processor/prelude/table_functions/connected_flow.h
@@ -19,6 +19,7 @@
 
 #include "src/trace_processor/prelude/table_functions/table_function.h"
 #include "src/trace_processor/storage/trace_storage.h"
+#include "src/trace_processor/tables/flow_tables.h"
 
 #include <queue>
 #include <set>
diff --git a/src/trace_processor/prelude/table_functions/descendant.cc b/src/trace_processor/prelude/table_functions/descendant.cc
index 89cd4a2..75cb8c9 100644
--- a/src/trace_processor/prelude/table_functions/descendant.cc
+++ b/src/trace_processor/prelude/table_functions/descendant.cc
@@ -193,13 +193,13 @@
 }
 
 // static
-base::Optional<std::vector<tables::SliceTable::RowNumber>>
+std::optional<std::vector<tables::SliceTable::RowNumber>>
 Descendant::GetDescendantSlices(const tables::SliceTable& slices,
                                 SliceId slice_id) {
   std::vector<tables::SliceTable::RowNumber> ret;
   auto status = GetDescendants(slices, slice_id, ret);
   if (!status.ok())
-    return base::nullopt;
+    return std::nullopt;
   return std::move(ret);
 }
 
diff --git a/src/trace_processor/prelude/table_functions/descendant.h b/src/trace_processor/prelude/table_functions/descendant.h
index d423d07..8e93811 100644
--- a/src/trace_processor/prelude/table_functions/descendant.h
+++ b/src/trace_processor/prelude/table_functions/descendant.h
@@ -17,7 +17,8 @@
 #ifndef SRC_TRACE_PROCESSOR_PRELUDE_TABLE_FUNCTIONS_DESCENDANT_H_
 #define SRC_TRACE_PROCESSOR_PRELUDE_TABLE_FUNCTIONS_DESCENDANT_H_
 
-#include "perfetto/ext/base/optional.h"
+#include <optional>
+
 #include "src/trace_processor/prelude/table_functions/table_function.h"
 #include "src/trace_processor/storage/trace_storage.h"
 
@@ -64,9 +65,9 @@
                             std::unique_ptr<Table>& table_return) override;
 
   // Returns a vector of slice rows which are descendants of |slice_id|. Returns
-  // base::nullopt if an invalid |slice_id| is given. This is used by
+  // std::nullopt if an invalid |slice_id| is given. This is used by
   // ConnectedFlow to traverse flow indirectly connected flow events.
-  static base::Optional<std::vector<tables::SliceTable::RowNumber>>
+  static std::optional<std::vector<tables::SliceTable::RowNumber>>
   GetDescendantSlices(const tables::SliceTable& slices, SliceId slice_id);
 
  private:
diff --git a/src/trace_processor/prelude/table_functions/experimental_annotated_stack.cc b/src/trace_processor/prelude/table_functions/experimental_annotated_stack.cc
index 494931b..8198376 100644
--- a/src/trace_processor/prelude/table_functions/experimental_annotated_stack.cc
+++ b/src/trace_processor/prelude/table_functions/experimental_annotated_stack.cc
@@ -16,7 +16,8 @@
 
 #include "src/trace_processor/prelude/table_functions/experimental_annotated_stack.h"
 
-#include "perfetto/ext/base/optional.h"
+#include <optional>
+
 #include "perfetto/ext/base/string_utils.h"
 #include "src/trace_processor/sqlite/sqlite_utils.h"
 #include "src/trace_processor/storage/trace_storage.h"
@@ -173,7 +174,7 @@
   // entries, each pointing at a frame.
   std::vector<CallsiteTable::RowNumber> cs_rows;
   cs_rows.push_back(opt_start_ref->ToRowNumber());
-  base::Optional<CallsiteId> maybe_parent_id = opt_start_ref->parent_id();
+  std::optional<CallsiteId> maybe_parent_id = opt_start_ref->parent_id();
   while (maybe_parent_id) {
     auto parent_ref = *cs_table.FindById(*maybe_parent_id);
     cs_rows.push_back(parent_ref.ToRowNumber());
diff --git a/src/trace_processor/prelude/table_functions/experimental_counter_dur.cc b/src/trace_processor/prelude/table_functions/experimental_counter_dur.cc
index 2f2fbcd..3513c89 100644
--- a/src/trace_processor/prelude/table_functions/experimental_counter_dur.cc
+++ b/src/trace_processor/prelude/table_functions/experimental_counter_dur.cc
@@ -16,6 +16,8 @@
 
 #include "src/trace_processor/prelude/table_functions/experimental_counter_dur.h"
 
+#include "src/trace_processor/tables/counter_tables.h"
+
 namespace perfetto {
 namespace trace_processor {
 namespace tables {
diff --git a/src/trace_processor/prelude/table_functions/experimental_counter_dur_unittest.cc b/src/trace_processor/prelude/table_functions/experimental_counter_dur_unittest.cc
index d194b23..d812394 100644
--- a/src/trace_processor/prelude/table_functions/experimental_counter_dur_unittest.cc
+++ b/src/trace_processor/prelude/table_functions/experimental_counter_dur_unittest.cc
@@ -31,7 +31,7 @@
 
 TEST(ExperimentalCounterDur, SmokeDur) {
   StringPool pool;
-  tables::CounterTable table(&pool, nullptr);
+  tables::CounterTable table(&pool);
 
   table.Insert(CounterRow(100 /* ts */, 1 /* track_id */));
   table.Insert(CounterRow(102 /* ts */, 2 /* track_id */));
diff --git a/src/trace_processor/prelude/table_functions/experimental_flamegraph.cc b/src/trace_processor/prelude/table_functions/experimental_flamegraph.cc
index 790ce96..ae855be 100644
--- a/src/trace_processor/prelude/table_functions/experimental_flamegraph.cc
+++ b/src/trace_processor/prelude/table_functions/experimental_flamegraph.cc
@@ -119,8 +119,8 @@
     }
   }
 
-  base::Optional<UniquePid> upid;
-  base::Optional<std::string> upid_group;
+  std::optional<UniquePid> upid;
+  std::optional<std::string> upid_group;
   if (upid_it != cs.end()) {
     upid = static_cast<UniquePid>(upid_it->value.AsLong());
   } else {
@@ -213,7 +213,7 @@
       ComputeFocusedState(*in, Matcher(focus_str));
   std::unique_ptr<ExperimentalFlamegraphNodesTable> tbl(
       new tables::ExperimentalFlamegraphNodesTable(
-          storage->mutable_string_pool(), nullptr));
+          storage->mutable_string_pool()));
 
   // Recompute cumulative counts
   std::vector<CumulativeCounts> node_to_cumulatives(in->row_count());
diff --git a/src/trace_processor/prelude/table_functions/experimental_flamegraph.h b/src/trace_processor/prelude/table_functions/experimental_flamegraph.h
index 8a7e9ae..60792f9 100644
--- a/src/trace_processor/prelude/table_functions/experimental_flamegraph.h
+++ b/src/trace_processor/prelude/table_functions/experimental_flamegraph.h
@@ -34,8 +34,8 @@
     ProfileType profile_type;
     int64_t ts;
     std::vector<TimeConstraints> time_constraints;
-    base::Optional<UniquePid> upid;
-    base::Optional<std::string> upid_group;
+    std::optional<UniquePid> upid;
+    std::optional<std::string> upid_group;
     std::string focus_str;
   };
 
diff --git a/src/trace_processor/prelude/table_functions/experimental_flat_slice.cc b/src/trace_processor/prelude/table_functions/experimental_flat_slice.cc
index 41e7e01..c9bdfed 100644
--- a/src/trace_processor/prelude/table_functions/experimental_flat_slice.cc
+++ b/src/trace_processor/prelude/table_functions/experimental_flat_slice.cc
@@ -74,7 +74,7 @@
                                              int64_t start_bound,
                                              int64_t end_bound) {
   std::unique_ptr<tables::ExperimentalFlatSliceTable> out(
-      new tables::ExperimentalFlatSliceTable(pool, nullptr));
+      new tables::ExperimentalFlatSliceTable(pool));
 
   auto insert_slice = [&](uint32_t i, int64_t ts,
                           tables::TrackTable::Id track_id) {
@@ -98,7 +98,7 @@
     row.category = kNullStringId;
     row.name = kNullStringId;
     row.arg_set_id = kInvalidArgSetId;
-    row.source_id = base::nullopt;
+    row.source_id = std::nullopt;
     row.start_bound = start_bound;
     row.end_bound = end_bound;
     return out->Insert(row).row;
@@ -111,7 +111,7 @@
   };
 
   struct ActiveSlice {
-    base::Optional<uint32_t> source_row;
+    std::optional<uint32_t> source_row;
     uint32_t out_row = std::numeric_limits<uint32_t>::max();
 
     bool is_sentinel() const { return !source_row; }
@@ -185,7 +185,7 @@
       return;
 
     // Otherwise, Add a sentinel slice after the end of the active slice.
-    t.active.source_row = base::nullopt;
+    t.active.source_row = std::nullopt;
     t.active.out_row = insert_sentinel(ts + dur, track_id);
   };
 
diff --git a/src/trace_processor/prelude/table_functions/experimental_flat_slice.h b/src/trace_processor/prelude/table_functions/experimental_flat_slice.h
index aa354c6..0cb10b5 100644
--- a/src/trace_processor/prelude/table_functions/experimental_flat_slice.h
+++ b/src/trace_processor/prelude/table_functions/experimental_flat_slice.h
@@ -17,7 +17,8 @@
 #ifndef SRC_TRACE_PROCESSOR_PRELUDE_TABLE_FUNCTIONS_EXPERIMENTAL_FLAT_SLICE_H_
 #define SRC_TRACE_PROCESSOR_PRELUDE_TABLE_FUNCTIONS_EXPERIMENTAL_FLAT_SLICE_H_
 
-#include "perfetto/ext/base/optional.h"
+#include <optional>
+
 #include "src/trace_processor/prelude/table_functions/table_function.h"
 #include "src/trace_processor/storage/trace_storage.h"
 
diff --git a/src/trace_processor/prelude/table_functions/experimental_flat_slice_unittest.cc b/src/trace_processor/prelude/table_functions/experimental_flat_slice_unittest.cc
index 8218acc..3d6a0f6 100644
--- a/src/trace_processor/prelude/table_functions/experimental_flat_slice_unittest.cc
+++ b/src/trace_processor/prelude/table_functions/experimental_flat_slice_unittest.cc
@@ -69,7 +69,7 @@
 TEST(ExperimentalFlatSlice, Smoke) {
   StringPool pool;
   TableInseter inserter;
-  tables::SliceTable table(&pool, nullptr);
+  tables::SliceTable table(&pool);
 
   // A simple stack on track 1.
   inserter.Insert(100, 10, 0, TrackId{1});
@@ -136,7 +136,7 @@
 TEST(ExperimentalFlatSlice, Bounds) {
   StringPool pool;
   TableInseter inserter;
-  tables::SliceTable table(&pool, nullptr);
+  tables::SliceTable table(&pool);
 
   /// Our timebounds is between 200 and 300.
   int64_t start = 200;
diff --git a/src/trace_processor/prelude/table_functions/experimental_sched_upid.cc b/src/trace_processor/prelude/table_functions/experimental_sched_upid.cc
index 54443bb..45a76ea 100644
--- a/src/trace_processor/prelude/table_functions/experimental_sched_upid.cc
+++ b/src/trace_processor/prelude/table_functions/experimental_sched_upid.cc
@@ -22,7 +22,7 @@
 #define PERFETTO_TP_SCHED_UPID_TABLE_DEF(NAME, PARENT, C)     \
   NAME(ExperimentalSchedUpidTable, "experimental_sched_upid") \
   PARENT(PERFETTO_TP_SCHED_SLICE_TABLE_DEF, C)                \
-  C(base::Optional<UniquePid>, upid)
+  C(std::optional<UniquePid>, upid)
 
 PERFETTO_TP_TABLE(PERFETTO_TP_SCHED_UPID_TABLE_DEF);
 
@@ -65,9 +65,9 @@
   return base::OkStatus();
 }
 
-ColumnStorage<base::Optional<UniquePid>>
+ColumnStorage<std::optional<UniquePid>>
 ExperimentalSchedUpid::ComputeUpidColumn() {
-  ColumnStorage<base::Optional<UniquePid>> upid;
+  ColumnStorage<std::optional<UniquePid>> upid;
   for (uint32_t i = 0; i < sched_slice_table_->row_count(); ++i) {
     upid.Append(thread_table_->upid()[sched_slice_table_->utid()[i]]);
   }
diff --git a/src/trace_processor/prelude/table_functions/experimental_sched_upid.h b/src/trace_processor/prelude/table_functions/experimental_sched_upid.h
index 7a9f23d..6837c18 100644
--- a/src/trace_processor/prelude/table_functions/experimental_sched_upid.h
+++ b/src/trace_processor/prelude/table_functions/experimental_sched_upid.h
@@ -41,7 +41,7 @@
                             std::unique_ptr<Table>& table_return) override;
 
  private:
-  ColumnStorage<base::Optional<UniquePid>> ComputeUpidColumn();
+  ColumnStorage<std::optional<UniquePid>> ComputeUpidColumn();
 
   const tables::SchedSliceTable* sched_slice_table_;
   const tables::ThreadTable* thread_table_;
diff --git a/src/trace_processor/prelude/table_functions/experimental_slice_layout.cc b/src/trace_processor/prelude/table_functions/experimental_slice_layout.cc
index 32bf906..e544dbb 100644
--- a/src/trace_processor/prelude/table_functions/experimental_slice_layout.cc
+++ b/src/trace_processor/prelude/table_functions/experimental_slice_layout.cc
@@ -16,7 +16,8 @@
 
 #include "src/trace_processor/prelude/table_functions/experimental_slice_layout.h"
 
-#include "perfetto/ext/base/optional.h"
+#include <optional>
+
 #include "perfetto/ext/base/string_splitter.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "src/trace_processor/sqlite/sqlite_utils.h"
@@ -88,7 +89,7 @@
     if (is_filter_track_ids && is_equal && is_string) {
       filter_string = c.value.AsString();
       for (base::StringSplitter sp(filter_string, ','); sp.Next();) {
-        base::Optional<uint32_t> maybe = base::CStringToUInt32(sp.cur_token());
+        std::optional<uint32_t> maybe = base::CStringToUInt32(sp.cur_token());
         if (maybe) {
           selected_tracks.insert(TrackId{maybe.value()});
         }
@@ -129,7 +130,7 @@
 tables::SliceTable::Id ExperimentalSliceLayout::InsertSlice(
     std::map<tables::SliceTable::Id, tables::SliceTable::Id>& id_map,
     tables::SliceTable::Id id,
-    base::Optional<tables::SliceTable::Id> parent_id) {
+    std::optional<tables::SliceTable::Id> parent_id) {
   if (parent_id) {
     tables::SliceTable::Id root_id = id_map[parent_id.value()];
     id_map[id] = root_id;
diff --git a/src/trace_processor/prelude/table_functions/experimental_slice_layout.h b/src/trace_processor/prelude/table_functions/experimental_slice_layout.h
index 5089e7a..19af803 100644
--- a/src/trace_processor/prelude/table_functions/experimental_slice_layout.h
+++ b/src/trace_processor/prelude/table_functions/experimental_slice_layout.h
@@ -59,7 +59,7 @@
   tables::SliceTable::Id InsertSlice(
       std::map<tables::SliceTable::Id, tables::SliceTable::Id>& id_map,
       tables::SliceTable::Id id,
-      base::Optional<tables::SliceTable::Id> parent_id);
+      std::optional<tables::SliceTable::Id> parent_id);
 
   // TODO(lalitm): remove this cache and move to having explicitly scoped
   // lifetimes of dynamic tables.
diff --git a/src/trace_processor/prelude/table_functions/experimental_slice_layout_unittest.cc b/src/trace_processor/prelude/table_functions/experimental_slice_layout_unittest.cc
index 37079a7..43c986d 100644
--- a/src/trace_processor/prelude/table_functions/experimental_slice_layout_unittest.cc
+++ b/src/trace_processor/prelude/table_functions/experimental_slice_layout_unittest.cc
@@ -72,18 +72,17 @@
       << "Actual:" << actual << "\nExpected:" << expected;
 }
 
-tables::SliceTable::Id Insert(
-    tables::SliceTable* table,
-    int64_t ts,
-    int64_t dur,
-    uint32_t track_id,
-    StringId name,
-    base::Optional<tables::SliceTable::Id> parent_id) {
+tables::SliceTable::Id Insert(tables::SliceTable* table,
+                              int64_t ts,
+                              int64_t dur,
+                              uint32_t track_id,
+                              StringId name,
+                              std::optional<tables::SliceTable::Id> parent_id) {
   tables::SliceTable::Row row;
   row.ts = ts;
   row.dur = dur;
   row.depth = 0;
-  base::Optional<tables::SliceTable::Id> id = parent_id;
+  std::optional<tables::SliceTable::Id> id = parent_id;
   while (id) {
     row.depth++;
     id = table->parent_id()[id.value().value];
@@ -96,11 +95,11 @@
 
 TEST(ExperimentalSliceLayoutTest, SingleRow) {
   StringPool pool;
-  tables::SliceTable slice_table(&pool, nullptr);
+  tables::SliceTable slice_table(&pool);
   StringId name = pool.InternString("SingleRow");
 
   Insert(&slice_table, 1 /*ts*/, 5 /*dur*/, 1 /*track_id*/, name,
-         base::nullopt /*parent*/);
+         std::nullopt /*parent*/);
 
   ExperimentalSliceLayout gen(&pool, &slice_table);
 
@@ -116,11 +115,11 @@
 
 TEST(ExperimentalSliceLayoutTest, DoubleRow) {
   StringPool pool;
-  tables::SliceTable slice_table(&pool, nullptr);
+  tables::SliceTable slice_table(&pool);
   StringId name = pool.InternString("SingleRow");
 
   auto id = Insert(&slice_table, 1 /*ts*/, 5 /*dur*/, 1 /*track_id*/, name,
-                   base::nullopt);
+                   std::nullopt);
   Insert(&slice_table, 1 /*ts*/, 5 /*dur*/, 1 /*track_id*/, name, id);
 
   ExperimentalSliceLayout gen(&pool, &slice_table);
@@ -138,11 +137,11 @@
 
 TEST(ExperimentalSliceLayoutTest, MultipleRows) {
   StringPool pool;
-  tables::SliceTable slice_table(&pool, nullptr);
+  tables::SliceTable slice_table(&pool);
   StringId name = pool.InternString("MultipleRows");
 
   auto a = Insert(&slice_table, 1 /*ts*/, 5 /*dur*/, 1 /*track_id*/, name,
-                  base::nullopt);
+                  std::nullopt);
   auto b = Insert(&slice_table, 1 /*ts*/, 4 /*dur*/, 1 /*track_id*/, name, a);
   auto c = Insert(&slice_table, 1 /*ts*/, 3 /*dur*/, 1 /*track_id*/, name, b);
   auto d = Insert(&slice_table, 1 /*ts*/, 2 /*dur*/, 1 /*track_id*/, name, c);
@@ -167,17 +166,17 @@
 
 TEST(ExperimentalSliceLayoutTest, MultipleTracks) {
   StringPool pool;
-  tables::SliceTable slice_table(&pool, nullptr);
+  tables::SliceTable slice_table(&pool);
   StringId name1 = pool.InternString("Slice1");
   StringId name2 = pool.InternString("Slice2");
   StringId name3 = pool.InternString("Slice3");
   StringId name4 = pool.InternString("Track4");
 
   auto a = Insert(&slice_table, 1 /*ts*/, 4 /*dur*/, 1 /*track_id*/, name1,
-                  base::nullopt);
+                  std::nullopt);
   auto b = Insert(&slice_table, 1 /*ts*/, 2 /*dur*/, 1 /*track_id*/, name2, a);
   auto x = Insert(&slice_table, 4 /*ts*/, 4 /*dur*/, 2 /*track_id*/, name3,
-                  base::nullopt);
+                  std::nullopt);
   auto y = Insert(&slice_table, 4 /*ts*/, 2 /*dur*/, 2 /*track_id*/, name4, x);
   base::ignore_result(b);
   base::ignore_result(y);
@@ -199,7 +198,7 @@
 
 TEST(ExperimentalSliceLayoutTest, MultipleTracksWithGap) {
   StringPool pool;
-  tables::SliceTable slice_table(&pool, nullptr);
+  tables::SliceTable slice_table(&pool);
   StringId name1 = pool.InternString("Slice1");
   StringId name2 = pool.InternString("Slice2");
   StringId name3 = pool.InternString("Slice3");
@@ -208,13 +207,13 @@
   StringId name6 = pool.InternString("Slice6");
 
   auto a = Insert(&slice_table, 0 /*ts*/, 4 /*dur*/, 1 /*track_id*/, name1,
-                  base::nullopt);
+                  std::nullopt);
   auto b = Insert(&slice_table, 0 /*ts*/, 2 /*dur*/, 1 /*track_id*/, name2, a);
   auto p = Insert(&slice_table, 3 /*ts*/, 4 /*dur*/, 2 /*track_id*/, name3,
-                  base::nullopt);
+                  std::nullopt);
   auto q = Insert(&slice_table, 3 /*ts*/, 2 /*dur*/, 2 /*track_id*/, name4, p);
   auto x = Insert(&slice_table, 5 /*ts*/, 4 /*dur*/, 1 /*track_id*/, name5,
-                  base::nullopt);
+                  std::nullopt);
   auto y = Insert(&slice_table, 5 /*ts*/, 2 /*dur*/, 1 /*track_id*/, name6, x);
   base::ignore_result(b);
   base::ignore_result(q);
@@ -237,7 +236,7 @@
 
 TEST(ExperimentalSliceLayoutTest, PreviousGroupFullyNested) {
   StringPool pool;
-  tables::SliceTable slice_table(&pool, nullptr);
+  tables::SliceTable slice_table(&pool);
   StringId name = pool.InternString("Slice");
 
   // This test ensures that our bounding box logic works when the bounding box
@@ -246,20 +245,20 @@
 
   // Group 1 exists just to create push group 2 down one row.
   auto a = Insert(&slice_table, 0 /*ts*/, 1 /*dur*/, 1 /*track_id*/, name,
-                  base::nullopt);
+                  std::nullopt);
   base::ignore_result(a);
 
   // Group 2 has a depth of 2 so it theoretically "nests" inside a group of
   // depth 4.
   auto c = Insert(&slice_table, 0 /*ts*/, 10 /*dur*/, 2 /*track_id*/, name,
-                  base::nullopt);
+                  std::nullopt);
   auto d = Insert(&slice_table, 0 /*ts*/, 9 /*dur*/, 2 /*track_id*/, name, c);
   base::ignore_result(d);
 
   // Group 3 has a depth of 4 so it could cause group 2 to "nest" if our
   // layout algorithm did not work correctly.
   auto p = Insert(&slice_table, 3 /*ts*/, 4 /*dur*/, 3 /*track_id*/, name,
-                  base::nullopt);
+                  std::nullopt);
   auto q = Insert(&slice_table, 3 /*ts*/, 3 /*dur*/, 3 /*track_id*/, name, p);
   auto r = Insert(&slice_table, 3 /*ts*/, 2 /*dur*/, 3 /*track_id*/, name, q);
   auto s = Insert(&slice_table, 3 /*ts*/, 1 /*dur*/, 3 /*track_id*/, name, r);
@@ -285,7 +284,7 @@
 
 TEST(ExperimentalSliceLayoutTest, FilterOutTracks) {
   StringPool pool;
-  tables::SliceTable slice_table(&pool, nullptr);
+  tables::SliceTable slice_table(&pool);
   StringId name1 = pool.InternString("Slice1");
   StringId name2 = pool.InternString("Slice2");
   StringId name3 = pool.InternString("Slice3");
@@ -293,14 +292,14 @@
   StringId name5 = pool.InternString("Slice5");
 
   auto a = Insert(&slice_table, 0 /*ts*/, 4 /*dur*/, 1 /*track_id*/, name1,
-                  base::nullopt);
+                  std::nullopt);
   auto b = Insert(&slice_table, 0 /*ts*/, 2 /*dur*/, 1 /*track_id*/, name2, a);
   auto p = Insert(&slice_table, 3 /*ts*/, 4 /*dur*/, 2 /*track_id*/, name3,
-                  base::nullopt);
+                  std::nullopt);
   auto q = Insert(&slice_table, 3 /*ts*/, 2 /*dur*/, 2 /*track_id*/, name4, p);
   // This slice should be ignored as it's not in the filter below:
   Insert(&slice_table, 0 /*ts*/, 9 /*dur*/, 3 /*track_id*/, name5,
-         base::nullopt);
+         std::nullopt);
   base::ignore_result(b);
   base::ignore_result(q);
 
diff --git a/src/trace_processor/prelude/table_functions/flamegraph_construction_algorithms.cc b/src/trace_processor/prelude/table_functions/flamegraph_construction_algorithms.cc
index e47c63c..7424134 100644
--- a/src/trace_processor/prelude/table_functions/flamegraph_construction_algorithms.cc
+++ b/src/trace_processor/prelude/table_functions/flamegraph_construction_algorithms.cc
@@ -29,9 +29,9 @@
 struct MergedCallsite {
   StringId frame_name;
   StringId mapping_name;
-  base::Optional<StringId> source_file;
-  base::Optional<uint32_t> line_number;
-  base::Optional<uint32_t> parent_idx;
+  std::optional<StringId> source_file;
+  std::optional<uint32_t> line_number;
+  std::optional<uint32_t> parent_idx;
   bool operator<(const MergedCallsite& o) const {
     return std::tie(frame_name, mapping_name, parent_idx) <
            std::tie(o.frame_name, o.mapping_name, o.parent_idx);
@@ -60,15 +60,14 @@
       *mapping_tbl.id().IndexOf(frames_tbl.mapping()[frame_idx]);
   StringId mapping_name = mapping_tbl.name()[mapping_idx];
 
-  base::Optional<uint32_t> symbol_set_id =
-      frames_tbl.symbol_set_id()[frame_idx];
+  std::optional<uint32_t> symbol_set_id = frames_tbl.symbol_set_id()[frame_idx];
 
   if (!symbol_set_id) {
     StringId frame_name = frames_tbl.name()[frame_idx];
-    base::Optional<StringId> deobfuscated_name =
+    std::optional<StringId> deobfuscated_name =
         frames_tbl.deobfuscated_name()[frame_idx];
     return {{deobfuscated_name ? *deobfuscated_name : frame_name, mapping_name,
-             base::nullopt, base::nullopt, base::nullopt}};
+             std::nullopt, std::nullopt, std::nullopt}};
   }
 
   std::vector<MergedCallsite> result;
@@ -82,7 +81,7 @@
        ++i) {
     result.emplace_back(MergedCallsite{
         symbols_tbl.name()[i], mapping_name, symbols_tbl.source_file()[i],
-        symbols_tbl.line_number()[i], base::nullopt});
+        symbols_tbl.line_number()[i], std::nullopt});
   }
   std::reverse(result.begin(), result.end());
   return result;
@@ -91,8 +90,8 @@
 
 static FlamegraphTableAndMergedCallsites BuildFlamegraphTableTreeStructure(
     TraceStorage* storage,
-    base::Optional<UniquePid> upid,
-    base::Optional<std::string> upid_group,
+    std::optional<UniquePid> upid,
+    std::optional<std::string> upid_group,
     int64_t default_timestamp,
     StringId profile_type) {
   const tables::StackProfileCallsiteTable& callsites_tbl =
@@ -104,13 +103,13 @@
 
   std::unique_ptr<tables::ExperimentalFlamegraphNodesTable> tbl(
       new tables::ExperimentalFlamegraphNodesTable(
-          storage->mutable_string_pool(), nullptr));
+          storage->mutable_string_pool()));
 
   // FORWARD PASS:
   // Aggregate callstacks by frame name / mapping name. Use symbolization
   // data.
   for (uint32_t i = 0; i < callsites_tbl.row_count(); ++i) {
-    base::Optional<uint32_t> parent_idx;
+    std::optional<uint32_t> parent_idx;
 
     auto opt_parent_id = callsites_tbl.parent_id()[i];
     if (opt_parent_id) {
@@ -133,8 +132,10 @@
         tables::ExperimentalFlamegraphNodesTable::Row row{};
         if (parent_idx) {
           row.depth = tbl->depth()[*parent_idx] + 1;
+          row.parent_id = tbl->id()[*parent_idx];
         } else {
           row.depth = 0;
+          row.parent_id = std::nullopt;
         }
 
         // The 'ts' column is given a default value, taken from the query.
@@ -158,8 +159,6 @@
         row.profile_type = profile_type;
         row.name = merged_callsite.frame_name;
         row.map_name = merged_callsite.mapping_name;
-        if (parent_idx)
-          row.parent_id = tbl->id()[*parent_idx];
         tbl->Insert(row);
         callsites_to_rowid[merged_callsite] =
             static_cast<uint32_t>(merged_callsites_to_table_idx.size() - 1);
@@ -170,10 +169,10 @@
         MergedCallsite saved_callsite = it->first;
         callsites_to_rowid.erase(saved_callsite);
         if (saved_callsite.source_file != merged_callsite.source_file) {
-          saved_callsite.source_file = base::nullopt;
+          saved_callsite.source_file = std::nullopt;
         }
         if (saved_callsite.line_number != merged_callsite.line_number) {
-          saved_callsite.line_number = base::nullopt;
+          saved_callsite.line_number = std::nullopt;
         }
         callsites_to_rowid[saved_callsite] = it->second;
       }
@@ -335,7 +334,7 @@
   }
   StringId profile_type = storage->InternString("native");
   FlamegraphTableAndMergedCallsites table_and_callsites =
-      BuildFlamegraphTableTreeStructure(storage, upid, base::nullopt, timestamp,
+      BuildFlamegraphTableTreeStructure(storage, upid, std::nullopt, timestamp,
                                         profile_type);
   return BuildFlamegraphTableHeapSizeAndCount(
       std::move(table_and_callsites.tbl),
@@ -345,8 +344,8 @@
 std::unique_ptr<tables::ExperimentalFlamegraphNodesTable>
 BuildNativeCallStackSamplingFlamegraph(
     TraceStorage* storage,
-    base::Optional<UniquePid> upid,
-    base::Optional<std::string> upid_group,
+    std::optional<UniquePid> upid,
+    std::optional<std::string> upid_group,
     const std::vector<TimeConstraints>& time_constraints) {
   // 1.Extract required upids from input.
   std::unordered_set<UniquePid> upids;
@@ -354,7 +353,7 @@
     upids.insert(*upid);
   } else {
     for (base::StringSplitter sp(*upid_group, ','); sp.Next();) {
-      base::Optional<uint32_t> maybe = base::CStringToUInt32(sp.cur_token());
+      std::optional<uint32_t> maybe = base::CStringToUInt32(sp.cur_token());
       if (maybe) {
         upids.insert(*maybe);
       }
@@ -365,7 +364,7 @@
   std::set<tables::ThreadTable::Id> utids;
   RowMap threads_in_pid_rm;
   for (uint32_t i = 0; i < storage->thread_table().row_count(); ++i) {
-    base::Optional<uint32_t> row_upid = storage->thread_table().upid()[i];
+    std::optional<uint32_t> row_upid = storage->thread_table().upid()[i];
     if (row_upid && upids.count(*row_upid) > 0) {
       threads_in_pid_rm.Insert(i);
     }
@@ -405,7 +404,7 @@
   if (filtered.row_count() == 0) {
     std::unique_ptr<tables::ExperimentalFlamegraphNodesTable> empty_tbl(
         new tables::ExperimentalFlamegraphNodesTable(
-            storage->mutable_string_pool(), nullptr));
+            storage->mutable_string_pool()));
     return empty_tbl;
   }
 
diff --git a/src/trace_processor/prelude/table_functions/flamegraph_construction_algorithms.h b/src/trace_processor/prelude/table_functions/flamegraph_construction_algorithms.h
index fdda131..82c79b8 100644
--- a/src/trace_processor/prelude/table_functions/flamegraph_construction_algorithms.h
+++ b/src/trace_processor/prelude/table_functions/flamegraph_construction_algorithms.h
@@ -36,8 +36,8 @@
 std::unique_ptr<tables::ExperimentalFlamegraphNodesTable>
 BuildNativeCallStackSamplingFlamegraph(
     TraceStorage* storage,
-    base::Optional<UniquePid> upid,
-    base::Optional<std::string> upid_group,
+    std::optional<UniquePid> upid,
+    std::optional<std::string> upid_group,
     const std::vector<TimeConstraints>& time_constraints);
 }  // namespace trace_processor
 }  // namespace perfetto
diff --git a/src/trace_processor/rpc/httpd.cc b/src/trace_processor/rpc/httpd.cc
index 97bee91..2e59675 100644
--- a/src/trace_processor/rpc/httpd.cc
+++ b/src/trace_processor/rpc/httpd.cc
@@ -258,7 +258,7 @@
 void RunHttpRPCServer(std::unique_ptr<TraceProcessor> preloaded_instance,
                       std::string port_number) {
   Httpd srv(std::move(preloaded_instance));
-  base::Optional<int> port_opt = base::StringToInt32(port_number);
+  std::optional<int> port_opt = base::StringToInt32(port_number);
   int port = port_opt.has_value() ? *port_opt : kBindPort;
   srv.Run(port);
 }
diff --git a/src/trace_processor/sorter/trace_token_buffer.cc b/src/trace_processor/sorter/trace_token_buffer.cc
index c8d2899..7541a4d 100644
--- a/src/trace_processor/sorter/trace_token_buffer.cc
+++ b/src/trace_processor/sorter/trace_token_buffer.cc
@@ -22,11 +22,11 @@
 #include <cstring>
 #include <functional>
 #include <limits>
+#include <optional>
 #include <type_traits>
 #include <utility>
 
 #include "perfetto/base/compiler.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/trace_processor/trace_blob.h"
 #include "perfetto/trace_processor/trace_blob_view.h"
 #include "src/trace_processor/importers/common/parser_types.h"
diff --git a/src/trace_processor/sorter/trace_token_buffer.h b/src/trace_processor/sorter/trace_token_buffer.h
index a222bbc..85af6ac 100644
--- a/src/trace_processor/sorter/trace_token_buffer.h
+++ b/src/trace_processor/sorter/trace_token_buffer.h
@@ -19,12 +19,12 @@
 
 #include <cstdint>
 #include <limits>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "perfetto/base/compiler.h"
 #include "perfetto/ext/base/circular_queue.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/utils.h"
 #include "perfetto/trace_processor/trace_blob.h"
 #include "perfetto/trace_processor/trace_blob_view.h"
diff --git a/src/trace_processor/sorter/trace_token_buffer_unittest.cc b/src/trace_processor/sorter/trace_token_buffer_unittest.cc
index 7d6292f..a8657d2 100644
--- a/src/trace_processor/sorter/trace_token_buffer_unittest.cc
+++ b/src/trace_processor/sorter/trace_token_buffer_unittest.cc
@@ -16,8 +16,9 @@
 
 #include "src/trace_processor/sorter/trace_token_buffer.h"
 
+#include <optional>
+
 #include "perfetto/base/compiler.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/trace_processor/trace_blob.h"
 #include "perfetto/trace_processor/trace_blob_view.h"
 #include "src/trace_processor/importers/common/parser_types.h"
@@ -145,7 +146,7 @@
   ASSERT_EQ(extracted.trace_packet_data.sequence_state,
             state.current_generation());
   ASSERT_EQ(extracted.thread_instruction_count, 123);
-  ASSERT_EQ(extracted.thread_timestamp, base::nullopt);
+  ASSERT_EQ(extracted.thread_timestamp, std::nullopt);
   ASSERT_DOUBLE_EQ(extracted.counter_value, 0.0);
   ASSERT_EQ(extracted.extra_counter_values, counter_array);
 }
diff --git a/src/trace_processor/sqlite/db_sqlite_table.cc b/src/trace_processor/sqlite/db_sqlite_table.cc
index 552a24b..a97ec8f 100644
--- a/src/trace_processor/sqlite/db_sqlite_table.cc
+++ b/src/trace_processor/sqlite/db_sqlite_table.cc
@@ -28,7 +28,7 @@
 
 namespace {
 
-base::Optional<FilterOp> SqliteOpToFilterOp(int sqlite_op) {
+std::optional<FilterOp> SqliteOpToFilterOp(int sqlite_op) {
   switch (sqlite_op) {
     case SQLITE_INDEX_CONSTRAINT_EQ:
     case SQLITE_INDEX_CONSTRAINT_IS:
@@ -54,7 +54,7 @@
     // TODO(lalitm): start supporting these constraints.
     case SQLITE_INDEX_CONSTRAINT_LIMIT:
     case SQLITE_INDEX_CONSTRAINT_OFFSET:
-      return base::nullopt;
+      return std::nullopt;
     default:
       PERFETTO_FATAL("Currently unsupported constraint");
   }
@@ -221,10 +221,10 @@
 
   const auto& cs = qc.constraints();
   for (uint32_t i = 0; i < cs.size(); ++i) {
-    // SqliteOpToFilterOp will return nullopt for any constraint which we don't
-    // support filtering ourselves. Only omit filtering by SQLite when we can
-    // handle filtering.
-    base::Optional<FilterOp> opt_op = SqliteOpToFilterOp(cs[i].op);
+    // SqliteOpToFilterOp will return std::nullopt for any constraint which we
+    // don't support filtering ourselves. Only omit filtering by SQLite when we
+    // can handle filtering.
+    std::optional<FilterOp> opt_op = SqliteOpToFilterOp(cs[i].op);
     info->sqlite_omit_constraint[i] = opt_op.has_value();
   }
 
@@ -458,7 +458,7 @@
                                   FilterHistory history) {
   // Clear out the iterator before filtering to ensure the destructor is run
   // before the table's destructor.
-  iterator_ = base::nullopt;
+  iterator_ = std::nullopt;
 
   // We reuse this vector to reduce memory allocations on nested subqueries.
   constraints_.resize(qc.constraints().size());
@@ -467,9 +467,9 @@
     const auto& cs = qc.constraints()[i];
     uint32_t col = static_cast<uint32_t>(cs.column);
 
-    // If we get a nullopt FilterOp, that means we should allow SQLite
+    // If we get a std::nullopt FilterOp, that means we should allow SQLite
     // to handle the constraint.
-    base::Optional<FilterOp> opt_op = SqliteOpToFilterOp(cs.op);
+    std::optional<FilterOp> opt_op = SqliteOpToFilterOp(cs.op);
     if (!opt_op)
       continue;
 
@@ -617,9 +617,8 @@
     // TODO(lalitm): investigate some other criteria where it is beneficial
     // to have a fast path and expand to them.
     mode_ = Mode::kSingleRow;
-    single_row_ = filter_map.size() == 1
-                      ? base::make_optional(filter_map.Get(0))
-                      : base::nullopt;
+    single_row_ = filter_map.size() == 1 ? std::make_optional(filter_map.Get(0))
+                                         : std::nullopt;
     eof_ = !single_row_.has_value();
   } else {
     mode_ = Mode::kTable;
diff --git a/src/trace_processor/sqlite/db_sqlite_table.h b/src/trace_processor/sqlite/db_sqlite_table.h
index 4b50e6d..6a2282d 100644
--- a/src/trace_processor/sqlite/db_sqlite_table.h
+++ b/src/trace_processor/sqlite/db_sqlite_table.h
@@ -82,11 +82,11 @@
     std::unique_ptr<Table> dynamic_table_;
 
     // Only valid for Mode::kSingleRow.
-    base::Optional<uint32_t> single_row_;
+    std::optional<uint32_t> single_row_;
 
     // Only valid for Mode::kTable.
-    base::Optional<Table> db_table_;
-    base::Optional<Table::Iterator> iterator_;
+    std::optional<Table> db_table_;
+    std::optional<Table::Iterator> iterator_;
 
     bool eof_ = true;
 
diff --git a/src/trace_processor/sqlite/query_cache.h b/src/trace_processor/sqlite/query_cache.h
index 16a2b6e..f3b8223 100644
--- a/src/trace_processor/sqlite/query_cache.h
+++ b/src/trace_processor/sqlite/query_cache.h
@@ -16,8 +16,7 @@
 
 #ifndef SRC_TRACE_PROCESSOR_SQLITE_QUERY_CACHE_H_
 #define SRC_TRACE_PROCESSOR_SQLITE_QUERY_CACHE_H_
-
-#include "perfetto/ext/base/optional.h"
+#include <optional>
 
 #include "src/trace_processor/db/table.h"
 #include "src/trace_processor/sqlite/query_constraints.h"
diff --git a/src/trace_processor/sqlite/sqlite_raw_table.cc b/src/trace_processor/sqlite/sqlite_raw_table.cc
index f6f0945..feaca00 100644
--- a/src/trace_processor/sqlite/sqlite_raw_table.cc
+++ b/src/trace_processor/sqlite/sqlite_raw_table.cc
@@ -60,7 +60,7 @@
   ArgsSerializer(TraceProcessorContext*,
                  ArgSetId arg_set_id,
                  NullTermStringView event_name,
-                 std::vector<base::Optional<uint32_t>>* field_id_to_arg_index,
+                 std::vector<std::optional<uint32_t>>* field_id_to_arg_index,
                  base::StringWriter*);
 
   void SerializeArgs();
@@ -71,7 +71,7 @@
 
   // Arg writing functions.
   void WriteArgForField(uint32_t field_id, ValueWriter writer) {
-    base::Optional<uint32_t> row = FieldIdToRow(field_id);
+    std::optional<uint32_t> row = FieldIdToRow(field_id);
     if (!row)
       return;
     WriteArgAtRow(*row, writer);
@@ -79,7 +79,7 @@
   void WriteArgForField(uint32_t field_id,
                         base::StringView key,
                         ValueWriter writer) {
-    base::Optional<uint32_t> row = FieldIdToRow(field_id);
+    std::optional<uint32_t> row = FieldIdToRow(field_id);
     if (!row)
       return;
     WriteArg(key, storage_->GetArgValue(*row), writer);
@@ -93,7 +93,7 @@
 
   // Value writing functions.
   void WriteValueForField(uint32_t field_id, ValueWriter writer) {
-    base::Optional<uint32_t> row = FieldIdToRow(field_id);
+    std::optional<uint32_t> row = FieldIdToRow(field_id);
     if (!row)
       return;
     writer(storage_->GetArgValue(*row));
@@ -116,21 +116,21 @@
   }
 
   // Converts a field id to a row in the args table.
-  base::Optional<uint32_t> FieldIdToRow(uint32_t field_id) {
+  std::optional<uint32_t> FieldIdToRow(uint32_t field_id) {
     PERFETTO_DCHECK(field_id > 0);
     PERFETTO_DCHECK(field_id < field_id_to_arg_index_->size());
-    base::Optional<uint32_t> index_in_arg_set =
+    std::optional<uint32_t> index_in_arg_set =
         (*field_id_to_arg_index_)[field_id];
     return index_in_arg_set.has_value()
-               ? base::make_optional(start_row_ + *index_in_arg_set)
-               : base::nullopt;
+               ? std::make_optional(start_row_ + *index_in_arg_set)
+               : std::nullopt;
   }
 
   const TraceStorage* storage_ = nullptr;
   TraceProcessorContext* context_ = nullptr;
   ArgSetId arg_set_id_ = kInvalidArgSetId;
   NullTermStringView event_name_;
-  std::vector<base::Optional<uint32_t>>* field_id_to_arg_index_;
+  std::vector<std::optional<uint32_t>>* field_id_to_arg_index_;
 
   RowMap row_map_;
   uint32_t start_row_ = 0;
@@ -142,7 +142,7 @@
     TraceProcessorContext* context,
     ArgSetId arg_set_id,
     NullTermStringView event_name,
-    std::vector<base::Optional<uint32_t>>* field_id_to_arg_index,
+    std::vector<std::optional<uint32_t>>* field_id_to_arg_index,
     base::StringWriter* writer)
     : context_(context),
       arg_set_id_(arg_set_id),
@@ -205,7 +205,7 @@
     WriteArgForField(SS::kPrevStateFieldNumber, [this](const Variadic& value) {
       PERFETTO_DCHECK(value.type == Variadic::Type::kInt);
       auto state = static_cast<uint16_t>(value.int_value);
-      base::Optional<VersionNumber> kernel_version =
+      std::optional<VersionNumber> kernel_version =
           SystemInfoTracker::GetOrCreate(context_)->GetKernelVersion();
       writer_->AppendString(
           ftrace_utils::TaskState::FromRawPrevState(state, kernel_version)
diff --git a/src/trace_processor/sqlite/sqlite_raw_table.h b/src/trace_processor/sqlite/sqlite_raw_table.h
index a3ec5c2..dcb5c46 100644
--- a/src/trace_processor/sqlite/sqlite_raw_table.h
+++ b/src/trace_processor/sqlite/sqlite_raw_table.h
@@ -38,7 +38,7 @@
 
  private:
   using StringIdMap =
-      base::FlatHashMap<StringId, std::vector<base::Optional<uint32_t>>>;
+      base::FlatHashMap<StringId, std::vector<std::optional<uint32_t>>>;
 
   void SerializePrefix(uint32_t raw_row, base::StringWriter* writer);
 
diff --git a/src/trace_processor/sqlite/sqlite_table.h b/src/trace_processor/sqlite/sqlite_table.h
index 2d9ed50..de94669 100644
--- a/src/trace_processor/sqlite/sqlite_table.h
+++ b/src/trace_processor/sqlite/sqlite_table.h
@@ -22,11 +22,11 @@
 #include <functional>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "perfetto/base/status.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/utils.h"
 #include "perfetto/trace_processor/basic_types.h"
 #include "src/trace_processor/sqlite/query_constraints.h"
diff --git a/src/trace_processor/sqlite/sqlite_utils.cc b/src/trace_processor/sqlite/sqlite_utils.cc
index 475b1d4..c4077a5 100644
--- a/src/trace_processor/sqlite/sqlite_utils.cc
+++ b/src/trace_processor/sqlite/sqlite_utils.cc
@@ -196,9 +196,9 @@
 
 template <typename T>
 base::Status ExtractFromSqlValueInt(const SqlValue& value,
-                                    base::Optional<T>& out) {
+                                    std::optional<T>& out) {
   if (value.is_null()) {
-    out = base::nullopt;
+    out = std::nullopt;
     return base::OkStatus();
   }
   if (value.type != SqlValue::kLong) {
@@ -221,21 +221,21 @@
 }
 
 base::Status ExtractFromSqlValue(const SqlValue& value,
-                                 base::Optional<int64_t>& out) {
+                                 std::optional<int64_t>& out) {
   return ExtractFromSqlValueInt(value, out);
 }
 base::Status ExtractFromSqlValue(const SqlValue& value,
-                                 base::Optional<int32_t>& out) {
+                                 std::optional<int32_t>& out) {
   return ExtractFromSqlValueInt(value, out);
 }
 base::Status ExtractFromSqlValue(const SqlValue& value,
-                                 base::Optional<uint32_t>& out) {
+                                 std::optional<uint32_t>& out) {
   return ExtractFromSqlValueInt(value, out);
 }
 base::Status ExtractFromSqlValue(const SqlValue& value,
-                                 base::Optional<double>& out) {
+                                 std::optional<double>& out) {
   if (value.is_null()) {
-    out = base::nullopt;
+    out = std::nullopt;
     return base::OkStatus();
   }
   if (value.type != SqlValue::kDouble) {
@@ -248,9 +248,9 @@
   return base::OkStatus();
 }
 base::Status ExtractFromSqlValue(const SqlValue& value,
-                                 base::Optional<const char*>& out) {
+                                 std::optional<const char*>& out) {
   if (value.is_null()) {
-    out = base::nullopt;
+    out = std::nullopt;
     return base::OkStatus();
   }
   if (value.type != SqlValue::kString) {
diff --git a/src/trace_processor/sqlite/sqlite_utils.h b/src/trace_processor/sqlite/sqlite_utils.h
index c3b08bb..ef44c45 100644
--- a/src/trace_processor/sqlite/sqlite_utils.h
+++ b/src/trace_processor/sqlite/sqlite_utils.h
@@ -22,11 +22,11 @@
 #include <bitset>
 #include <cstddef>
 #include <cstring>
+#include <optional>
 #include <utility>
 
 #include "perfetto/base/logging.h"
 #include "perfetto/base/status.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/status_or.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/string_view.h"
@@ -98,7 +98,7 @@
   return sql_value;
 }
 
-inline base::Optional<std::string> SqlValueToString(SqlValue value) {
+inline std::optional<std::string> SqlValueToString(SqlValue value) {
   switch (value.type) {
     case SqlValue::Type::kString:
       return value.AsString();
@@ -108,7 +108,7 @@
       return std::to_string(value.AsLong());
     case SqlValue::Type::kBytes:
     case SqlValue::Type::kNull:
-      return base::nullopt;
+      return std::nullopt;
   }
   PERFETTO_FATAL("For GCC");
 }
@@ -169,7 +169,7 @@
 }
 
 inline base::Status FormatErrorMessage(sqlite3_stmt* stmt,
-                                       base::Optional<base::StringView> sql,
+                                       std::optional<base::StringView> sql,
                                        sqlite3* db,
                                        int error_code) {
   if (stmt) {
@@ -209,7 +209,7 @@
   if (err != SQLITE_DONE) {
     auto db = sqlite3_db_handle(stmt);
     return base::ErrStatus(
-        "%s", FormatErrorMessage(stmt, base::nullopt, db, err).c_message());
+        "%s", FormatErrorMessage(stmt, std::nullopt, db, err).c_message());
   }
   return base::OkStatus();
 }
@@ -228,21 +228,20 @@
 
 // Exracts the given type from the SqlValue if |value| can fit
 // in the provided optional. Note that SqlValue::kNull will always
-// succeed and cause base::nullopt to be set.
+// succeed and cause std::nullopt to be set.
 //
 // Returns base::ErrStatus if the type does not match or does not
 // fit in the width of the provided optional type (i.e. int64 value
 // not fitting in int32 optional).
 base::Status ExtractFromSqlValue(const SqlValue& value,
-                                 base::Optional<int64_t>&);
+                                 std::optional<int64_t>&);
 base::Status ExtractFromSqlValue(const SqlValue& value,
-                                 base::Optional<int32_t>&);
+                                 std::optional<int32_t>&);
 base::Status ExtractFromSqlValue(const SqlValue& value,
-                                 base::Optional<uint32_t>&);
+                                 std::optional<uint32_t>&);
+base::Status ExtractFromSqlValue(const SqlValue& value, std::optional<double>&);
 base::Status ExtractFromSqlValue(const SqlValue& value,
-                                 base::Optional<double>&);
-base::Status ExtractFromSqlValue(const SqlValue& value,
-                                 base::Optional<const char*>&);
+                                 std::optional<const char*>&);
 
 // Returns the column names for the table named by |raw_table_name|.
 base::Status GetColumnsForTable(sqlite3* db,
diff --git a/src/trace_processor/sqlite/sqlite_utils_unittest.cc b/src/trace_processor/sqlite/sqlite_utils_unittest.cc
index b52df66..be28af1 100644
--- a/src/trace_processor/sqlite/sqlite_utils_unittest.cc
+++ b/src/trace_processor/sqlite/sqlite_utils_unittest.cc
@@ -75,7 +75,7 @@
 }
 
 TEST(SqliteUtilsTest, ExtractFromSqlValueInt32) {
-  base::Optional<int32_t> int32;
+  std::optional<int32_t> int32;
 
   static constexpr int64_t kMin = std::numeric_limits<int32_t>::min();
   static constexpr int64_t kMax = std::numeric_limits<int32_t>::max();
@@ -98,7 +98,7 @@
 }
 
 TEST(SqliteUtilsTest, ExtractFromSqlValueUint32) {
-  base::Optional<uint32_t> uint32;
+  std::optional<uint32_t> uint32;
 
   static constexpr int64_t kMin = std::numeric_limits<uint32_t>::min();
   static constexpr int64_t kMax = std::numeric_limits<uint32_t>::max();
@@ -121,7 +121,7 @@
 }
 
 TEST(SqliteUtilsTest, ExtractFromSqlValueInt64) {
-  base::Optional<int64_t> int64;
+  std::optional<int64_t> int64;
 
   static constexpr int64_t kMin = std::numeric_limits<int64_t>::min();
   static constexpr int64_t kMax = std::numeric_limits<int64_t>::max();
@@ -143,7 +143,7 @@
 }
 
 TEST(SqliteUtilsTest, ExtractFromSqlValueDouble) {
-  base::Optional<double> doub;
+  std::optional<double> doub;
 
   static constexpr double kMin = std::numeric_limits<double>::min();
   static constexpr double kMax = std::numeric_limits<double>::max();
@@ -165,7 +165,7 @@
 }
 
 TEST(SqliteUtilsTest, ExtractFromSqlValueString) {
-  base::Optional<const char*> string;
+  std::optional<const char*> string;
 
   ASSERT_TRUE(ExtractFromSqlValue(SqlValue::String("foo"), string).ok());
   ASSERT_STREQ(*string, "foo");
diff --git a/src/trace_processor/stdlib/android/process_metadata.sql b/src/trace_processor/stdlib/android/process_metadata.sql
index a593f69..20fb82e 100644
--- a/src/trace_processor/stdlib/android/process_metadata.sql
+++ b/src/trace_processor/stdlib/android/process_metadata.sql
@@ -57,4 +57,4 @@
       internal_uid_package_count.cnt = 1
       -- or process name starts with the package name
       OR process.name GLOB plist.package_name || '*')
-  );
\ No newline at end of file
+  );
diff --git a/src/trace_processor/stdlib/common/slices.sql b/src/trace_processor/stdlib/common/slices.sql
index ab59ea6..9c645aa 100644
--- a/src/trace_processor/stdlib/common/slices.sql
+++ b/src/trace_processor/stdlib/common/slices.sql
@@ -13,10 +13,6 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 
---
--- Thread slices view functions
---
-
 -- All thread slices with data about thread, thread track and process.
 -- Where possible, use available view functions which filter this view.
 --
@@ -32,7 +28,7 @@
 -- @column thread_name        Name of thread with slice.
 -- @column upid               Upid of process with slice.
 -- @column process_name       Name of process with slice.
-CREATE VIEW all_thread_slices AS
+CREATE VIEW thread_slice AS
 SELECT
   slice.id AS slice_id,
   slice.name AS slice_name,
@@ -51,232 +47,6 @@
 JOIN thread using (utid)
 LEFT JOIN process using (upid);
 
--- Detailed thread slices data with process, thread and track for thread with provided utid.
---
--- @arg utid INT              Utid of thread.
--- @column slice_id           Id of slice.
--- @column slice_name         Name of slice.
--- @column ts                 Timestamp of slice start.
--- @column dur                Duration of slice.
--- @column slice_depth        Depth of slice.
--- @column arg_set_id         Slice arg set id.
--- @column thread_track_id    Id of thread track.
--- @column thread_track_name  Name of thread track.
--- @column utid               Utid of thread with slice.
--- @column thread_name        Name of thread with slice.
--- @column upid               Upid of process with slice.
--- @column process_name       Name of process with slice.
-SELECT CREATE_VIEW_FUNCTION(
-'THREAD_SLICES_FOR_UTID(utid INT)',
-  '
-    slice_id INT,
-    slice_name STRING,
-    ts LONG,
-    dur LONG,
-    slice_depth INT,
-    arg_set_id INT,
-    thread_track_id INT,
-    thread_track_name STRING,
-    utid INT,
-    thread_name STRING,
-    upid INT,
-    process_name STRING
-  ',
-'
-  SELECT * FROM all_thread_slices
-  WHERE utid = $utid;
-');
-
--- Detailed thread slices data with process, thread and track for process with provided upid.
---
--- @arg upid INT              Upid of process.
--- @column slice_id           Id of slice.
--- @column slice_name         Name of slice.
--- @column ts                 Timestamp of slice start.
--- @column dur                Duration of slice.
--- @column slice_depth        Depth of slice.
--- @column arg_set_id         Slice arg set id.
--- @column thread_track_id    Id of thread track.
--- @column thread_track_name  Name of thread track.
--- @column utid               Utid of thread with slice.
--- @column thread_name        Name of thread with slice.
--- @column upid               Upid of process with slice.
--- @column process_name       Name of process with slice.
-SELECT CREATE_VIEW_FUNCTION(
-  'THREAD_SLICES_FOR_UPID(upid INT)',
-  '
-    slice_id INT,
-    slice_name STRING,
-    ts LONG,
-    dur LONG,
-    slice_depth INT,
-    arg_set_id INT,
-    thread_track_id INT,
-    thread_track_name STRING,
-    utid INT,
-    thread_name STRING,
-    upid INT,
-    process_name STRING
-  ',
-  '
-    SELECT * FROM all_thread_slices
-    WHERE upid = $upid;
-  '
-);
-
--- Detailed thread slices data with process, thread and track for track id.
---
--- @arg thread_track_id INT   Id of thread_track.
--- @column slice_id           Id of slice.
--- @column slice_name         Name of slice.
--- @column ts                 Timestamp of slice start.
--- @column dur                Duration of slice.
--- @column slice_depth        Depth of slice.
--- @column arg_set_id         Slice arg set id.
--- @column thread_track_id    Id of thread track.
--- @column thread_track_name  Name of thread track.
--- @column utid               Utid of thread with slice.
--- @column thread_name        Name of thread with slice.
--- @column upid               Upid of process with slice.
--- @column process_name       Name of process with slice.
-SELECT CREATE_VIEW_FUNCTION(
-  'THREAD_SLICES_FOR_THREAD_TRACK_ID(thread_track_id INT)',
-  '
-    slice_id INT,
-    slice_name STRING,
-    ts LONG,
-    dur LONG,
-    slice_depth INT,
-    arg_set_id INT,
-    thread_track_id INT,
-    thread_track_name STRING,
-    utid INT,
-    thread_name STRING,
-    upid INT,
-    process_name STRING
-  ',
-  '
-    SELECT * FROM all_thread_slices
-    WHERE thread_track_id = $thread_track_id;
-  '
-);
-
-
--- Detailed thread slices data with process, thread and track for specified slice name.
--- Searches for slice name with GLOB.
---
--- @arg glob_name STRING      String name to glob.
--- @column slice_id           Id of slice.
--- @column slice_name         Name of slice.
--- @column ts                 Timestamp of slice start.
--- @column dur                Duration of slice.
--- @column slice_depth        Depth of slice.
--- @column arg_set_id         Slice arg set id.
--- @column thread_track_id    Id of thread track.
--- @column thread_track_name  Name of thread track.
--- @column utid               Utid of thread with slice.
--- @column thread_name        Name of thread with slice.
--- @column upid               Upid of process with slice.
--- @column process_name       Name of process with slice.
-SELECT CREATE_VIEW_FUNCTION(
-  'THREAD_SLICES_FOR_SLICE_NAME(glob_name STRING)',
-  '
-    slice_id INT,
-    slice_name STRING,
-    ts LONG,
-    dur LONG,
-    slice_depth INT,
-    arg_set_id INT,
-    thread_track_id INT,
-    thread_track_name STRING,
-    utid INT,
-    thread_name STRING,
-    upid INT,
-    process_name STRING
-  ',
-  '
-    SELECT * FROM all_thread_slices
-    WHERE slice_name GLOB $glob_name;
-  ');
-
--- Detailed thread slices data with process, thread and track for specified thread name.
--- Searches for thread name with GLOB.
---
--- @arg glob_name STRING      Thread name to glob.
--- @column slice_id           Id of slice.
--- @column slice_name         Name of slice.
--- @column ts                 Timestamp of slice start.
--- @column dur                Duration of slice.
--- @column slice_depth        Depth of slice.
--- @column arg_set_id         Slice arg set id.
--- @column thread_track_id    Id of thread track.
--- @column thread_track_name  Name of thread track.
--- @column utid               Utid of thread with slice.
--- @column thread_name        Name of thread with slice.
--- @column upid               Upid of process with slice.
--- @column process_name       Name of process with slice.
-SELECT CREATE_VIEW_FUNCTION(
-  'THREAD_SLICES_FOR_THREAD_NAME(glob_name STRING)',
-  '
-    slice_id INT,
-    slice_name STRING,
-    ts LONG,
-    dur LONG,
-    slice_depth INT,
-    arg_set_id INT,
-    thread_track_id INT,
-    thread_track_name STRING,
-    utid INT,
-    thread_name STRING,
-    upid INT,
-    process_name STRING
-  ',
-  '
-    SELECT * FROM all_thread_slices
-    WHERE thread_name GLOB $glob_name;
-  ');
-
--- Detailed thread slices data with process, thread and track for specified process name.
--- Searches for process name with GLOB.
---
--- @arg glob_name STRING      Process name to glob.
--- @column slice_id           Id of slice.
--- @column slice_name         Name of slice.
--- @column ts                 Timestamp of slice start.
--- @column dur                Duration of slice.
--- @column slice_depth        Depth of slice.
--- @column arg_set_id         Slice arg set id.
--- @column thread_track_id    Id of thread track.
--- @column thread_track_name  Name of thread track.
--- @column utid               Utid of thread with slice.
--- @column thread_name        Name of thread with slice.
--- @column upid               Upid of process with slice.
--- @column process_name       Name of process with slice.
-SELECT CREATE_VIEW_FUNCTION(
-  'THREAD_SLICES_FOR_PROCESS_NAME(glob_name STRING)',
-  '
-    slice_id INT,
-    slice_name STRING,
-    ts LONG,
-    dur LONG,
-    slice_depth INT,
-    arg_set_id INT,
-    thread_track_id INT,
-    thread_track_name STRING,
-    utid INT,
-    thread_name STRING,
-    upid INT,
-    process_name STRING
-  ',
-  '
-    SELECT * FROM all_thread_slices
-    WHERE process_name GLOB $glob_name;
-  ');
-
---
--- Process slices view functions
---
-
 -- All process slices with data about process track and process.
 -- Where possible, use available view functions which filter this view.
 --
@@ -290,7 +60,7 @@
 -- @column process_track_name Name of process track.
 -- @column upid               Upid of process with slice.
 -- @column process_name       Name of process with slice.
-CREATE VIEW all_process_slices AS
+CREATE VIEW process_slice AS
 SELECT
   slice.id AS slice_id,
   slice.name AS slice_name,
@@ -306,146 +76,6 @@
 JOIN process_track ON slice.track_id = process_track.id
 JOIN process using (upid);
 
--- Detailed process slices data for process and track with provided upid.
---
--- @arg upid INT              Upid of process.
--- @column slice_id           Id of slice.
--- @column slice_name         Name of slice.
--- @column ts                 Timestamp of slice start.
--- @column dur                Duration of slice.
--- @column slice_depth        Depth of slice.
--- @column arg_set_id         Slice arg set id.
--- @column process_track_id   Id of process track.
--- @column process_track_name Name of process track.
--- @column upid               Upid of process with slice.
--- @column process_name       Name of process with slice.
-SELECT CREATE_VIEW_FUNCTION(
-  'PROCESS_SLICES_FOR_UPID(upid INT)',
-  '
-    slice_id INT,
-    slice_name STRING,
-    ts LONG,
-    dur LONG,
-    slice_depth INT,
-    arg_set_id INT,
-    process_track_id INT,
-    process_track_name INT,
-    upid INT,
-    process_name STRING
-  ',
-  '
-    SELECT * FROM all_process_slices
-    WHERE upid = $upid;
-  '
-);
-
--- Detailed process slices data for process and track with provided process_track_id.
---
--- @arg process_track_id INT  Id of process track.
--- @column slice_id           Id of slice.
--- @column slice_name         Name of slice.
--- @column ts                 Timestamp of slice start.
--- @column dur                Duration of slice.
--- @column slice_depth        Depth of slice.
--- @column arg_set_id         Slice arg set id.
--- @column process_track_id   Id of process track.
--- @column process_track_name Name of process track.
--- @column upid               Upid of process with slice.
--- @column process_name       Name of process with slice.
-SELECT CREATE_VIEW_FUNCTION(
-  'PROCESS_SLICES_FOR_PROCESS_TRACK_ID(process_track_id INT)',
-  '
-    slice_id INT,
-    slice_name STRING,
-    ts LONG,
-    dur LONG,
-    slice_depth INT,
-    arg_set_id INT,
-    process_track_id INT,
-    process_track_name INT,
-    upid INT,
-    process_name STRING
-  ',
-  '
-    SELECT * FROM all_process_slices
-    WHERE process_track_id = $process_track_id;
-  '
-);
-
-
--- Detailed process slices data for specified slice name.
--- Searches for slice name with GLOB.
---
--- @arg glob_name STRING      String name to glob.
--- @column slice_id           Id of slice.
--- @column slice_name         Name of slice.
--- @column ts                 Timestamp of slice start.
--- @column dur                Duration of slice.
--- @column slice_depth        Depth of slice.
--- @column arg_set_id         Slice arg set id.
--- @column process_track_id   Id of process track.
--- @column process_track_name Name of process track.
--- @column upid               Upid of process with slice.
--- @column process_name       Name of process with slice.
-SELECT CREATE_VIEW_FUNCTION(
-  'PROCESS_SLICES_FOR_SLICE_NAME(glob_name STRING)',
-  '
-    slice_id INT,
-    slice_name STRING,
-    ts LONG,
-    dur LONG,
-    slice_depth INT,
-    arg_set_id INT,
-    process_track_id INT,
-    process_track_name INT,
-    upid INT,
-    process_name STRING
-  ',
-  '
-    SELECT * FROM all_process_slices
-    WHERE slice_name GLOB $glob_name;
-  '
-);
-
--- Detailed process slices data for specified process name.
--- Searches for process name with GLOB.
---
--- @arg glob_name STRING      Process name to glob.
--- @column slice_id           Id of slice.
--- @column slice_name         Name of slice.
--- @column ts                 Timestamp of slice start.
--- @column dur                Duration of slice.
--- @column slice_depth        Depth of slice.
--- @column arg_set_id         Slice arg set id.
--- @column process_track_id   Id of process track.
--- @column process_track_name Name of process track.
--- @column upid               Upid of process with slice.
--- @column process_name       Name of process with slice.
-SELECT CREATE_VIEW_FUNCTION(
-  'PROCESS_SLICES_FOR_PROCESS_NAME(glob_name STRING)',
-  '
-    slice_id INT,
-    slice_name STRING,
-    ts LONG,
-    dur LONG,
-    slice_depth INT,
-    arg_set_id INT,
-    process_track_id INT,
-    process_track_name INT,
-    upid INT,
-    process_name STRING
-  ',
-  '
-    SELECT * FROM all_process_slices
-    WHERE process_name GLOB $glob_name;
-  '
-);
-
-
---
--- Other functions
---
-
 -- Checks if slice has an ancestor with provided name.
 --
 -- @arg id INT              Id of the slice to check parents of.
diff --git a/src/trace_processor/storage/metadata.h b/src/trace_processor/storage/metadata.h
index de2e651..88eac06 100644
--- a/src/trace_processor/storage/metadata.h
+++ b/src/trace_processor/storage/metadata.h
@@ -50,6 +50,7 @@
   F(system_version,                    KeyType::kSingle,  Variadic::kString), \
   F(trace_config_pbtxt,                KeyType::kSingle,  Variadic::kString), \
   F(trace_size_bytes,                  KeyType::kSingle,  Variadic::kInt),    \
+  F(trace_time_clock_id,               KeyType::kSingle,  Variadic::kInt),    \
   F(trace_type,                        KeyType::kSingle,  Variadic::kString), \
   F(trace_uuid,                        KeyType::kSingle,  Variadic::kString), \
   F(tracing_disabled_ns,               KeyType::kSingle,  Variadic::kInt),    \
diff --git a/src/trace_processor/storage/trace_storage.h b/src/trace_processor/storage/trace_storage.h
index 2fd2b24..4fe2071 100644
--- a/src/trace_processor/storage/trace_storage.h
+++ b/src/trace_processor/storage/trace_storage.h
@@ -20,6 +20,7 @@
 #include <array>
 #include <deque>
 #include <map>
+#include <optional>
 #include <string>
 #include <unordered_map>
 #include <utility>
@@ -28,7 +29,6 @@
 #include "perfetto/base/logging.h"
 #include "perfetto/base/time.h"
 #include "perfetto/ext/base/hash.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/ext/base/utils.h"
 #include "perfetto/trace_processor/basic_types.h"
@@ -36,14 +36,14 @@
 #include "src/trace_processor/containers/string_pool.h"
 #include "src/trace_processor/storage/metadata.h"
 #include "src/trace_processor/storage/stats.h"
-#include "src/trace_processor/tables/android_tables.h"
-#include "src/trace_processor/tables/counter_tables.h"
-#include "src/trace_processor/tables/flow_tables.h"
-#include "src/trace_processor/tables/memory_tables.h"
-#include "src/trace_processor/tables/metadata_tables.h"
-#include "src/trace_processor/tables/profiler_tables.h"
-#include "src/trace_processor/tables/slice_tables.h"
-#include "src/trace_processor/tables/trace_proto_tables.h"
+#include "src/trace_processor/tables/android_tables_py.h"
+#include "src/trace_processor/tables/counter_tables_py.h"
+#include "src/trace_processor/tables/flow_tables_py.h"
+#include "src/trace_processor/tables/memory_tables_py.h"
+#include "src/trace_processor/tables/metadata_tables_py.h"
+#include "src/trace_processor/tables/profiler_tables_py.h"
+#include "src/trace_processor/tables/slice_tables_py.h"
+#include "src/trace_processor/tables/trace_proto_tables_py.h"
 #include "src/trace_processor/tables/track_tables_py.h"
 #include "src/trace_processor/types/variadic.h"
 #include "src/trace_processor/views/slice_views.h"
@@ -154,13 +154,13 @@
       return thread_instruction_deltas_;
     }
 
-    base::Optional<uint32_t> FindRowForSliceId(SliceId slice_id) const {
+    std::optional<uint32_t> FindRowForSliceId(SliceId slice_id) const {
       auto it =
           std::lower_bound(slice_ids().begin(), slice_ids().end(), slice_id);
       if (it != slice_ids().end() && *it == slice_id) {
         return static_cast<uint32_t>(std::distance(slice_ids().begin(), it));
       }
-      return base::nullopt;
+      return std::nullopt;
     }
 
     void UpdateThreadDeltasForSliceId(SliceId slice_id,
@@ -251,14 +251,14 @@
   }
 
   // Example usage: opt_cpu_failure = GetIndexedStats(stats::cpu_failure, 1);
-  base::Optional<int64_t> GetIndexedStats(size_t key, int index) {
+  std::optional<int64_t> GetIndexedStats(size_t key, int index) {
     PERFETTO_DCHECK(key < stats::kNumKeys);
     PERFETTO_DCHECK(stats::kTypes[key] == stats::kIndexed);
     auto kv = stats_[key].indexed_values.find(index);
     if (kv != stats_[key].indexed_values.end()) {
       return kv->second;
     }
-    return base::nullopt;
+    return std::nullopt;
   }
 
   class ScopedStatsTracer {
@@ -739,12 +739,12 @@
 
   util::Status ExtractArg(uint32_t arg_set_id,
                           const char* key,
-                          base::Optional<Variadic>* result) {
+                          std::optional<Variadic>* result) {
     const auto& args = arg_table();
     RowMap filtered = args.FilterToRowMap(
         {args.arg_set_id().eq(arg_set_id), args.key().eq(key)});
     if (filtered.empty()) {
-      *result = base::nullopt;
+      *result = std::nullopt;
       return util::OkStatus();
     }
     if (filtered.size() > 1) {
@@ -799,11 +799,11 @@
     return variadic_type_ids_[type];
   }
 
-  base::Optional<Variadic::Type> GetVariadicTypeForId(StringId id) const {
+  std::optional<Variadic::Type> GetVariadicTypeForId(StringId id) const {
     auto it =
         std::find(variadic_type_ids_.begin(), variadic_type_ids_.end(), id);
     if (it == variadic_type_ids_.end())
-      return base::nullopt;
+      return std::nullopt;
 
     int64_t idx = std::distance(variadic_type_ids_.begin(), it);
     return static_cast<Variadic::Type>(idx);
@@ -827,14 +827,14 @@
   // Extra data extracted from the trace. Includes:
   // * metadata from chrome and benchmarking infrastructure
   // * descriptions of android packages
-  tables::MetadataTable metadata_table_{&string_pool_, nullptr};
+  tables::MetadataTable metadata_table_{&string_pool_};
 
   // Contains data from all the clock snapshots in the trace.
-  tables::ClockSnapshotTable clock_snapshot_table_{&string_pool_, nullptr};
+  tables::ClockSnapshotTable clock_snapshot_table_{&string_pool_};
 
   // Metadata for tracks.
   tables::TrackTable track_table_{&string_pool_};
-  tables::ThreadStateTable thread_state_table_{&string_pool_, nullptr};
+  tables::ThreadStateTable thread_state_table_{&string_pool_};
   tables::CpuTrackTable cpu_track_table_{&string_pool_, &track_table_};
   tables::GpuTrackTable gpu_track_table_{&string_pool_, &track_table_};
   tables::ProcessTrackTable process_track_table_{&string_pool_, &track_table_};
@@ -860,26 +860,26 @@
                                                         &counter_track_table_};
   tables::EnergyPerUidCounterTrackTable energy_per_uid_counter_track_table_{
       &string_pool_, &uid_counter_track_table_};
-  tables::GpuCounterGroupTable gpu_counter_group_table_{&string_pool_, nullptr};
+  tables::GpuCounterGroupTable gpu_counter_group_table_{&string_pool_};
   tables::PerfCounterTrackTable perf_counter_track_table_{
       &string_pool_, &counter_track_table_};
 
   // Args for all other tables.
-  tables::ArgTable arg_table_{&string_pool_, nullptr};
+  tables::ArgTable arg_table_{&string_pool_};
 
   // Information about all the threads and processes in the trace.
   tables::ThreadTable thread_table_{&string_pool_};
   tables::ProcessTable process_table_{&string_pool_};
-  tables::FiledescriptorTable filedescriptor_table_{&string_pool_, nullptr};
+  tables::FiledescriptorTable filedescriptor_table_{&string_pool_};
 
   // Slices coming from userspace events (e.g. Chromium TRACE_EVENT macros).
-  tables::SliceTable slice_table_{&string_pool_, nullptr};
+  tables::SliceTable slice_table_{&string_pool_};
 
   // Flow events from userspace events (e.g. Chromium TRACE_EVENT macros).
-  tables::FlowTable flow_table_{&string_pool_, nullptr};
+  tables::FlowTable flow_table_{&string_pool_};
 
   // Slices from CPU scheduling data.
-  tables::SchedSliceTable sched_slice_table_{&string_pool_, nullptr};
+  tables::SchedSliceTable sched_slice_table_{&string_pool_};
 
   // Additional attributes for virtual track slices (sub-type of
   // NestableSlices).
@@ -891,7 +891,7 @@
 
   // The values from the Counter events from the trace. This includes CPU
   // frequency events as well systrace trace_marker counter events.
-  tables::CounterTable counter_table_{&string_pool_, nullptr};
+  tables::CounterTable counter_table_{&string_pool_};
 
   SqlStats sql_stats_;
 
@@ -899,55 +899,49 @@
   // the timestamp and the pid. The args for the raw event will be in the
   // args table. This table can be used to generate a text version of the
   // trace.
-  tables::RawTable raw_table_{&string_pool_, nullptr};
+  tables::RawTable raw_table_{&string_pool_};
 
-  tables::CpuTable cpu_table_{&string_pool_, nullptr};
+  tables::CpuTable cpu_table_{&string_pool_};
 
-  tables::CpuFreqTable cpu_freq_table_{&string_pool_, nullptr};
+  tables::CpuFreqTable cpu_freq_table_{&string_pool_};
 
   tables::AndroidLogTable android_log_table_{&string_pool_};
 
-  tables::AndroidDumpstateTable android_dumpstate_table_{&string_pool_,
-                                                         nullptr};
+  tables::AndroidDumpstateTable android_dumpstate_table_{&string_pool_};
 
-  tables::StackProfileMappingTable stack_profile_mapping_table_{&string_pool_,
-                                                                nullptr};
-  tables::StackProfileFrameTable stack_profile_frame_table_{&string_pool_,
-                                                            nullptr};
-  tables::StackProfileCallsiteTable stack_profile_callsite_table_{&string_pool_,
-                                                                  nullptr};
-  tables::StackSampleTable stack_sample_table_{&string_pool_, nullptr};
+  tables::StackProfileMappingTable stack_profile_mapping_table_{&string_pool_};
+  tables::StackProfileFrameTable stack_profile_frame_table_{&string_pool_};
+  tables::StackProfileCallsiteTable stack_profile_callsite_table_{
+      &string_pool_};
+  tables::StackSampleTable stack_sample_table_{&string_pool_};
   tables::HeapProfileAllocationTable heap_profile_allocation_table_{
-      &string_pool_, nullptr};
+      &string_pool_};
   tables::CpuProfileStackSampleTable cpu_profile_stack_sample_table_{
       &string_pool_, &stack_sample_table_};
-  tables::PerfSampleTable perf_sample_table_{&string_pool_, nullptr};
-  tables::PackageListTable package_list_table_{&string_pool_, nullptr};
+  tables::PerfSampleTable perf_sample_table_{&string_pool_};
+  tables::PackageListTable package_list_table_{&string_pool_};
   tables::AndroidGameInterventionListTable
-      android_game_intervention_list_table_{&string_pool_, nullptr};
-  tables::ProfilerSmapsTable profiler_smaps_table_{&string_pool_, nullptr};
+      android_game_intervention_list_table_{&string_pool_};
+  tables::ProfilerSmapsTable profiler_smaps_table_{&string_pool_};
 
   // Symbol tables (mappings from frames to symbol names)
-  tables::SymbolTable symbol_table_{&string_pool_, nullptr};
-  tables::HeapGraphObjectTable heap_graph_object_table_{&string_pool_, nullptr};
-  tables::HeapGraphClassTable heap_graph_class_table_{&string_pool_, nullptr};
-  tables::HeapGraphReferenceTable heap_graph_reference_table_{&string_pool_,
-                                                              nullptr};
+  tables::SymbolTable symbol_table_{&string_pool_};
+  tables::HeapGraphObjectTable heap_graph_object_table_{&string_pool_};
+  tables::HeapGraphClassTable heap_graph_class_table_{&string_pool_};
+  tables::HeapGraphReferenceTable heap_graph_reference_table_{&string_pool_};
 
   tables::VulkanMemoryAllocationsTable vulkan_memory_allocations_table_{
-      &string_pool_, nullptr};
+      &string_pool_};
 
   tables::GraphicsFrameSliceTable graphics_frame_slice_table_{&string_pool_,
                                                               &slice_table_};
 
   // Metadata for memory snapshot.
-  tables::MemorySnapshotTable memory_snapshot_table_{&string_pool_, nullptr};
+  tables::MemorySnapshotTable memory_snapshot_table_{&string_pool_};
   tables::ProcessMemorySnapshotTable process_memory_snapshot_table_{
-      &string_pool_, nullptr};
-  tables::MemorySnapshotNodeTable memory_snapshot_node_table_{&string_pool_,
-                                                              nullptr};
-  tables::MemorySnapshotEdgeTable memory_snapshot_edge_table_{&string_pool_,
-                                                              nullptr};
+      &string_pool_};
+  tables::MemorySnapshotNodeTable memory_snapshot_node_table_{&string_pool_};
+  tables::MemorySnapshotEdgeTable memory_snapshot_edge_table_{&string_pool_};
 
   // FrameTimeline tables
   tables::ExpectedFrameTimelineSliceTable expected_frame_timeline_slice_table_{
@@ -956,12 +950,12 @@
       &string_pool_, &slice_table_};
 
   tables::ExperimentalProtoPathTable experimental_proto_path_table_{
-      &string_pool_, nullptr};
+      &string_pool_};
   tables::ExperimentalProtoContentTable experimental_proto_content_table_{
-      &string_pool_, nullptr};
+      &string_pool_};
 
   tables::ExpMissingChromeProcTable
-      experimental_missing_chrome_processes_table_{&string_pool_, nullptr};
+      experimental_missing_chrome_processes_table_{&string_pool_};
 
   views::ThreadSliceView thread_slice_view_{&slice_table_, &thread_track_table_,
                                             &thread_table_};
@@ -1009,8 +1003,8 @@
 
   result_type operator()(const argument_type& r) const {
     return std::hash<::perfetto::trace_processor::StringId>{}(r.name) ^
-           std::hash<::perfetto::base::Optional<
-               ::perfetto::trace_processor::MappingId>>{}(r.mapping) ^
+           std::hash<std::optional<::perfetto::trace_processor::MappingId>>{}(
+               r.mapping) ^
            std::hash<int64_t>{}(r.rel_pc);
   }
 };
@@ -1024,8 +1018,8 @@
 
   result_type operator()(const argument_type& r) const {
     return std::hash<int64_t>{}(r.depth) ^
-           std::hash<::perfetto::base::Optional<
-               ::perfetto::trace_processor::CallsiteId>>{}(r.parent_id) ^
+           std::hash<std::optional<::perfetto::trace_processor::CallsiteId>>{}(
+               r.parent_id) ^
            std::hash<::perfetto::trace_processor::FrameId>{}(r.frame_id);
   }
 };
diff --git a/src/trace_processor/tables/BUILD.gn b/src/trace_processor/tables/BUILD.gn
index 4e578cb..83145a4 100644
--- a/src/trace_processor/tables/BUILD.gn
+++ b/src/trace_processor/tables/BUILD.gn
@@ -18,7 +18,13 @@
 perfetto_tp_tables("tables_python") {
   sources = [
     "android_tables.py",
+    "counter_tables.py",
+    "flow_tables.py",
+    "memory_tables.py",
     "metadata_tables.py",
+    "profiler_tables.py",
+    "slice_tables.py",
+    "trace_proto_tables.py",
     "track_tables.py",
   ]
   generate_docs = true
@@ -26,17 +32,13 @@
 
 source_set("tables") {
   sources = [
-    "android_tables.h",
     "counter_tables.h",
     "flow_tables.h",
     "macros.h",
     "macros_internal.h",
-    "memory_tables.h",
-    "metadata_tables.h",
     "profiler_tables.h",
     "slice_tables.h",
     "table_destructors.cc",
-    "trace_proto_tables.h",
   ]
   deps = [
     "../../../gn:default_deps",
diff --git a/src/trace_processor/tables/android_tables.h b/src/trace_processor/tables/android_tables.h
deleted file mode 100644
index 1f46c16..0000000
--- a/src/trace_processor/tables/android_tables.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_TABLES_ANDROID_TABLES_H_
-#define SRC_TRACE_PROCESSOR_TABLES_ANDROID_TABLES_H_
-
-#include "src/trace_processor/tables/android_tables_py.h"
-#include "src/trace_processor/tables/macros.h"
-
-namespace perfetto {
-namespace trace_processor {
-namespace tables {
-
-// A table presenting all game modes and interventions
-// of games installed on the system.
-// This is generated by the game_mode_intervention data-source.
-// @param package_name name of the pakcage, e.g. com.google.android.gm.
-// @param uid UID processes of this package runs as.
-// @param current_mode current game mode the game is running at.
-// @param standard_mode_supported bool whether standard mode is supported.
-// @param standard_mode_downscale resolution downscaling factor of standard
-// mode.
-// @param standard_mode_use_angle bool whether ANGLE is used in standard mode.
-// @param standard_mode_fps frame rate that the game is throttled at in standard
-// mode.
-// @param perf_mode_supported bool whether performance mode is supported.
-// @param perf_mode_downscale resolution downscaling factor of performance mode.
-// @param perf_mode_use_angle bool whether ANGLE is used in performance mode.
-// @param perf_mode_fps frame rate that the game is throttled at in performance
-// mode.
-// @param battery_mode_supported bool whether battery mode is supported.
-// @param battery_mode_downscale resolution downscaling factor of battery mode.
-// @param battery_mode_use_angle bool whether ANGLE is used in battery mode.
-// @param battery_mode_fps frame rate that the game is throttled at in battery
-// mode.
-#define PERFETTO_TP_ANDROID_GAME_INTERVENTION_LIST_DEF(NAME, PARENT, C)    \
-  NAME(AndroidGameInterventionListTable, "android_game_intervention_list") \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                                        \
-  C(StringPool::Id, package_name)                                          \
-  C(int64_t, uid)                                                          \
-  C(int32_t, current_mode)                                                 \
-  C(int32_t, standard_mode_supported)                                      \
-  C(base::Optional<double>, standard_mode_downscale)                       \
-  C(base::Optional<int32_t>, standard_mode_use_angle)                      \
-  C(base::Optional<double>, standard_mode_fps)                             \
-  C(int32_t, perf_mode_supported)                                          \
-  C(base::Optional<double>, perf_mode_downscale)                           \
-  C(base::Optional<int32_t>, perf_mode_use_angle)                          \
-  C(base::Optional<double>, perf_mode_fps)                                 \
-  C(int32_t, battery_mode_supported)                                       \
-  C(base::Optional<double>, battery_mode_downscale)                        \
-  C(base::Optional<int32_t>, battery_mode_use_angle)                       \
-  C(base::Optional<double>, battery_mode_fps)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_ANDROID_GAME_INTERVENTION_LIST_DEF);
-
-// Dumpsys entries from Android dumpstate.
-//
-// @param section name of the dumpstate section.
-// @param service name of the dumpsys service. Only present when
-// dumpstate=="dumpsys", NULL otherwise.
-// @param line line-by-line contents of the section/service, one row per line.
-// @tablegroup Events
-#define PERFETTO_TP_ANDROID_DUMPSTATE_TABLE_DEF(NAME, PARENT, C) \
-  NAME(AndroidDumpstateTable, "android_dumpstate")               \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                              \
-  C(base::Optional<StringPool::Id>, section)                     \
-  C(base::Optional<StringPool::Id>, service)                     \
-  C(StringPool::Id, line)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_ANDROID_DUMPSTATE_TABLE_DEF);
-
-}  // namespace tables
-}  // namespace trace_processor
-}  // namespace perfetto
-
-#endif  // SRC_TRACE_PROCESSOR_TABLES_ANDROID_TABLES_H_
diff --git a/src/trace_processor/tables/android_tables.py b/src/trace_processor/tables/android_tables.py
index dc1b96f..b77afcb 100644
--- a/src/trace_processor/tables/android_tables.py
+++ b/src/trace_processor/tables/android_tables.py
@@ -14,13 +14,17 @@
 """Contains tables for relevant for Android."""
 
 from python.generators.trace_processor_table.public import Column as C
+from python.generators.trace_processor_table.public import CppDouble
+from python.generators.trace_processor_table.public import CppInt32
 from python.generators.trace_processor_table.public import CppInt64
 from python.generators.trace_processor_table.public import CppOptional
+from python.generators.trace_processor_table.public import CppSelfTableId
 from python.generators.trace_processor_table.public import CppString
 from python.generators.trace_processor_table.public import Table
 from python.generators.trace_processor_table.public import TableDoc
 from python.generators.trace_processor_table.public import CppTableId
 from python.generators.trace_processor_table.public import CppUint32
+
 from src.trace_processor.tables.metadata_tables import THREAD_TABLE
 
 ANDROID_LOG_TABLE = Table(
@@ -49,7 +53,109 @@
             'msg': 'Content of the log entry.'
         }))
 
+ANDROID_GAME_INTERVENTION_LIST_TABLE = Table(
+    class_name='AndroidGameInterventionListTable',
+    sql_name='android_game_intervention_list',
+    columns=[
+        C('package_name', CppString()),
+        C('uid', CppInt64()),
+        C('current_mode', CppInt32()),
+        C('standard_mode_supported', CppInt32()),
+        C('standard_mode_downscale', CppOptional(CppDouble())),
+        C('standard_mode_use_angle', CppOptional(CppInt32())),
+        C('standard_mode_fps', CppOptional(CppDouble())),
+        C('perf_mode_supported', CppInt32()),
+        C('perf_mode_downscale', CppOptional(CppDouble())),
+        C('perf_mode_use_angle', CppOptional(CppInt32())),
+        C('perf_mode_fps', CppOptional(CppDouble())),
+        C('battery_mode_supported', CppInt32()),
+        C('battery_mode_downscale', CppOptional(CppDouble())),
+        C('battery_mode_use_angle', CppOptional(CppInt32())),
+        C('battery_mode_fps', CppOptional(CppDouble())),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          A table presenting all game modes and interventions
+of games installed on the system.
+This is generated by the game_mode_intervention data-source.
+        ''',
+        group='Misc',
+        columns={
+            'package_name':
+                '''name of the pakcage, e.g. com.google.android.gm.''',
+            'uid':
+                '''UID processes of this package runs as.''',
+            'current_mode':
+                '''current game mode the game is running at.''',
+            'standard_mode_supported':
+                '''bool whether standard mode is supported.''',
+            'standard_mode_downscale':
+                '''
+                    resolution downscaling factor of standard
+                    mode.
+                ''',
+            'standard_mode_use_angle':
+                '''bool whether ANGLE is used in standard mode.''',
+            'standard_mode_fps':
+                '''
+                    frame rate that the game is throttled at in standard
+                    mode.
+                ''',
+            'perf_mode_supported':
+                '''bool whether performance mode is supported.''',
+            'perf_mode_downscale':
+                '''resolution downscaling factor of performance mode.''',
+            'perf_mode_use_angle':
+                '''bool whether ANGLE is used in performance mode.''',
+            'perf_mode_fps':
+                '''
+                    frame rate that the game is throttled at in performance
+                    mode.
+                ''',
+            'battery_mode_supported':
+                '''bool whether battery mode is supported.''',
+            'battery_mode_downscale':
+                '''resolution downscaling factor of battery mode.''',
+            'battery_mode_use_angle':
+                '''bool whether ANGLE is used in battery mode.''',
+            'battery_mode_fps':
+                '''
+                    frame rate that the game is throttled at in battery
+                    mode.
+                '''
+        }))
+
+ANDROID_DUMPSTATE_TABLE = Table(
+    class_name='AndroidDumpstateTable',
+    sql_name='android_dumpstate',
+    columns=[
+        C('section', CppOptional(CppString())),
+        C('service', CppOptional(CppString())),
+        C('line', CppString()),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          Dumpsys entries from Android dumpstate.
+        ''',
+        group='Events',
+        columns={
+            'section':
+                '''name of the dumpstate section.''',
+            'service':
+                '''
+                    name of the dumpsys service. Only present when
+                    dumpstate=="dumpsys", NULL otherwise.
+                ''',
+            'line':
+                '''
+                    line-by-line contents of the section/service,
+                    one row per line.
+                '''
+        }))
+
 # Keep this list sorted.
 ALL_TABLES = [
     ANDROID_LOG_TABLE,
+    ANDROID_DUMPSTATE_TABLE,
+    ANDROID_GAME_INTERVENTION_LIST_TABLE,
 ]
diff --git a/src/trace_processor/tables/counter_tables.h b/src/trace_processor/tables/counter_tables.h
index e051980..69668b2 100644
--- a/src/trace_processor/tables/counter_tables.h
+++ b/src/trace_processor/tables/counter_tables.h
@@ -32,9 +32,7 @@
   C(int64_t, ts, Column::Flag::kSorted)                \
   C(CounterTrackTable::Id, track_id)                   \
   C(double, value)                                     \
-  C(base::Optional<uint32_t>, arg_set_id)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_COUNTER_TABLE_DEF);
+  C(std::optional<uint32_t>, arg_set_id)
 
 }  // namespace tables
 }  // namespace trace_processor
diff --git a/src/trace_processor/tables/counter_tables.py b/src/trace_processor/tables/counter_tables.py
new file mode 100644
index 0000000..1dd6495
--- /dev/null
+++ b/src/trace_processor/tables/counter_tables.py
@@ -0,0 +1,50 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Contains tables for relevant for TODO."""
+
+from python.generators.trace_processor_table.public import Column as C
+from python.generators.trace_processor_table.public import CppDouble
+from python.generators.trace_processor_table.public import ColumnFlag
+from python.generators.trace_processor_table.public import CppInt64
+from python.generators.trace_processor_table.public import CppOptional
+from python.generators.trace_processor_table.public import Table
+from python.generators.trace_processor_table.public import TableDoc
+from python.generators.trace_processor_table.public import CppTableId
+from python.generators.trace_processor_table.public import CppUint32
+
+from src.trace_processor.tables.track_tables import COUNTER_TRACK_TABLE
+
+COUNTER_TABLE = Table(
+    class_name='CounterTable',
+    sql_name='counter',
+    columns=[
+        C('ts', CppInt64(), flags=ColumnFlag.SORTED),
+        C('track_id', CppTableId(COUNTER_TRACK_TABLE)),
+        C('value', CppDouble()),
+        C('arg_set_id', CppOptional(CppUint32())),
+    ],
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Events',
+        columns={
+            'ts': '''''',
+            'track_id': '''''',
+            'value': '''''',
+            'arg_set_id': '''''',
+        }))
+
+# Keep this list sorted.
+ALL_TABLES = [
+    COUNTER_TABLE,
+]
diff --git a/src/trace_processor/tables/flow_tables.h b/src/trace_processor/tables/flow_tables.h
index 1023836..a00ee89 100644
--- a/src/trace_processor/tables/flow_tables.h
+++ b/src/trace_processor/tables/flow_tables.h
@@ -32,8 +32,6 @@
   C(SliceTable::Id, slice_in)                       \
   C(uint32_t, arg_set_id)
 
-PERFETTO_TP_TABLE(PERFETTO_TP_FLOW_TABLE_DEF);
-
 }  // namespace tables
 }  // namespace trace_processor
 }  // namespace perfetto
diff --git a/src/trace_processor/tables/flow_tables.py b/src/trace_processor/tables/flow_tables.py
new file mode 100644
index 0000000..0491a31
--- /dev/null
+++ b/src/trace_processor/tables/flow_tables.py
@@ -0,0 +1,44 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Contains tables for relevant for TODO."""
+
+from python.generators.trace_processor_table.public import Column as C
+from python.generators.trace_processor_table.public import Table
+from python.generators.trace_processor_table.public import TableDoc
+from python.generators.trace_processor_table.public import CppTableId
+from python.generators.trace_processor_table.public import CppUint32
+
+from src.trace_processor.tables.slice_tables import SLICE_TABLE
+
+FLOW_TABLE = Table(
+    class_name='FlowTable',
+    sql_name='flow',
+    columns=[
+        C('slice_out', CppTableId(SLICE_TABLE)),
+        C('slice_in', CppTableId(SLICE_TABLE)),
+        C('arg_set_id', CppUint32()),
+    ],
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Misc',
+        columns={
+            'arg_set_id': '''''',
+            'slice_out': '''''',
+            'slice_in': ''''''
+        }))
+
+# Keep this list sorted.
+ALL_TABLES = [
+    FLOW_TABLE,
+]
diff --git a/src/trace_processor/tables/macros_benchmark.cc b/src/trace_processor/tables/macros_benchmark.cc
index 5df9e8c..c946696 100644
--- a/src/trace_processor/tables/macros_benchmark.cc
+++ b/src/trace_processor/tables/macros_benchmark.cc
@@ -28,7 +28,7 @@
   C(uint32_t, root_sorted, Column::Flag::kSorted)    \
   C(uint32_t, root_non_null)                         \
   C(uint32_t, root_non_null_2)                       \
-  C(base::Optional<uint32_t>, root_nullable)
+  C(std::optional<uint32_t>, root_nullable)
 
 PERFETTO_TP_TABLE(PERFETTO_TP_ROOT_TEST_TABLE);
 
@@ -37,7 +37,7 @@
   PARENT(PERFETTO_TP_ROOT_TEST_TABLE, C)           \
   C(uint32_t, child_sorted, Column::Flag::kSorted) \
   C(uint32_t, child_non_null)                      \
-  C(base::Optional<uint32_t>, child_nullable)
+  C(std::optional<uint32_t>, child_nullable)
 
 PERFETTO_TP_TABLE(PERFETTO_TP_CHILD_TABLE);
 
@@ -264,8 +264,8 @@
     uint32_t value = rnd_engine() % partitions;
 
     RootTestTable::Row row;
-    row.root_nullable = value % 2 == 0 ? perfetto::base::nullopt
-                                       : perfetto::base::make_optional(value);
+    row.root_nullable =
+        value % 2 == 0 ? std::nullopt : std::make_optional(value);
     root.Insert(row);
   }
 
@@ -310,8 +310,8 @@
     uint32_t value = rnd_engine() % partitions;
 
     ChildTestTable::Row row;
-    row.child_nullable = value % 2 == 0 ? perfetto::base::nullopt
-                                        : perfetto::base::make_optional(value);
+    row.child_nullable =
+        value % 2 == 0 ? std::nullopt : std::make_optional(value);
     root.Insert({});
     child.Insert(row);
   }
@@ -488,9 +488,8 @@
     const uint32_t root_value = static_cast<uint32_t>(rnd_engine());
 
     RootTestTable::Row row;
-    row.root_nullable = root_value % 2 == 0
-                            ? perfetto::base::nullopt
-                            : perfetto::base::make_optional(root_value);
+    row.root_nullable =
+        root_value % 2 == 0 ? std::nullopt : std::make_optional(root_value);
     root.Insert(row);
   }
 
@@ -540,17 +539,15 @@
     const uint32_t root_value = static_cast<uint32_t>(rnd_engine());
 
     RootTestTable::Row root_row;
-    root_row.root_nullable = root_value % 2 == 0
-                                 ? perfetto::base::nullopt
-                                 : perfetto::base::make_optional(root_value);
+    root_row.root_nullable =
+        root_value % 2 == 0 ? std::nullopt : std::make_optional(root_value);
     root.Insert(root_row);
 
     const uint32_t child_value = static_cast<uint32_t>(rnd_engine());
 
     ChildTestTable::Row child_row;
-    child_row.root_nullable = child_value % 2 == 0
-                                  ? perfetto::base::nullopt
-                                  : perfetto::base::make_optional(child_value);
+    child_row.root_nullable =
+        child_value % 2 == 0 ? std::nullopt : std::make_optional(child_value);
     child.Insert(child_row);
   }
 
diff --git a/src/trace_processor/tables/macros_internal.h b/src/trace_processor/tables/macros_internal.h
index 4389ce2..059e7b7 100644
--- a/src/trace_processor/tables/macros_internal.h
+++ b/src/trace_processor/tables/macros_internal.h
@@ -576,7 +576,7 @@
                                                                               \
     struct Row : parent_class_name::Row {                                     \
       /*                                                                      \
-       * Expands to Row(col_type1 col1_c, base::Optional<col_type2> col2_c,   \
+       * Expands to Row(col_type1 col1_c, std::optional<col_type2> col2_c,    \
        * ...)                                                                 \
        */                                                                     \
       Row(PERFETTO_TP_ALL_COLUMNS(DEF, PERFETTO_TP_ROW_CONSTRUCTOR)           \
@@ -841,18 +841,18 @@
     }                                                                         \
                                                                               \
     /* Returns a ConstRowReference to the row pointed to by |find_id|. */     \
-    base::Optional<ConstRowReference> FindById(Id find_id) const {            \
-      base::Optional<uint32_t> row = id().IndexOf(find_id);                   \
+    std::optional<ConstRowReference> FindById(Id find_id) const {             \
+      std::optional<uint32_t> row = id().IndexOf(find_id);                    \
       if (!row)                                                               \
-        return base::nullopt;                                                 \
+        return std::nullopt;                                                  \
       return ConstRowReference(this, *row);                                   \
     }                                                                         \
                                                                               \
     /* Returns a RowReference to the row pointed to by |find_id|. */          \
-    base::Optional<RowReference> FindById(Id find_id) {                       \
-      base::Optional<uint32_t> row = id().IndexOf(find_id);                   \
+    std::optional<RowReference> FindById(Id find_id) {                        \
+      std::optional<uint32_t> row = id().IndexOf(find_id);                    \
       if (!row)                                                               \
-        return base::nullopt;                                                 \
+        return std::nullopt;                                                  \
       return RowReference(this, *row);                                        \
     }                                                                         \
                                                                               \
diff --git a/src/trace_processor/tables/macros_unittest.cc b/src/trace_processor/tables/macros_unittest.cc
index 9844a9d..f6414cd 100644
--- a/src/trace_processor/tables/macros_unittest.cc
+++ b/src/trace_processor/tables/macros_unittest.cc
@@ -33,13 +33,13 @@
 #define PERFETTO_TP_TEST_COUNTER_TABLE_DEF(NAME, PARENT, C) \
   NAME(TestCounterTable, "counter")                         \
   PARENT(PERFETTO_TP_TEST_EVENT_TABLE_DEF, C)               \
-  C(base::Optional<double>, value)
+  C(std::optional<double>, value)
 PERFETTO_TP_TABLE(PERFETTO_TP_TEST_COUNTER_TABLE_DEF);
 
 #define PERFETTO_TP_TEST_SLICE_TABLE_DEF(NAME, PARENT, C) \
   NAME(TestSliceTable, "slice")                           \
   PARENT(PERFETTO_TP_TEST_EVENT_TABLE_DEF, C)             \
-  C(base::Optional<int64_t>, dur)                         \
+  C(std::optional<int64_t>, dur)                          \
   C(int64_t, depth)
 PERFETTO_TP_TABLE(PERFETTO_TP_TEST_SLICE_TABLE_DEF);
 
@@ -107,7 +107,7 @@
   ASSERT_EQ(slice_.dur()[0], 10);
   ASSERT_EQ(slice_.depth()[0], 0);
 
-  id = slice_.Insert(TestSliceTable::Row(210, 456, base::nullopt, 0)).id;
+  id = slice_.Insert(TestSliceTable::Row(210, 456, std::nullopt, 0)).id;
   ASSERT_EQ(id.value, 2u);
 
   ASSERT_EQ(event_.type().GetString(2), "slice");
@@ -116,7 +116,7 @@
   ASSERT_EQ(slice_.type().GetString(1), "slice");
   ASSERT_EQ(slice_.ts()[1], 210);
   ASSERT_EQ(slice_.arg_set_id()[1], 456);
-  ASSERT_EQ(slice_.dur()[1], base::nullopt);
+  ASSERT_EQ(slice_.dur()[1], std::nullopt);
   ASSERT_EQ(slice_.depth()[1], 0);
 }
 
diff --git a/src/trace_processor/tables/memory_tables.h b/src/trace_processor/tables/memory_tables.h
deleted file mode 100644
index aa09667..0000000
--- a/src/trace_processor/tables/memory_tables.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_TABLES_MEMORY_TABLES_H_
-#define SRC_TRACE_PROCESSOR_TABLES_MEMORY_TABLES_H_
-
-#include "src/trace_processor/tables/macros.h"
-#include "src/trace_processor/tables/track_tables_py.h"
-
-namespace perfetto {
-namespace trace_processor {
-namespace tables {
-
-// @tablegroup Memory Snapshots
-#define PERFETTO_TP_MEMORY_SNAPSHOT_DEF(NAME, PARENT, C) \
-  NAME(MemorySnapshotTable, "memory_snapshot")           \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                      \
-  C(int64_t, timestamp)                                  \
-  C(TrackTable::Id, track_id)                            \
-  C(StringPool::Id, detail_level)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_MEMORY_SNAPSHOT_DEF);
-
-// @tablegroup Memory Snapshots
-#define PERFETTO_TP_PROCESS_MEMORY_SNAPSHOT_DEF(NAME, PARENT, C) \
-  NAME(ProcessMemorySnapshotTable, "process_memory_snapshot")    \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                              \
-  C(MemorySnapshotTable::Id, snapshot_id)                        \
-  C(uint32_t, upid)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_PROCESS_MEMORY_SNAPSHOT_DEF);
-
-// @tablegroup Memory Snapshots
-#define PERFETTO_TP_MEMORY_SNAPSHOT_NODE_DEF(NAME, PARENT, C)    \
-  NAME(MemorySnapshotNodeTable, "memory_snapshot_node")          \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                              \
-  C(ProcessMemorySnapshotTable::Id, process_snapshot_id)         \
-  C(base::Optional<MemorySnapshotNodeTable::Id>, parent_node_id) \
-  C(StringPool::Id, path)                                        \
-  C(int64_t, size)                                               \
-  C(int64_t, effective_size)                                     \
-  C(base::Optional<uint32_t>, arg_set_id)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_MEMORY_SNAPSHOT_NODE_DEF);
-
-// @tablegroup Memory Snapshots
-#define PERFETTO_TP_MEMORY_SNAPSHOT_EDGE_DEF(NAME, PARENT, C) \
-  NAME(MemorySnapshotEdgeTable, "memory_snapshot_edge")       \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                           \
-  C(MemorySnapshotNodeTable::Id, source_node_id)              \
-  C(MemorySnapshotNodeTable::Id, target_node_id)              \
-  C(uint32_t, importance)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_MEMORY_SNAPSHOT_EDGE_DEF);
-
-}  // namespace tables
-}  // namespace trace_processor
-}  // namespace perfetto
-
-#endif  // SRC_TRACE_PROCESSOR_TABLES_MEMORY_TABLES_H_
diff --git a/src/trace_processor/tables/memory_tables.py b/src/trace_processor/tables/memory_tables.py
new file mode 100644
index 0000000..65263f8
--- /dev/null
+++ b/src/trace_processor/tables/memory_tables.py
@@ -0,0 +1,106 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Contains tables for relevant for TODO."""
+
+from python.generators.trace_processor_table.public import Column as C
+from python.generators.trace_processor_table.public import CppInt64
+from python.generators.trace_processor_table.public import CppOptional
+from python.generators.trace_processor_table.public import CppSelfTableId
+from python.generators.trace_processor_table.public import CppString
+from python.generators.trace_processor_table.public import Table
+from python.generators.trace_processor_table.public import TableDoc
+from python.generators.trace_processor_table.public import CppTableId
+from python.generators.trace_processor_table.public import CppUint32
+
+from src.trace_processor.tables.track_tables import TRACK_TABLE
+
+MEMORY_SNAPSHOT_TABLE = Table(
+    class_name='MemorySnapshotTable',
+    sql_name='memory_snapshot',
+    columns=[
+        C('timestamp', CppInt64()),
+        C('track_id', CppTableId(TRACK_TABLE)),
+        C('detail_level', CppString()),
+    ],
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Memory Snapshots',
+        columns={
+            'timestamp': '''''',
+            'track_id': '''''',
+            'detail_level': ''''''
+        }))
+
+PROCESS_MEMORY_SNAPSHOT_TABLE = Table(
+    class_name='ProcessMemorySnapshotTable',
+    sql_name='process_memory_snapshot',
+    columns=[
+        C('snapshot_id', CppTableId(MEMORY_SNAPSHOT_TABLE)),
+        C('upid', CppUint32()),
+    ],
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Memory Snapshots',
+        columns={
+            'snapshot_id': '''''',
+            'upid': ''''''
+        }))
+
+MEMORY_SNAPSHOT_NODE_TABLE = Table(
+    class_name='MemorySnapshotNodeTable',
+    sql_name='memory_snapshot_node',
+    columns=[
+        C('process_snapshot_id', CppTableId(PROCESS_MEMORY_SNAPSHOT_TABLE)),
+        C('parent_node_id', CppOptional(CppSelfTableId())),
+        C('path', CppString()),
+        C('size', CppInt64()),
+        C('effective_size', CppInt64()),
+        C('arg_set_id', CppOptional(CppUint32())),
+    ],
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Memory Snapshots',
+        columns={
+            'process_snapshot_id': '''''',
+            'parent_node_id': '''''',
+            'path': '''''',
+            'size': '''''',
+            'effective_size': '''''',
+            'arg_set_id': ''''''
+        }))
+
+MEMORY_SNAPSHOT_EDGE_TABLE = Table(
+    class_name='MemorySnapshotEdgeTable',
+    sql_name='memory_snapshot_edge',
+    columns=[
+        C('source_node_id', CppTableId(MEMORY_SNAPSHOT_NODE_TABLE)),
+        C('target_node_id', CppTableId(MEMORY_SNAPSHOT_NODE_TABLE)),
+        C('importance', CppUint32()),
+    ],
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Memory Snapshots',
+        columns={
+            'source_node_id': '''''',
+            'target_node_id': '''''',
+            'importance': ''''''
+        }))
+
+# Keep this list sorted.
+ALL_TABLES = [
+    MEMORY_SNAPSHOT_EDGE_TABLE,
+    MEMORY_SNAPSHOT_NODE_TABLE,
+    MEMORY_SNAPSHOT_TABLE,
+    PROCESS_MEMORY_SNAPSHOT_TABLE,
+]
diff --git a/src/trace_processor/tables/metadata_tables.h b/src/trace_processor/tables/metadata_tables.h
deleted file mode 100644
index 76768ed..0000000
--- a/src/trace_processor/tables/metadata_tables.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_TABLES_METADATA_TABLES_H_
-#define SRC_TRACE_PROCESSOR_TABLES_METADATA_TABLES_H_
-
-#include "src/trace_processor/tables/macros.h"
-#include "src/trace_processor/tables/metadata_tables_py.h"
-
-namespace perfetto {
-namespace trace_processor {
-namespace tables {
-
-// @param arg_set_id {@joinable args.arg_set_id}
-#define PERFETTO_TP_RAW_TABLE_DEF(NAME, PARENT, C) \
-  NAME(RawTable, "raw")                            \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                \
-  C(int64_t, ts, Column::Flag::kSorted)            \
-  C(StringPool::Id, name)                          \
-  C(uint32_t, cpu)                                 \
-  C(uint32_t, utid)                                \
-  C(uint32_t, arg_set_id)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_RAW_TABLE_DEF);
-
-// @name args
-#define PERFETTO_TP_ARG_TABLE_DEF(NAME, PARENT, C) \
-  NAME(ArgTable, "internal_args")                  \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                \
-  C(uint32_t, arg_set_id, Column::Flag::kSorted)   \
-  C(StringPool::Id, flat_key)                      \
-  C(StringPool::Id, key)                           \
-  C(base::Optional<int64_t>, int_value)            \
-  C(base::Optional<StringPool::Id>, string_value)  \
-  C(base::Optional<double>, real_value)            \
-  C(StringPool::Id, value_type)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_ARG_TABLE_DEF);
-
-#define PERFETTO_TP_METADATA_TABLE_DEF(NAME, PARENT, C) \
-  NAME(MetadataTable, "metadata")                       \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                     \
-  C(StringPool::Id, name)                               \
-  C(StringPool::Id, key_type)                           \
-  C(base::Optional<int64_t>, int_value)                 \
-  C(base::Optional<StringPool::Id>, str_value)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_METADATA_TABLE_DEF);
-
-// Contains information of filedescriptors collected during the trace
-//
-// @name filedescriptor
-// @param ufd             {int64_t} Unique fd. This is != the OS fd.
-//                        This is a monotonic number associated to each
-//                        filedescriptor. The OS assigned fd cannot be used as
-//                        primary key because fds are recycled by most kernels.
-// @param fd              The OS id for this process. Note: this is *not*
-//                        unique over the lifetime of the trace so cannot be
-//                        used as a primary key. Use |ufd| instead.
-// @param ts              The timestamp for when the fd was collected.
-// @param upid            {@joinable process.upid} The upid of the process which
-//                        opened the filedescriptor.
-// @param path            The path to the file or device backing the fd
-//                        In case this was a socket the path will be the port
-//                        number.
-#define PERFETTO_TP_FILEDESCRIPTOR_TABLE_DEF(NAME, PARENT, C) \
-  NAME(FiledescriptorTable, "filedescriptor")                 \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                           \
-  C(int64_t, fd)                                              \
-  C(base::Optional<int64_t>, ts)                              \
-  C(base::Optional<uint32_t>, upid)                           \
-  C(base::Optional<StringPool::Id>, path)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_FILEDESCRIPTOR_TABLE_DEF);
-
-// Experimental table, subject to arbitrary breaking changes.
-#define PERFETTO_TP_EXP_MISSING_CHROME_PROC_TABLE_DEF(NAME, PARENT, C)     \
-  NAME(ExpMissingChromeProcTable, "experimental_missing_chrome_processes") \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                                        \
-  C(uint32_t, upid)                                                        \
-  C(base::Optional<int64_t>, reliable_from)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_EXP_MISSING_CHROME_PROC_TABLE_DEF);
-
-// Contains information of processes seen during the trace
-//
-// @name cpu
-// @param id                     id of this CPU
-// @param cluster_id             the cluster id is shared by CPUs in
-//                               the same cluster
-// @param processor              a string describing this core
-#define PERFETTO_TP_CPU_TABLE_DEF(NAME, PARENT, C) \
-  NAME(CpuTable, "cpu")                            \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                \
-  C(uint32_t, cluster_id)                          \
-  C(StringPool::Id, processor)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_CPU_TABLE_DEF);
-
-#define PERFETTO_TP_CPU_FREQ_TABLE_DEF(NAME, PARENT, C) \
-  NAME(CpuFreqTable, "cpu_freq")                        \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                     \
-  C(CpuTable::Id, cpu_id)                               \
-  C(uint32_t, freq)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_CPU_FREQ_TABLE_DEF);
-
-// Contains all the mapping between clock snapshots and trace time.
-//
-// NOTE: this table is not sorted by timestamp; this is why we omit the
-// sorted flag on the ts column.
-//
-// @param ts            timestamp of the snapshot in trace time.
-// @param clock_id      id of the clock (corresponds to the id in the trace).
-// @param clock_name    the name of the clock for builtin clocks or null
-//                      otherwise.
-// @param clock_value   timestamp of the snapshot in clock time.
-// @param snapshot_id   the index of this snapshot (only useful for debugging)
-#define PERFETTO_TP_CLOCK_SNAPSHOT_TABLE_DEF(NAME, PARENT, C) \
-  NAME(ClockSnapshotTable, "clock_snapshot")                  \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                           \
-  C(int64_t, ts)                                              \
-  C(int64_t, clock_id)                                        \
-  C(base::Optional<StringPool::Id>, clock_name)               \
-  C(int64_t, clock_value)                                     \
-  C(uint32_t, snapshot_id)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_CLOCK_SNAPSHOT_TABLE_DEF);
-
-}  // namespace tables
-}  // namespace trace_processor
-}  // namespace perfetto
-
-#endif  // SRC_TRACE_PROCESSOR_TABLES_METADATA_TABLES_H_
diff --git a/src/trace_processor/tables/metadata_tables.py b/src/trace_processor/tables/metadata_tables.py
index 18f0324..621f3fc 100644
--- a/src/trace_processor/tables/metadata_tables.py
+++ b/src/trace_processor/tables/metadata_tables.py
@@ -16,6 +16,8 @@
 from python.generators.trace_processor_table.public import Alias
 from python.generators.trace_processor_table.public import Column as C
 from python.generators.trace_processor_table.public import ColumnDoc
+from python.generators.trace_processor_table.public import ColumnFlag
+from python.generators.trace_processor_table.public import CppDouble
 from python.generators.trace_processor_table.public import CppInt64
 from python.generators.trace_processor_table.public import CppOptional
 from python.generators.trace_processor_table.public import CppString
@@ -78,10 +80,12 @@
                   (e.g. sched_process_free ftrace event on Linux/Android).
                 ''',
             'parent_upid':
-                '''
+                ColumnDoc(
+                    '''
                   The upid of the process which caused this process to be
                   spawned.
                 ''',
+                    joinable='process.upid'),
             'uid':
                 ColumnDoc(
                     'The Unix user id of the process.',
@@ -144,7 +148,9 @@
                   sched_process_free ftrace event on Linux/Android).
                 ''',
             'upid':
-                'The process hosting this thread.',
+                ColumnDoc(
+                    'The process hosting this thread.',
+                    joinable='process.upid'),
             'is_main_thread':
                 '''
                   Boolean indicating if this thread is the main thread
@@ -152,8 +158,193 @@
                 '''
         }))
 
+RAW_TABLE = Table(
+    class_name='RawTable',
+    sql_name='raw',
+    columns=[
+        C('ts', CppInt64(), flags=ColumnFlag.SORTED),
+        C('name', CppString()),
+        C('cpu', CppUint32()),
+        C('utid', CppUint32()),
+        C('arg_set_id', CppUint32()),
+    ],
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Misc',
+        columns={
+            'arg_set_id': '''''',
+            'ts': '''''',
+            'name': '''''',
+            'cpu': '''''',
+            'utid': ''''''
+        }))
+
+ARG_TABLE = Table(
+    class_name='ArgTable',
+    sql_name='internal_args',
+    columns=[
+        C('arg_set_id', CppUint32(), flags=ColumnFlag.SORTED),
+        C('flat_key', CppString()),
+        C('key', CppString()),
+        C('int_value', CppOptional(CppInt64())),
+        C('string_value', CppOptional(CppString())),
+        C('real_value', CppOptional(CppDouble())),
+        C('value_type', CppString()),
+    ],
+    wrapping_sql_view=WrappingSqlView(view_name='args'),
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Misc',
+        columns={
+            'arg_set_id': '''''',
+            'flat_key': '''''',
+            'key': '''''',
+            'int_value': '''''',
+            'string_value': '''''',
+            'real_value': '''''',
+            'value_type': ''''''
+        }))
+
+METADATA_TABLE = Table(
+    class_name='MetadataTable',
+    sql_name='metadata',
+    columns=[
+        C('name', CppString()),
+        C('key_type', CppString()),
+        C('int_value', CppOptional(CppInt64())),
+        C('str_value', CppOptional(CppString())),
+    ],
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Misc',
+        columns={
+            'name': '''''',
+            'key_type': '''''',
+            'int_value': '''''',
+            'str_value': ''''''
+        }))
+
+FILEDESCRIPTOR_TABLE = Table(
+    class_name='FiledescriptorTable',
+    sql_name='filedescriptor',
+    columns=[
+        C('ufd', CppInt64()),
+        C('fd', CppInt64()),
+        C('ts', CppOptional(CppInt64())),
+        C('upid', CppOptional(CppUint32())),
+        C('path', CppOptional(CppString())),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          Contains information of filedescriptors collected during the trace
+        ''',
+        group='Misc',
+        columns={
+            'ufd':
+                '''Unique fd. This is != the OS fd.
+This is a monotonic number associated to each
+filedescriptor. The OS assigned fd cannot be used as
+primary key because fds are recycled by most kernels.''',
+            'fd':
+                '''The OS id for this process. Note: this is *not*
+unique over the lifetime of the trace so cannot be
+used as a primary key. Use |ufd| instead.''',
+            'ts':
+                '''The timestamp for when the fd was collected.''',
+            'upid':
+                ''' The upid of the process which
+opened the filedescriptor.''',
+            'path':
+                '''The path to the file or device backing the fd
+In case this was a socket the path will be the port
+number.'''
+        }))
+
+EXP_MISSING_CHROME_PROC_TABLE = Table(
+    class_name='ExpMissingChromeProcTable',
+    sql_name='experimental_missing_chrome_processes',
+    columns=[
+        C('upid', CppUint32()),
+        C('reliable_from', CppOptional(CppInt64())),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          Experimental table, subject to arbitrary breaking changes.
+        ''',
+        group='Misc',
+        columns={
+            'upid': '''''',
+            'reliable_from': ''''''
+        }))
+
+CPU_TABLE = Table(
+    class_name='CpuTable',
+    sql_name='cpu',
+    columns=[
+        C('cluster_id', CppUint32()),
+        C('processor', CppString()),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          Contains information of processes seen during the trace
+        ''',
+        group='Misc',
+        columns={
+            'cluster_id':
+                '''the cluster id is shared by CPUs in
+the same cluster''',
+            'processor':
+                '''a string describing this core'''
+        }))
+
+CPU_FREQ_TABLE = Table(
+    class_name='CpuFreqTable',
+    sql_name='cpu_freq',
+    columns=[
+        C('cpu_id', CppTableId(CPU_TABLE)),
+        C('freq', CppUint32()),
+    ],
+    tabledoc=TableDoc(
+        doc='''''', group='Misc', columns={
+            'cpu_id': '''''',
+            'freq': ''''''
+        }))
+
+CLOCK_SNAPSHOT_TABLE = Table(
+    class_name='ClockSnapshotTable',
+    sql_name='clock_snapshot',
+    columns=[
+        C('ts', CppInt64()),
+        C('clock_id', CppInt64()),
+        C('clock_name', CppOptional(CppString())),
+        C('clock_value', CppInt64()),
+        C('snapshot_id', CppUint32()),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          Contains all the mapping between clock snapshots and trace time.
+
+NOTE: this table is not sorted by timestamp; this is why we omit the
+sorted flag on the ts column.
+        ''',
+        group='Misc',
+        columns={
+            'ts':
+                '''timestamp of the snapshot in trace time.''',
+            'clock_id':
+                '''id of the clock (corresponds to the id in the trace).''',
+            'clock_name':
+                '''the name of the clock for builtin clocks or null
+otherwise.''',
+            'clock_value':
+                '''timestamp of the snapshot in clock time.''',
+            'snapshot_id':
+                '''the index of this snapshot (only useful for debugging)'''
+        }))
+
 # Keep this list sorted.
 ALL_TABLES = [
-    THREAD_TABLE,
-    PROCESS_TABLE,
+    ARG_TABLE, CLOCK_SNAPSHOT_TABLE, CPU_FREQ_TABLE, CPU_TABLE,
+    EXP_MISSING_CHROME_PROC_TABLE, FILEDESCRIPTOR_TABLE, METADATA_TABLE,
+    PROCESS_TABLE, RAW_TABLE, THREAD_TABLE
 ]
diff --git a/src/trace_processor/tables/profiler_tables.h b/src/trace_processor/tables/profiler_tables.h
index 3523b80..f0e84b2 100644
--- a/src/trace_processor/tables/profiler_tables.h
+++ b/src/trace_processor/tables/profiler_tables.h
@@ -24,108 +24,6 @@
 namespace trace_processor {
 namespace tables {
 
-// The profiler smaps contains the memory stats for virtual memory ranges
-// captured by the [heap profiler](/docs/data-sources/native-heap-profiler.md).
-// @param upid The UniquePID of the process {@joinable process.upid}.
-// @param ts   Timestamp of the snapshot. Multiple rows will have the same
-//             timestamp.
-// @param path The mmaped file, as per /proc/pid/smaps.
-// @param size_kb Total size of the mapping.
-// @param private_dirty_kb KB of this mapping that are private dirty  RSS.
-// @param swap_kb KB of this mapping that are in swap.
-// @param file_name
-// @param start_address
-// @param module_timestamp
-// @param module_debugid
-// @param module_debug_path
-// @param protection_flags
-// @param private_clean_resident_kb
-// @param shared_dirty_resident_kb
-// @param shared_clean_resident_kb
-// @param locked_kb
-// @param proportional_resident_kb
-// @tablegroup Callstack profilers
-#define PERFETTO_TP_PROFILER_SMAPS_DEF(NAME, PARENT, C) \
-  NAME(ProfilerSmapsTable, "profiler_smaps")            \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                     \
-  C(uint32_t, upid)                                     \
-  C(int64_t, ts)                                        \
-  C(StringPool::Id, path)                               \
-  C(int64_t, size_kb)                                   \
-  C(int64_t, private_dirty_kb)                          \
-  C(int64_t, swap_kb)                                   \
-  C(StringPool::Id, file_name)                          \
-  C(int64_t, start_address)                             \
-  C(int64_t, module_timestamp)                          \
-  C(StringPool::Id, module_debugid)                     \
-  C(StringPool::Id, module_debug_path)                  \
-  C(int64_t, protection_flags)                          \
-  C(int64_t, private_clean_resident_kb)                 \
-  C(int64_t, shared_dirty_resident_kb)                  \
-  C(int64_t, shared_clean_resident_kb)                  \
-  C(int64_t, locked_kb)                                 \
-  C(int64_t, proportional_resident_kb)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_PROFILER_SMAPS_DEF);
-
-// Metadata about packages installed on the system.
-// This is generated by the packages_list data-source.
-// @param package_name name of the package, e.g. com.google.android.gm.
-// @param uid UID processes of this package run as.
-// @param debuggable bool whether this app is debuggable.
-// @param profileable_from_shell bool whether this app is profileable.
-// @param version_code versionCode from the APK.
-#define PERFETTO_TP_PACKAGES_LIST_DEF(NAME, PARENT, C) \
-  NAME(PackageListTable, "package_list")               \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                    \
-  C(StringPool::Id, package_name)                      \
-  C(int64_t, uid)                                      \
-  C(int32_t, debuggable)                               \
-  C(int32_t, profileable_from_shell)                   \
-  C(int64_t, version_code)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_PACKAGES_LIST_DEF);
-
-// A mapping (binary / library) in a process.
-// This is generated by the stack profilers: heapprofd and traced_perf.
-// @param build_id hex-encoded Build ID of the binary / library.
-// @param start start of the mapping in the process' address space.
-// @param end end of the mapping in the process' address space.
-// @param name filename of the binary / library {@joinable profiler_smaps.path}.
-// @tablegroup Callstack profilers
-#define PERFETTO_TP_STACK_PROFILE_MAPPING_DEF(NAME, PARENT, C) \
-  NAME(StackProfileMappingTable, "stack_profile_mapping")      \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                            \
-  C(StringPool::Id, build_id)                                  \
-  C(int64_t, exact_offset)                                     \
-  C(int64_t, start_offset)                                     \
-  C(int64_t, start)                                            \
-  C(int64_t, end)                                              \
-  C(int64_t, load_bias)                                        \
-  C(StringPool::Id, name)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_STACK_PROFILE_MAPPING_DEF);
-
-// A frame on the callstack. This is a location in a program.
-// This is generated by the stack profilers: heapprofd and traced_perf.
-// @param name name of the function this location is in.
-// @param mapping the mapping (library / binary) this location is in.
-// @param rel_pc the program counter relative to the start of the mapping.
-// @param symbol_set_id if the profile was offline symbolized, the offline
-//        symbol information of this frame.
-//        {@joinable stack_profile_symbol.symbol_set_id}
-// @tablegroup Callstack profilers
-#define PERFETTO_TP_STACK_PROFILE_FRAME_DEF(NAME, PARENT, C) \
-  NAME(StackProfileFrameTable, "stack_profile_frame")        \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                          \
-  C(StringPool::Id, name)                                    \
-  C(StackProfileMappingTable::Id, mapping)                   \
-  C(int64_t, rel_pc)                                         \
-  C(base::Optional<uint32_t>, symbol_set_id)                 \
-  C(base::Optional<StringPool::Id>, deobfuscated_name)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_STACK_PROFILE_FRAME_DEF);
-
 // A callsite. This is a list of frames that were on the stack.
 // This is generated by the stack profilers: heapprofd and traced_perf.
 // @param depth distance from the bottom-most frame of the callstack.
@@ -136,264 +34,9 @@
   NAME(StackProfileCallsiteTable, "stack_profile_callsite")     \
   PERFETTO_TP_ROOT_TABLE(PARENT, C)                             \
   C(uint32_t, depth)                                            \
-  C(base::Optional<StackProfileCallsiteTable::Id>, parent_id)   \
+  C(std::optional<StackProfileCallsiteTable::Id>, parent_id)    \
   C(StackProfileFrameTable::Id, frame_id)
 
-PERFETTO_TP_TABLE(PERFETTO_TP_STACK_PROFILE_CALLSITE_DEF);
-
-// TODO(rsavitski): rethink what to do with the root table now that only chrome
-// callstacks use it.
-
-// Root table for timestamped stack samples.
-// @param ts timestamp of the sample.
-// @param callsite_id unwound callstack.
-// @tablegroup Callstack profilers
-#define PERFETTO_TP_STACK_SAMPLE_DEF(NAME, PARENT, C) \
-  NAME(StackSampleTable, "stack_sample")              \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                   \
-  C(int64_t, ts, Column::Flag::kSorted)               \
-  C(StackProfileCallsiteTable::Id, callsite_id)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_STACK_SAMPLE_DEF);
-
-// Samples from the Chromium stack sampler.
-// @param utid thread that was active when the sample was taken.
-// @tablegroup Callstack profilers
-#define PERFETTO_TP_CPU_PROFILE_STACK_SAMPLE_DEF(NAME, PARENT, C) \
-  NAME(CpuProfileStackSampleTable, "cpu_profile_stack_sample")    \
-  PARENT(PERFETTO_TP_STACK_SAMPLE_DEF, C)                         \
-  C(uint32_t, utid)                                               \
-  C(int32_t, process_priority)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_CPU_PROFILE_STACK_SAMPLE_DEF);
-
-// Samples from the traced_perf profiler.
-//
-// @param ts timestamp of the sample.
-// @param utid sampled thread. {@joinable thread.utid}.
-// @param cpu the core the sampled thread was running on.
-// @param cpu_mode execution state (userspace/kernelspace) of the sampled
-//        thread.
-// @param callsite_id if set, unwound callstack of the sampled thread.
-// @param unwind_error if set, indicates that the unwinding for this sample
-//        encountered an error. Such samples still reference the best-effort
-//        result via the callsite_id (with a synthetic error frame at the point
-//        where unwinding stopped).
-// @param perf_session_id distinguishes samples from different profiling
-//        streams (i.e. multiple data sources).
-//        {@joinable perf_counter_track.perf_session_id}
-// @tablegroup Callstack profilers
-#define PERFETTO_TP_PERF_SAMPLE_DEF(NAME, PARENT, C)            \
-  NAME(PerfSampleTable, "perf_sample")                          \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                             \
-  C(int64_t, ts, Column::Flag::kSorted)                         \
-  C(uint32_t, utid)                                             \
-  C(uint32_t, cpu)                                              \
-  C(StringPool::Id, cpu_mode)                                   \
-  C(base::Optional<StackProfileCallsiteTable::Id>, callsite_id) \
-  C(base::Optional<StringPool::Id>, unwind_error)               \
-  C(uint32_t, perf_session_id)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_PERF_SAMPLE_DEF);
-
-// Symbolization data for a frame. Rows with the same symbol_set_id describe
-// one callframe, with the most-inlined symbol having id == symbol_set_id.
-//
-// For instance, if the function foo has an inlined call to the function bar,
-// which has an inlined call to baz, the stack_profile_symbol table would look
-// like this.
-//
-// ```
-// |id|symbol_set_id|name         |source_file|line_number|
-// |--|-------------|-------------|-----------|-----------|
-// |1 |      1      |baz          |foo.cc     | 36        |
-// |2 |      1      |bar          |foo.cc     | 30        |
-// |3 |      1      |foo          |foo.cc     | 60        |
-// ```
-// @param name name of the function.
-// @param source_file name of the source file containing the function.
-// @param line_number line number of the frame in the source file. This is the
-// exact line for the corresponding program counter, not the beginning of the
-// function.
-// @tablegroup Callstack profilers
-#define PERFETTO_TP_SYMBOL_DEF(NAME, PARENT, C)                            \
-  NAME(SymbolTable, "stack_profile_symbol")                                \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                                        \
-  C(uint32_t, symbol_set_id, Column::Flag::kSorted | Column::Flag::kSetId) \
-  C(StringPool::Id, name)                                                  \
-  C(StringPool::Id, source_file)                                           \
-  C(uint32_t, line_number)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_SYMBOL_DEF);
-
-// Allocations that happened at a callsite.
-//
-//
-// NOTE: this table is not sorted by timestamp intentionanlly - see b/193757386
-// for details.
-// TODO(b/193757386): readd the sorted flag once this bug is fixed.
-//
-// This is generated by heapprofd.
-// @param ts the timestamp the allocations happened at. heapprofd batches
-// allocations and frees, and all data from a dump will have the same
-// timestamp.
-// @param upid the UniquePID of the allocating process.
-//        {@joinable process.upid}
-// @param callsite_id the callsite the allocation happened at.
-// @param count if positive: number of allocations that happened at this
-// callsite. if negative: number of allocations that happened at this callsite
-// that were freed.
-// @param size if positive: size of allocations that happened at this
-// callsite. if negative: size of allocations that happened at this callsite
-// that were freed.
-// @tablegroup Callstack profilers
-#define PERFETTO_TP_HEAP_PROFILE_ALLOCATION_DEF(NAME, PARENT, C) \
-  NAME(HeapProfileAllocationTable, "heap_profile_allocation")    \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                              \
-  C(int64_t, ts)                                                 \
-  C(uint32_t, upid)                                              \
-  C(StringPool::Id, heap_name)                                   \
-  C(StackProfileCallsiteTable::Id, callsite_id)                  \
-  C(int64_t, count)                                              \
-  C(int64_t, size)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_HEAP_PROFILE_ALLOCATION_DEF);
-
-// Table used to render flamegraphs. This gives cumulative sizes of nodes in
-// the flamegraph.
-//
-// WARNING: This is experimental and the API is subject to change.
-// @tablegroup Callstack profilers
-#define PERFETTO_TP_EXPERIMENTAL_FLAMEGRAPH_NODES(NAME, PARENT, C)        \
-  NAME(ExperimentalFlamegraphNodesTable, "experimental_flamegraph_nodes") \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                                       \
-  C(int64_t, ts, Column::Flag::kSorted | Column::Flag::kHidden)           \
-  C(uint32_t, upid, Column::Flag::kHidden)                                \
-  C(StringPool::Id, profile_type, Column::Flag::kHidden)                  \
-  C(StringPool::Id, focus_str, Column::Flag::kHidden)                     \
-  C(uint32_t, depth)                                                      \
-  C(StringPool::Id, name)                                                 \
-  C(StringPool::Id, map_name)                                             \
-  C(int64_t, count)                                                       \
-  C(int64_t, cumulative_count)                                            \
-  C(int64_t, size)                                                        \
-  C(int64_t, cumulative_size)                                             \
-  C(int64_t, alloc_count)                                                 \
-  C(int64_t, cumulative_alloc_count)                                      \
-  C(int64_t, alloc_size)                                                  \
-  C(int64_t, cumulative_alloc_size)                                       \
-  C(base::Optional<ExperimentalFlamegraphNodesTable::Id>, parent_id)      \
-  C(base::Optional<StringPool::Id>, source_file)                          \
-  C(base::Optional<uint32_t>, line_number)                                \
-  C(base::Optional<StringPool::Id>, upid_group)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_EXPERIMENTAL_FLAMEGRAPH_NODES);
-
-// @param name (potentially obfuscated) name of the class.
-// @param deobfuscated_name if class name was obfuscated and deobfuscation map
-// for it provided, the deobfuscated name.
-// @param location the APK / Dex / JAR file the class is contained in.
-// @tablegroup ART Heap Graphs
-//
-// classloader_id should really be HeapGraphObject::id, but that would
-// create a loop, which is currently not possible.
-// TODO(lalitm): resolve this
-#define PERFETTO_TP_HEAP_GRAPH_CLASS_DEF(NAME, PARENT, C)   \
-  NAME(HeapGraphClassTable, "heap_graph_class")             \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                         \
-  C(StringPool::Id, name)                                   \
-  C(base::Optional<StringPool::Id>, deobfuscated_name)      \
-  C(base::Optional<StringPool::Id>, location)               \
-  C(base::Optional<HeapGraphClassTable::Id>, superclass_id) \
-  C(base::Optional<uint32_t>, classloader_id)               \
-  C(StringPool::Id, kind)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_HEAP_GRAPH_CLASS_DEF);
-
-// The objects on the Dalvik heap.
-//
-// All rows with the same (upid, graph_sample_ts) are one dump.
-// @param upid UniquePid of the target {@joinable process.upid}.
-// @param graph_sample_ts timestamp this dump was taken at.
-// @param self_size size this object uses on the Java Heap.
-// @param native_size approximate amount of native memory used by this object,
-//        as reported by libcore.util.NativeAllocationRegistry.size.
-// @param reference_set_id join key with heap_graph_reference containing all
-//        objects referred in this object's fields.
-//        {@joinable heap_graph_reference.reference_set_id}
-// @param reachable bool whether this object is reachable from a GC root. If
-// false, this object is uncollected garbage.
-// @param type_id class this object is an instance of.
-// @param root_type if not NULL, this object is a GC root.
-// @tablegroup ART Heap Graphs
-#define PERFETTO_TP_HEAP_GRAPH_OBJECT_DEF(NAME, PARENT, C)            \
-  NAME(HeapGraphObjectTable, "heap_graph_object")                     \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                                   \
-  C(uint32_t, upid)                                                   \
-  C(int64_t, graph_sample_ts)                                         \
-  C(int64_t, self_size)                                               \
-  C(int64_t, native_size)                                             \
-  C(base::Optional<uint32_t>, reference_set_id, Column::Flag::kDense) \
-  C(int32_t, reachable)                                               \
-  C(HeapGraphClassTable::Id, type_id)                                 \
-  C(base::Optional<StringPool::Id>, root_type)                        \
-  C(int32_t, root_distance, Column::Flag::kHidden)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_HEAP_GRAPH_OBJECT_DEF);
-
-// Many-to-many mapping between heap_graph_object.
-//
-// This associates the object with given reference_set_id with the objects
-// that are referred to by its fields.
-// @param reference_set_id join key to heap_graph_object.
-// @param owner_id id of object that has this reference_set_id.
-// @param owned_id id of object that is referred to.
-// @param field_name the field that refers to the object. E.g. Foo.name.
-// @param field_type_name the static type of the field. E.g. java.lang.String.
-// @param deobfuscated_field_name if field_name was obfuscated and a
-// deobfuscation mapping was provided for it, the deobfuscated name.
-// @tablegroup ART Heap Graphs
-#define PERFETTO_TP_HEAP_GRAPH_REFERENCE_DEF(NAME, PARENT, C)                 \
-  NAME(HeapGraphReferenceTable, "heap_graph_reference")                       \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                                           \
-  C(uint32_t, reference_set_id, Column::Flag::kSorted | Column::Flag::kSetId) \
-  C(HeapGraphObjectTable::Id, owner_id)                                       \
-  C(base::Optional<HeapGraphObjectTable::Id>, owned_id)                       \
-  C(StringPool::Id, field_name)                                               \
-  C(StringPool::Id, field_type_name)                                          \
-  C(base::Optional<StringPool::Id>, deobfuscated_field_name)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_HEAP_GRAPH_REFERENCE_DEF);
-
-// @param arg_set_id {@joinable args.arg_set_id}
-#define PERFETTO_TP_VULKAN_MEMORY_ALLOCATIONS_DEF(NAME, PARENT, C) \
-  NAME(VulkanMemoryAllocationsTable, "vulkan_memory_allocations")  \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                                \
-  C(StringPool::Id, source)                                        \
-  C(StringPool::Id, operation)                                     \
-  C(int64_t, timestamp)                                            \
-  C(base::Optional<uint32_t>, upid)                                \
-  C(base::Optional<int64_t>, device)                               \
-  C(base::Optional<int64_t>, device_memory)                        \
-  C(base::Optional<uint32_t>, memory_type)                         \
-  C(base::Optional<uint32_t>, heap)                                \
-  C(base::Optional<StringPool::Id>, function_name)                 \
-  C(base::Optional<int64_t>, object_handle)                        \
-  C(base::Optional<int64_t>, memory_address)                       \
-  C(base::Optional<int64_t>, memory_size)                          \
-  C(StringPool::Id, scope)                                         \
-  C(base::Optional<uint32_t>, arg_set_id)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_VULKAN_MEMORY_ALLOCATIONS_DEF);
-
-#define PERFETTO_TP_GPU_COUNTER_GROUP_DEF(NAME, PARENT, C) \
-  NAME(GpuCounterGroupTable, "gpu_counter_group")          \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                        \
-  C(int32_t, group_id)                                     \
-  C(TrackTable::Id, track_id)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_GPU_COUNTER_GROUP_DEF);
-
 }  // namespace tables
 }  // namespace trace_processor
 }  // namespace perfetto
diff --git a/src/trace_processor/tables/profiler_tables.py b/src/trace_processor/tables/profiler_tables.py
new file mode 100644
index 0000000..d428009
--- /dev/null
+++ b/src/trace_processor/tables/profiler_tables.py
@@ -0,0 +1,611 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Contains tables for relevant for TODO."""
+
+from python.generators.trace_processor_table.public import Column as C
+from python.generators.trace_processor_table.public import ColumnFlag
+from python.generators.trace_processor_table.public import CppInt32
+from python.generators.trace_processor_table.public import CppInt64
+from python.generators.trace_processor_table.public import CppOptional
+from python.generators.trace_processor_table.public import CppSelfTableId
+from python.generators.trace_processor_table.public import CppString
+from python.generators.trace_processor_table.public import Table
+from python.generators.trace_processor_table.public import TableDoc
+from python.generators.trace_processor_table.public import CppTableId
+from python.generators.trace_processor_table.public import CppUint32
+
+from src.trace_processor.tables.track_tables import TRACK_TABLE
+
+PROFILER_SMAPS_TABLE = Table(
+    class_name='ProfilerSmapsTable',
+    sql_name='profiler_smaps',
+    columns=[
+        C('upid', CppUint32()),
+        C('ts', CppInt64()),
+        C('path', CppString()),
+        C('size_kb', CppInt64()),
+        C('private_dirty_kb', CppInt64()),
+        C('swap_kb', CppInt64()),
+        C('file_name', CppString()),
+        C('start_address', CppInt64()),
+        C('module_timestamp', CppInt64()),
+        C('module_debugid', CppString()),
+        C('module_debug_path', CppString()),
+        C('protection_flags', CppInt64()),
+        C('private_clean_resident_kb', CppInt64()),
+        C('shared_dirty_resident_kb', CppInt64()),
+        C('shared_clean_resident_kb', CppInt64()),
+        C('locked_kb', CppInt64()),
+        C('proportional_resident_kb', CppInt64()),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          The profiler smaps contains the memory stats for virtual memory ranges
+captured by the [heap profiler](/docs/data-sources/native-heap-profiler.md).
+        ''',
+        group='Callstack profilers',
+        columns={
+            'upid':
+                '''The UniquePID of the process.''',
+            'ts':
+                '''Timestamp of the snapshot. Multiple rows will have the same
+timestamp.''',
+            'path':
+                '''The mmaped file, as per /proc/pid/smaps.''',
+            'size_kb':
+                '''Total size of the mapping.''',
+            'private_dirty_kb':
+                '''KB of this mapping that are private dirty  RSS.''',
+            'swap_kb':
+                '''KB of this mapping that are in swap.''',
+            'file_name':
+                '''''',
+            'start_address':
+                '''''',
+            'module_timestamp':
+                '''''',
+            'module_debugid':
+                '''''',
+            'module_debug_path':
+                '''''',
+            'protection_flags':
+                '''''',
+            'private_clean_resident_kb':
+                '''''',
+            'shared_dirty_resident_kb':
+                '''''',
+            'shared_clean_resident_kb':
+                '''''',
+            'locked_kb':
+                '''''',
+            'proportional_resident_kb':
+                ''''''
+        }))
+
+PACKAGE_LIST_TABLE = Table(
+    class_name='PackageListTable',
+    sql_name='package_list',
+    columns=[
+        C('package_name', CppString()),
+        C('uid', CppInt64()),
+        C('debuggable', CppInt32()),
+        C('profileable_from_shell', CppInt32()),
+        C('version_code', CppInt64()),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          Metadata about packages installed on the system.
+This is generated by the packages_list data-source.
+        ''',
+        group='Misc',
+        columns={
+            'package_name':
+                '''name of the package, e.g. com.google.android.gm.''',
+            'uid':
+                '''UID processes of this package run as.''',
+            'debuggable':
+                '''bool whether this app is debuggable.''',
+            'profileable_from_shell':
+                '''bool whether this app is profileable.''',
+            'version_code':
+                '''versionCode from the APK.'''
+        }))
+
+STACK_PROFILE_MAPPING_TABLE = Table(
+    class_name='StackProfileMappingTable',
+    sql_name='stack_profile_mapping',
+    columns=[
+        C('build_id', CppString()),
+        C('exact_offset', CppInt64()),
+        C('start_offset', CppInt64()),
+        C('start', CppInt64()),
+        C('end', CppInt64()),
+        C('load_bias', CppInt64()),
+        C('name', CppString()),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          A mapping (binary / library) in a process.
+This is generated by the stack profilers: heapprofd and traced_perf.
+        ''',
+        group='Callstack profilers',
+        columns={
+            'build_id': '''hex-encoded Build ID of the binary / library.''',
+            'start': '''start of the mapping in the process' address space.''',
+            'end': '''end of the mapping in the process' address space.''',
+            'name': '''filename of the binary / library.''',
+            'exact_offset': '''''',
+            'start_offset': '''''',
+            'load_bias': ''''''
+        }))
+
+STACK_PROFILE_FRAME_TABLE = Table(
+    class_name='StackProfileFrameTable',
+    sql_name='stack_profile_frame',
+    columns=[
+        C('name', CppString()),
+        C('mapping', CppTableId(STACK_PROFILE_MAPPING_TABLE)),
+        C('rel_pc', CppInt64()),
+        C('symbol_set_id', CppOptional(CppUint32())),
+        C('deobfuscated_name', CppOptional(CppString())),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          A frame on the callstack. This is a location in a program.
+This is generated by the stack profilers: heapprofd and traced_perf.
+        ''',
+        group='Callstack profilers',
+        columns={
+            'name':
+                '''name of the function this location is in.''',
+            'mapping':
+                '''the mapping (library / binary) this location is in.''',
+            'rel_pc':
+                '''the program counter relative to the start of the mapping.''',
+            'symbol_set_id':
+                '''if the profile was offline symbolized, the offline
+symbol information of this frame.''',
+            'deobfuscated_name':
+                ''''''
+        }))
+
+STACK_PROFILE_CALLSITE_TABLE = Table(
+    class_name='StackProfileCallsiteTable',
+    sql_name='stack_profile_callsite',
+    columns=[
+        C('depth', CppUint32()),
+        C('parent_id', CppOptional(CppSelfTableId())),
+        C('frame_id', CppTableId(STACK_PROFILE_FRAME_TABLE)),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          A callsite. This is a list of frames that were on the stack.
+This is generated by the stack profilers: heapprofd and traced_perf.
+        ''',
+        group='Callstack profilers',
+        columns={
+            'depth':
+                '''distance from the bottom-most frame of the callstack.''',
+            'parent_id':
+                '''parent frame on the callstack. NULL for the bottom-most.''',
+            'frame_id':
+                '''frame at this position in the callstack.'''
+        }))
+
+STACK_SAMPLE_TABLE = Table(
+    class_name='StackSampleTable',
+    sql_name='stack_sample',
+    columns=[
+        C('ts', CppInt64(), flags=ColumnFlag.SORTED),
+        C('callsite_id', CppTableId(STACK_PROFILE_CALLSITE_TABLE)),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          Root table for timestamped stack samples.
+        ''',
+        group='Callstack profilers',
+        columns={
+            'ts': '''timestamp of the sample.''',
+            'callsite_id': '''unwound callstack.'''
+        }))
+
+CPU_PROFILE_STACK_SAMPLE_TABLE = Table(
+    class_name='CpuProfileStackSampleTable',
+    sql_name='cpu_profile_stack_sample',
+    columns=[
+        C('utid', CppUint32()),
+        C('process_priority', CppInt32()),
+    ],
+    parent=STACK_SAMPLE_TABLE,
+    tabledoc=TableDoc(
+        doc='''
+          Samples from the Chromium stack sampler.
+        ''',
+        group='Callstack profilers',
+        columns={
+            'utid': '''thread that was active when the sample was taken.''',
+            'process_priority': ''''''
+        }))
+
+PERF_SAMPLE_TABLE = Table(
+    class_name='PerfSampleTable',
+    sql_name='perf_sample',
+    columns=[
+        C('ts', CppInt64(), flags=ColumnFlag.SORTED),
+        C('utid', CppUint32()),
+        C('cpu', CppUint32()),
+        C('cpu_mode', CppString()),
+        C('callsite_id', CppOptional(CppTableId(STACK_PROFILE_CALLSITE_TABLE))),
+        C('unwind_error', CppOptional(CppString())),
+        C('perf_session_id', CppUint32()),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          Samples from the traced_perf profiler.
+        ''',
+        group='Callstack profilers',
+        columns={
+            'ts':
+                '''timestamp of the sample.''',
+            'utid':
+                '''sampled thread..''',
+            'cpu':
+                '''the core the sampled thread was running on.''',
+            'cpu_mode':
+                '''execution state (userspace/kernelspace) of the sampled
+thread.''',
+            'callsite_id':
+                '''if set, unwound callstack of the sampled thread.''',
+            'unwind_error':
+                '''if set, indicates that the unwinding for this sample
+encountered an error. Such samples still reference the best-effort
+result via the callsite_id (with a synthetic error frame at the point
+where unwinding stopped).''',
+            'perf_session_id':
+                '''distinguishes samples from different profiling
+streams (i.e. multiple data sources).'''
+        }))
+
+SYMBOL_TABLE = Table(
+    class_name='SymbolTable',
+    sql_name='stack_profile_symbol',
+    columns=[
+        C('symbol_set_id',
+          CppUint32(),
+          flags=ColumnFlag.SORTED | ColumnFlag.SET_ID),
+        C('name', CppString()),
+        C('source_file', CppString()),
+        C('line_number', CppUint32()),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+            Symbolization data for a frame. Rows with the same symbol_set_id
+            describe one callframe, with the most-inlined symbol having
+            id == symbol_set_id.
+
+            For instance, if the function foo has an inlined call to the
+            function bar, which has an inlined call to baz, the
+            stack_profile_symbol table would look like this.
+
+            ```
+            |id|symbol_set_id|name         |source_file|line_number|
+            |--|-------------|-------------|-----------|-----------|
+            |1 |      1      |baz          |foo.cc     | 36        |
+            |2 |      1      |bar          |foo.cc     | 30        |
+            |3 |      1      |foo          |foo.cc     | 60        |
+            ```
+        ''',
+        group='Callstack profilers',
+        columns={
+            'name':
+                '''name of the function.''',
+            'source_file':
+                '''name of the source file containing the function.''',
+            'line_number':
+                '''
+                    line number of the frame in the source file. This is the
+                    exact line for the corresponding program counter, not the
+                    beginning of the function.
+                ''',
+            'symbol_set_id':
+                ''''''
+        }))
+
+HEAP_PROFILE_ALLOCATION_TABLE = Table(
+    class_name='HeapProfileAllocationTable',
+    sql_name='heap_profile_allocation',
+    columns=[
+        C('ts', CppInt64()),
+        C('upid', CppUint32()),
+        C('heap_name', CppString()),
+        C('callsite_id', CppTableId(STACK_PROFILE_CALLSITE_TABLE)),
+        C('count', CppInt64()),
+        C('size', CppInt64()),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          Allocations that happened at a callsite.
+
+
+NOTE: this table is not sorted by timestamp intentionanlly - see b/193757386
+for details.
+TODO(b/193757386): readd the sorted flag once this bug is fixed.
+
+This is generated by heapprofd.
+        ''',
+        group='Callstack profilers',
+        columns={
+            'ts':
+                '''the timestamp the allocations happened at. heapprofd batches
+allocations and frees, and all data from a dump will have the same
+timestamp.''',
+            'upid':
+                '''the UniquePID of the allocating process.''',
+            'callsite_id':
+                '''the callsite the allocation happened at.''',
+            'count':
+                '''if positive: number of allocations that happened at this
+callsite. if negative: number of allocations that happened at this callsite
+that were freed.''',
+            'size':
+                '''if positive: size of allocations that happened at this
+callsite. if negative: size of allocations that happened at this callsite
+that were freed.''',
+            'heap_name':
+                ''''''
+        }))
+
+EXPERIMENTAL_FLAMEGRAPH_NODES_TABLE = Table(
+    class_name='ExperimentalFlamegraphNodesTable',
+    sql_name='experimental_flamegraph_nodes',
+    columns=[
+        C('ts', CppInt64(), flags=ColumnFlag.SORTED | ColumnFlag.HIDDEN),
+        C('upid', CppUint32(), flags=ColumnFlag.HIDDEN),
+        C('profile_type', CppString(), flags=ColumnFlag.HIDDEN),
+        C('focus_str', CppString(), flags=ColumnFlag.HIDDEN),
+        C('depth', CppUint32()),
+        C('name', CppString()),
+        C('map_name', CppString()),
+        C('count', CppInt64()),
+        C('cumulative_count', CppInt64()),
+        C('size', CppInt64()),
+        C('cumulative_size', CppInt64()),
+        C('alloc_count', CppInt64()),
+        C('cumulative_alloc_count', CppInt64()),
+        C('alloc_size', CppInt64()),
+        C('cumulative_alloc_size', CppInt64()),
+        C('parent_id', CppOptional(CppSelfTableId())),
+        C('source_file', CppOptional(CppString())),
+        C('line_number', CppOptional(CppUint32())),
+        C('upid_group', CppOptional(CppString())),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+            Table used to render flamegraphs. This gives cumulative sizes of
+            nodes in the flamegraph.
+
+            WARNING: This is experimental and the API is subject to change.
+        ''',
+        group='Callstack profilers',
+        columns={
+            'ts': '''''',
+            'upid': '''''',
+            'profile_type': '''''',
+            'focus_str': '''''',
+            'depth': '''''',
+            'name': '''''',
+            'map_name': '''''',
+            'count': '''''',
+            'cumulative_count': '''''',
+            'size': '''''',
+            'cumulative_size': '''''',
+            'alloc_count': '''''',
+            'cumulative_alloc_count': '''''',
+            'alloc_size': '''''',
+            'cumulative_alloc_size': '''''',
+            'parent_id': '''''',
+            'source_file': '''''',
+            'line_number': '''''',
+            'upid_group': ''''''
+        }))
+
+HEAP_GRAPH_CLASS_TABLE = Table(
+    class_name='HeapGraphClassTable',
+    sql_name='heap_graph_class',
+    columns=[
+        C('name', CppString()),
+        C('deobfuscated_name', CppOptional(CppString())),
+        C('location', CppOptional(CppString())),
+        C('superclass_id', CppOptional(CppSelfTableId())),
+        C('classloader_id', CppOptional(CppUint32())),
+        C('kind', CppString()),
+    ],
+    tabledoc=TableDoc(
+        doc='''''',
+        group='ART Heap Graphs',
+        columns={
+            'name':
+                '''(potentially obfuscated) name of the class.''',
+            'deobfuscated_name':
+                '''if class name was obfuscated and deobfuscation map
+for it provided, the deobfuscated name.''',
+            'location':
+                '''the APK / Dex / JAR file the class is contained in.
+
+classloader_id should really be HeapGraphObject::id, but that would
+create a loop, which is currently not possible.
+TODO(lalitm): resolve this''',
+            'superclass_id':
+                '''''',
+            'classloader_id':
+                '''''',
+            'kind':
+                ''''''
+        }))
+
+HEAP_GRAPH_OBJECT_TABLE = Table(
+    class_name='HeapGraphObjectTable',
+    sql_name='heap_graph_object',
+    columns=[
+        C('upid', CppUint32()),
+        C('graph_sample_ts', CppInt64()),
+        C('self_size', CppInt64()),
+        C('native_size', CppInt64()),
+        C('reference_set_id', CppOptional(CppUint32()), flags=ColumnFlag.DENSE),
+        C('reachable', CppInt32()),
+        C('type_id', CppTableId(HEAP_GRAPH_CLASS_TABLE)),
+        C('root_type', CppOptional(CppString())),
+        C('root_distance', CppInt32(), flags=ColumnFlag.HIDDEN),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          The objects on the Dalvik heap.
+
+All rows with the same (upid, graph_sample_ts) are one dump.
+        ''',
+        group='ART Heap Graphs',
+        columns={
+            'upid':
+                '''UniquePid of the target.''',
+            'graph_sample_ts':
+                '''timestamp this dump was taken at.''',
+            'self_size':
+                '''size this object uses on the Java Heap.''',
+            'native_size':
+                '''approximate amount of native memory used by this object,
+as reported by libcore.util.NativeAllocationRegistry.size.''',
+            'reference_set_id':
+                '''join key with heap_graph_reference containing all
+objects referred in this object's fields.''',
+            'reachable':
+                '''bool whether this object is reachable from a GC root. If
+false, this object is uncollected garbage.''',
+            'type_id':
+                '''class this object is an instance of.''',
+            'root_type':
+                '''if not NULL, this object is a GC root.''',
+            'root_distance':
+                ''''''
+        }))
+
+HEAP_GRAPH_REFERENCE_TABLE = Table(
+    class_name='HeapGraphReferenceTable',
+    sql_name='heap_graph_reference',
+    columns=[
+        C('reference_set_id',
+          CppUint32(),
+          flags=ColumnFlag.SORTED | ColumnFlag.SET_ID),
+        C('owner_id', CppTableId(HEAP_GRAPH_OBJECT_TABLE)),
+        C('owned_id', CppOptional(CppTableId(HEAP_GRAPH_OBJECT_TABLE))),
+        C('field_name', CppString()),
+        C('field_type_name', CppString()),
+        C('deobfuscated_field_name', CppOptional(CppString())),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          Many-to-many mapping between heap_graph_object.
+
+This associates the object with given reference_set_id with the objects
+that are referred to by its fields.
+        ''',
+        group='ART Heap Graphs',
+        columns={
+            'reference_set_id':
+                '''join key to heap_graph_object.''',
+            'owner_id':
+                '''id of object that has this reference_set_id.''',
+            'owned_id':
+                '''id of object that is referred to.''',
+            'field_name':
+                '''the field that refers to the object. E.g. Foo.name.''',
+            'field_type_name':
+                '''the static type of the field. E.g. java.lang.String.''',
+            'deobfuscated_field_name':
+                '''if field_name was obfuscated and a
+deobfuscation mapping was provided for it, the deobfuscated name.'''
+        }))
+
+VULKAN_MEMORY_ALLOCATIONS_TABLE = Table(
+    class_name='VulkanMemoryAllocationsTable',
+    sql_name='vulkan_memory_allocations',
+    columns=[
+        C('arg_set_id', CppOptional(CppUint32())),
+        C('source', CppString()),
+        C('operation', CppString()),
+        C('timestamp', CppInt64()),
+        C('upid', CppOptional(CppUint32())),
+        C('device', CppOptional(CppInt64())),
+        C('device_memory', CppOptional(CppInt64())),
+        C('memory_type', CppOptional(CppUint32())),
+        C('heap', CppOptional(CppUint32())),
+        C('function_name', CppOptional(CppString())),
+        C('object_handle', CppOptional(CppInt64())),
+        C('memory_address', CppOptional(CppInt64())),
+        C('memory_size', CppOptional(CppInt64())),
+        C('scope', CppString()),
+    ],
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Misc',
+        columns={
+            'arg_set_id': '''''',
+            'source': '''''',
+            'operation': '''''',
+            'timestamp': '''''',
+            'upid': '''''',
+            'device': '''''',
+            'device_memory': '''''',
+            'memory_type': '''''',
+            'heap': '''''',
+            'function_name': '''''',
+            'object_handle': '''''',
+            'memory_address': '''''',
+            'memory_size': '''''',
+            'scope': ''''''
+        }))
+
+GPU_COUNTER_GROUP_TABLE = Table(
+    class_name='GpuCounterGroupTable',
+    sql_name='gpu_counter_group',
+    columns=[
+        C('group_id', CppInt32()),
+        C('track_id', CppTableId(TRACK_TABLE)),
+    ],
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Misc',
+        columns={
+            'group_id': '''''',
+            'track_id': ''''''
+        }))
+
+# Keep this list sorted.
+ALL_TABLES = [
+    CPU_PROFILE_STACK_SAMPLE_TABLE,
+    EXPERIMENTAL_FLAMEGRAPH_NODES_TABLE,
+    GPU_COUNTER_GROUP_TABLE,
+    HEAP_GRAPH_CLASS_TABLE,
+    HEAP_GRAPH_OBJECT_TABLE,
+    HEAP_GRAPH_REFERENCE_TABLE,
+    HEAP_PROFILE_ALLOCATION_TABLE,
+    PACKAGE_LIST_TABLE,
+    PERF_SAMPLE_TABLE,
+    PROFILER_SMAPS_TABLE,
+    STACK_PROFILE_CALLSITE_TABLE,
+    STACK_PROFILE_FRAME_TABLE,
+    STACK_PROFILE_MAPPING_TABLE,
+    STACK_SAMPLE_TABLE,
+    SYMBOL_TABLE,
+    VULKAN_MEMORY_ALLOCATIONS_TABLE,
+]
diff --git a/src/trace_processor/tables/slice_tables.h b/src/trace_processor/tables/slice_tables.h
index c66cba8..e33ae19 100644
--- a/src/trace_processor/tables/slice_tables.h
+++ b/src/trace_processor/tables/slice_tables.h
@@ -24,54 +24,24 @@
 namespace trace_processor {
 namespace tables {
 
-// @name slice
-// @tablegroup Events
-// @param ts timestamp of the start of the slice (in nanoseconds)
-// @param dur duration of the slice (in nanoseconds)
-// @param arg_set_id {@joinable args.arg_set_id}
-// @param thread_instruction_count The value of the CPU instruction counter at
-// the start of the slice.
-// @param thread_instruction_delta The change in value from
-// @param thread_instruction_count to the end of the slice.
-#define PERFETTO_TP_SLICE_TABLE_DEF(NAME, PARENT, C)   \
-  NAME(SliceTable, "internal_slice")                   \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                    \
-  C(int64_t, ts, Column::Flag::kSorted)                \
-  C(int64_t, dur)                                      \
-  C(TrackTable::Id, track_id)                          \
-  C(base::Optional<StringPool::Id>, category)          \
-  C(base::Optional<StringPool::Id>, name)              \
-  C(uint32_t, depth)                                   \
-  C(int64_t, stack_id)                                 \
-  C(int64_t, parent_stack_id)                          \
-  C(base::Optional<SliceTable::Id>, parent_id)         \
-  C(uint32_t, arg_set_id)                              \
-  C(base::Optional<int64_t>, thread_ts)                \
-  C(base::Optional<int64_t>, thread_dur)               \
-  C(base::Optional<int64_t>, thread_instruction_count) \
-  C(base::Optional<int64_t>, thread_instruction_delta)
+#define PERFETTO_TP_SLICE_TABLE_DEF(NAME, PARENT, C)  \
+  NAME(SliceTable, "internal_slice")                  \
+  PERFETTO_TP_ROOT_TABLE(PARENT, C)                   \
+  C(int64_t, ts, Column::Flag::kSorted)               \
+  C(int64_t, dur)                                     \
+  C(TrackTable::Id, track_id)                         \
+  C(std::optional<StringPool::Id>, category)          \
+  C(std::optional<StringPool::Id>, name)              \
+  C(uint32_t, depth)                                  \
+  C(int64_t, stack_id)                                \
+  C(int64_t, parent_stack_id)                         \
+  C(std::optional<SliceTable::Id>, parent_id)         \
+  C(uint32_t, arg_set_id)                             \
+  C(std::optional<int64_t>, thread_ts)                \
+  C(std::optional<int64_t>, thread_dur)               \
+  C(std::optional<int64_t>, thread_instruction_count) \
+  C(std::optional<int64_t>, thread_instruction_delta)
 
-PERFETTO_TP_TABLE(PERFETTO_TP_SLICE_TABLE_DEF);
-
-// @name sched_slice
-//   This table holds slices with kernel thread scheduling information.
-//   These slices are collected when the Linux "ftrace" data source is
-//   used with the "sched/switch" and "sched/wakeup*" events enabled.
-// @tablegroup Events
-// @param id The row id for the table row.
-// @param type This field always contains the string 'sched_slice'.
-// @param ts The timestamp at the start of the slice (in nanoseconds).
-// @param dur The duration of the slice (in nanoseconds).
-// @param utid The thread's unique id in the trace. {@joinable thread.utid}.
-// @param cpu The CPU that the slice executed on.
-// @param end_state A string representing the scheduling state of the
-//   kernel thread at the end of the slice.  The individual characters in
-//   the string mean the following: R (runnable), S (awaiting a wakeup),
-//   D (in an uninterruptible sleep), T (suspended), t (being traced),
-//   X (exiting), P (parked), W (waking), I (idle), N (not contributing
-//   to the load average), K (wakeable on fatal signals) and
-//   Z (zombie, awaiting cleanup).
-// @param priority The kernel priority that the thread ran at.
 #define PERFETTO_TP_SCHED_SLICE_TABLE_DEF(NAME, PARENT, C) \
   NAME(SchedSliceTable, "sched_slice")                     \
   PERFETTO_TP_ROOT_TABLE(PARENT, C)                        \
@@ -82,95 +52,6 @@
   C(StringPool::Id, end_state)                             \
   C(int32_t, priority)
 
-PERFETTO_TP_TABLE(PERFETTO_TP_SCHED_SLICE_TABLE_DEF);
-
-// @tablegroup Events
-// @param utid {@joinable thread.utid}
-#define PERFETTO_TP_THREAD_STATE_TABLE_DEF(NAME, PARENT, C) \
-  NAME(ThreadStateTable, "thread_state")                    \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                         \
-  C(int64_t, ts)                                            \
-  C(int64_t, dur)                                           \
-  C(base::Optional<uint32_t>, cpu)                          \
-  C(uint32_t, utid)                                         \
-  C(StringPool::Id, state)                                  \
-  C(base::Optional<uint32_t>, io_wait)                      \
-  C(base::Optional<StringPool::Id>, blocked_function)       \
-  C(base::Optional<uint32_t>, waker_utid)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_THREAD_STATE_TABLE_DEF);
-
-// @tablegroup Events
-#define PERFETTO_TP_GPU_SLICES_DEF(NAME, PARENT, C) \
-  NAME(GpuSliceTable, "gpu_slice")                  \
-  PARENT(PERFETTO_TP_SLICE_TABLE_DEF, C)            \
-  C(base::Optional<int64_t>, context_id)            \
-  C(base::Optional<int64_t>, render_target)         \
-  C(StringPool::Id, render_target_name)             \
-  C(base::Optional<int64_t>, render_pass)           \
-  C(StringPool::Id, render_pass_name)               \
-  C(base::Optional<int64_t>, command_buffer)        \
-  C(StringPool::Id, command_buffer_name)            \
-  C(base::Optional<uint32_t>, frame_id)             \
-  C(base::Optional<uint32_t>, submission_id)        \
-  C(base::Optional<int64_t>, hw_queue_id)           \
-  C(StringPool::Id, render_subpasses)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_GPU_SLICES_DEF);
-
-// @tablegroup Events
-#define PERFETTO_TP_GRAPHICS_FRAME_SLICES_DEF(NAME, PARENT, C) \
-  NAME(GraphicsFrameSliceTable, "frame_slice")                 \
-  PARENT(PERFETTO_TP_SLICE_TABLE_DEF, C)                       \
-  C(uint32_t, frame_number)                                    \
-  C(StringPool::Id, layer_name)                                \
-  C(int64_t, queue_to_acquire_time)                            \
-  C(int64_t, acquire_to_latch_time)                            \
-  C(int64_t, latch_to_present_time)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_GRAPHICS_FRAME_SLICES_DEF);
-
-#define PERFETTO_TP_EXPECTED_FRAME_TIMELINE_SLICES_DEF(NAME, PARENT, C)  \
-  NAME(ExpectedFrameTimelineSliceTable, "expected_frame_timeline_slice") \
-  PARENT(PERFETTO_TP_SLICE_TABLE_DEF, C)                                 \
-  C(int64_t, display_frame_token)                                        \
-  C(int64_t, surface_frame_token)                                        \
-  C(uint32_t, upid)                                                      \
-  C(StringPool::Id, layer_name)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_EXPECTED_FRAME_TIMELINE_SLICES_DEF);
-
-#define PERFETTO_TP_ACTUAL_FRAME_TIMELINE_SLICES_DEF(NAME, PARENT, C) \
-  NAME(ActualFrameTimelineSliceTable, "actual_frame_timeline_slice")  \
-  PARENT(PERFETTO_TP_SLICE_TABLE_DEF, C)                              \
-  C(int64_t, display_frame_token)                                     \
-  C(int64_t, surface_frame_token)                                     \
-  C(uint32_t, upid)                                                   \
-  C(StringPool::Id, layer_name)                                       \
-  C(StringPool::Id, present_type)                                     \
-  C(int32_t, on_time_finish)                                          \
-  C(int32_t, gpu_composition)                                         \
-  C(StringPool::Id, jank_type)                                        \
-  C(StringPool::Id, prediction_type)                                  \
-  C(StringPool::Id, jank_tag)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_ACTUAL_FRAME_TIMELINE_SLICES_DEF);
-
-#define PERFETTO_TP_EXPERIMENTAL_FLAT_SLICE_TABLE_DEF(NAME, PARENT, C) \
-  NAME(ExperimentalFlatSliceTable, "experimental_flat_slice")          \
-  PERFETTO_TP_ROOT_TABLE(PARENT, C)                                    \
-  C(int64_t, ts)                                                       \
-  C(int64_t, dur)                                                      \
-  C(TrackTable::Id, track_id)                                          \
-  C(base::Optional<StringPool::Id>, category)                          \
-  C(base::Optional<StringPool::Id>, name)                              \
-  C(uint32_t, arg_set_id)                                              \
-  C(base::Optional<SliceTable::Id>, source_id)                         \
-  C(int64_t, start_bound, Column::Flag::kHidden)                       \
-  C(int64_t, end_bound, Column::Flag::kHidden)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_EXPERIMENTAL_FLAT_SLICE_TABLE_DEF);
-
 }  // namespace tables
 }  // namespace trace_processor
 }  // namespace perfetto
diff --git a/src/trace_processor/tables/slice_tables.py b/src/trace_processor/tables/slice_tables.py
new file mode 100644
index 0000000..50b8c3e
--- /dev/null
+++ b/src/trace_processor/tables/slice_tables.py
@@ -0,0 +1,284 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Contains tables for relevant for TODO."""
+
+from python.generators.trace_processor_table.public import Column as C
+from python.generators.trace_processor_table.public import ColumnFlag
+from python.generators.trace_processor_table.public import CppInt32
+from python.generators.trace_processor_table.public import CppInt64
+from python.generators.trace_processor_table.public import CppOptional
+from python.generators.trace_processor_table.public import CppSelfTableId
+from python.generators.trace_processor_table.public import CppString
+from python.generators.trace_processor_table.public import CppTableId
+from python.generators.trace_processor_table.public import CppUint32
+from python.generators.trace_processor_table.public import Table
+from python.generators.trace_processor_table.public import TableDoc
+from python.generators.trace_processor_table.public import WrappingSqlView
+
+from src.trace_processor.tables.track_tables import TRACK_TABLE
+
+SLICE_TABLE = Table(
+    class_name='SliceTable',
+    sql_name='internal_slice',
+    columns=[
+        C('ts', CppInt64(), flags=ColumnFlag.SORTED),
+        C('dur', CppInt64()),
+        C('track_id', CppTableId(TRACK_TABLE)),
+        C('category', CppOptional(CppString())),
+        C('name', CppOptional(CppString())),
+        C('depth', CppUint32()),
+        C('stack_id', CppInt64()),
+        C('parent_stack_id', CppInt64()),
+        C('parent_id', CppOptional(CppSelfTableId())),
+        C('arg_set_id', CppUint32()),
+        C('thread_ts', CppOptional(CppInt64())),
+        C('thread_dur', CppOptional(CppInt64())),
+        C('thread_instruction_count', CppOptional(CppInt64())),
+        C('thread_instruction_delta', CppOptional(CppInt64())),
+    ],
+    wrapping_sql_view=WrappingSqlView('slice'),
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Events',
+        columns={
+            'ts': '''timestamp of the start of the slice (in nanoseconds)''',
+            'dur': '''duration of the slice (in nanoseconds)''',
+            'arg_set_id': '''''',
+            'thread_instruction_count': '''to the end of the slice.''',
+            'thread_instruction_delta': '''The change in value from''',
+            'track_id': '''''',
+            'category': '''''',
+            'name': '''''',
+            'depth': '''''',
+            'stack_id': '''''',
+            'parent_stack_id': '''''',
+            'parent_id': '''''',
+            'thread_ts': '''''',
+            'thread_dur': ''''''
+        }))
+
+SCHED_SLICE_TABLE = Table(
+    class_name='SchedSliceTable',
+    sql_name='sched_slice',
+    columns=[
+        C('ts', CppInt64(), flags=ColumnFlag.SORTED),
+        C('dur', CppInt64()),
+        C('cpu', CppUint32()),
+        C('utid', CppUint32()),
+        C('end_state', CppString()),
+        C('priority', CppInt32()),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          This table holds slices with kernel thread scheduling information.
+These slices are collected when the Linux "ftrace" data source is
+used with the "sched/switch" and "sched/wakeup*" events enabled.
+        ''',
+        group='Events',
+        columns={
+            'ts':
+                '''The timestamp at the start of the slice (in nanoseconds).''',
+            'dur':
+                '''The duration of the slice (in nanoseconds).''',
+            'utid':
+                '''The thread's unique id in the trace..''',
+            'cpu':
+                '''The CPU that the slice executed on.''',
+            'end_state':
+                '''A string representing the scheduling state of the
+kernel thread at the end of the slice.  The individual characters in
+the string mean the following: R (runnable), S (awaiting a wakeup),
+D (in an uninterruptible sleep), T (suspended), t (being traced),
+X (exiting), P (parked), W (waking), I (idle), N (not contributing
+to the load average), K (wakeable on fatal signals) and
+Z (zombie, awaiting cleanup).''',
+            'priority':
+                '''The kernel priority that the thread ran at.'''
+        }))
+
+THREAD_STATE_TABLE = Table(
+    class_name='ThreadStateTable',
+    sql_name='thread_state',
+    columns=[
+        C('utid', CppUint32()),
+        C('ts', CppInt64()),
+        C('dur', CppInt64()),
+        C('cpu', CppOptional(CppUint32())),
+        C('state', CppString()),
+        C('io_wait', CppOptional(CppUint32())),
+        C('blocked_function', CppOptional(CppString())),
+        C('waker_utid', CppOptional(CppUint32())),
+    ],
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Events',
+        columns={
+            'utid': '''''',
+            'ts': '''''',
+            'dur': '''''',
+            'cpu': '''''',
+            'state': '''''',
+            'io_wait': '''''',
+            'blocked_function': '''''',
+            'waker_utid': ''''''
+        }))
+
+GPU_SLICE_TABLE = Table(
+    class_name='GpuSliceTable',
+    sql_name='gpu_slice',
+    columns=[
+        C('context_id', CppOptional(CppInt64())),
+        C('render_target', CppOptional(CppInt64())),
+        C('render_target_name', CppString()),
+        C('render_pass', CppOptional(CppInt64())),
+        C('render_pass_name', CppString()),
+        C('command_buffer', CppOptional(CppInt64())),
+        C('command_buffer_name', CppString()),
+        C('frame_id', CppOptional(CppUint32())),
+        C('submission_id', CppOptional(CppUint32())),
+        C('hw_queue_id', CppOptional(CppInt64())),
+        C('render_subpasses', CppString()),
+    ],
+    parent=SLICE_TABLE,
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Events',
+        columns={
+            'context_id': '''''',
+            'render_target': '''''',
+            'render_target_name': '''''',
+            'render_pass': '''''',
+            'render_pass_name': '''''',
+            'command_buffer': '''''',
+            'command_buffer_name': '''''',
+            'frame_id': '''''',
+            'submission_id': '''''',
+            'hw_queue_id': '''''',
+            'render_subpasses': ''''''
+        }))
+
+GRAPHICS_FRAME_SLICE_TABLE = Table(
+    class_name='GraphicsFrameSliceTable',
+    sql_name='frame_slice',
+    columns=[
+        C('frame_number', CppUint32()),
+        C('layer_name', CppString()),
+        C('queue_to_acquire_time', CppInt64()),
+        C('acquire_to_latch_time', CppInt64()),
+        C('latch_to_present_time', CppInt64()),
+    ],
+    parent=SLICE_TABLE,
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Events',
+        columns={
+            'frame_number': '''''',
+            'layer_name': '''''',
+            'queue_to_acquire_time': '''''',
+            'acquire_to_latch_time': '''''',
+            'latch_to_present_time': ''''''
+        }))
+
+EXPECTED_FRAME_TIMELINE_SLICE_TABLE = Table(
+    class_name='ExpectedFrameTimelineSliceTable',
+    sql_name='expected_frame_timeline_slice',
+    columns=[
+        C('display_frame_token', CppInt64()),
+        C('surface_frame_token', CppInt64()),
+        C('upid', CppUint32()),
+        C('layer_name', CppString()),
+    ],
+    parent=SLICE_TABLE,
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Misc',
+        columns={
+            'display_frame_token': '''''',
+            'surface_frame_token': '''''',
+            'upid': '''''',
+            'layer_name': ''''''
+        }))
+
+ACTUAL_FRAME_TIMELINE_SLICE_TABLE = Table(
+    class_name='ActualFrameTimelineSliceTable',
+    sql_name='actual_frame_timeline_slice',
+    columns=[
+        C('display_frame_token', CppInt64()),
+        C('surface_frame_token', CppInt64()),
+        C('upid', CppUint32()),
+        C('layer_name', CppString()),
+        C('present_type', CppString()),
+        C('on_time_finish', CppInt32()),
+        C('gpu_composition', CppInt32()),
+        C('jank_type', CppString()),
+        C('prediction_type', CppString()),
+        C('jank_tag', CppString()),
+    ],
+    parent=SLICE_TABLE,
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Misc',
+        columns={
+            'display_frame_token': '''''',
+            'surface_frame_token': '''''',
+            'upid': '''''',
+            'layer_name': '''''',
+            'present_type': '''''',
+            'on_time_finish': '''''',
+            'gpu_composition': '''''',
+            'jank_type': '''''',
+            'prediction_type': '''''',
+            'jank_tag': ''''''
+        }))
+
+EXPERIMENTAL_FLAT_SLICE_TABLE = Table(
+    class_name='ExperimentalFlatSliceTable',
+    sql_name='experimental_flat_slice',
+    columns=[
+        C('ts', CppInt64()),
+        C('dur', CppInt64()),
+        C('track_id', CppTableId(TRACK_TABLE)),
+        C('category', CppOptional(CppString())),
+        C('name', CppOptional(CppString())),
+        C('arg_set_id', CppUint32()),
+        C('source_id', CppOptional(CppTableId(SLICE_TABLE))),
+        C('start_bound', CppInt64(), flags=ColumnFlag.HIDDEN),
+        C('end_bound', CppInt64(), flags=ColumnFlag.HIDDEN),
+    ],
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Misc',
+        columns={
+            'ts': '''''',
+            'dur': '''''',
+            'track_id': '''''',
+            'category': '''''',
+            'name': '''''',
+            'arg_set_id': '''''',
+            'source_id': '''''',
+            'start_bound': '''''',
+            'end_bound': ''''''
+        }))
+
+# Keep this list sorted.
+ALL_TABLES = [
+    ACTUAL_FRAME_TIMELINE_SLICE_TABLE,
+    EXPECTED_FRAME_TIMELINE_SLICE_TABLE,
+    EXPERIMENTAL_FLAT_SLICE_TABLE,
+    GPU_SLICE_TABLE,
+    GRAPHICS_FRAME_SLICE_TABLE,
+    SCHED_SLICE_TABLE,
+    SLICE_TABLE,
+    THREAD_STATE_TABLE,
+]
diff --git a/src/trace_processor/tables/table_destructors.cc b/src/trace_processor/tables/table_destructors.cc
index b8e0482..5025ab3 100644
--- a/src/trace_processor/tables/table_destructors.cc
+++ b/src/trace_processor/tables/table_destructors.cc
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-#include "src/trace_processor/tables/android_tables.h"
-#include "src/trace_processor/tables/counter_tables.h"
-#include "src/trace_processor/tables/flow_tables.h"
-#include "src/trace_processor/tables/memory_tables.h"
-#include "src/trace_processor/tables/metadata_tables.h"
-#include "src/trace_processor/tables/profiler_tables.h"
-#include "src/trace_processor/tables/slice_tables.h"
-#include "src/trace_processor/tables/trace_proto_tables.h"
+#include "src/trace_processor/tables/android_tables_py.h"
+#include "src/trace_processor/tables/counter_tables_py.h"
+#include "src/trace_processor/tables/flow_tables_py.h"
+#include "src/trace_processor/tables/memory_tables_py.h"
+#include "src/trace_processor/tables/metadata_tables_py.h"
+#include "src/trace_processor/tables/profiler_tables_py.h"
+#include "src/trace_processor/tables/slice_tables_py.h"
+#include "src/trace_processor/tables/trace_proto_tables_py.h"
 #include "src/trace_processor/tables/track_tables_py.h"
 
 namespace perfetto {
@@ -32,15 +32,15 @@
 }  // namespace macros_internal
 
 namespace tables {
-// android_tables.h
+// android_tables_py.h
 AndroidDumpstateTable::~AndroidDumpstateTable() = default;
 AndroidGameInterventionListTable::~AndroidGameInterventionListTable() = default;
 AndroidLogTable::~AndroidLogTable() = default;
 
-// counter_tables.h
+// counter_tables_py.h
 CounterTable::~CounterTable() = default;
 
-// metadata_tables.h
+// metadata_tables_py.h
 RawTable::~RawTable() = default;
 ArgTable::~ArgTable() = default;
 ExpMissingChromeProcTable::~ExpMissingChromeProcTable() = default;
@@ -52,7 +52,7 @@
 FiledescriptorTable::~FiledescriptorTable() = default;
 ClockSnapshotTable::~ClockSnapshotTable() = default;
 
-// profiler_tables.h
+// profiler_tables_py.h
 StackProfileMappingTable::~StackProfileMappingTable() = default;
 StackProfileFrameTable::~StackProfileFrameTable() = default;
 StackProfileCallsiteTable::~StackProfileCallsiteTable() = default;
@@ -70,7 +70,7 @@
 ProfilerSmapsTable::~ProfilerSmapsTable() = default;
 GpuCounterGroupTable::~GpuCounterGroupTable() = default;
 
-// slice_tables.h
+// slice_tables_py.h
 SliceTable::~SliceTable() = default;
 FlowTable::~FlowTable() = default;
 SchedSliceTable::~SchedSliceTable() = default;
@@ -99,11 +99,11 @@
 UidCounterTrackTable::~UidCounterTrackTable() = default;
 EnergyPerUidCounterTrackTable::~EnergyPerUidCounterTrackTable() = default;
 
-// trace_proto_tables.h
+// trace_proto_tables_py.h
 ExperimentalProtoPathTable::~ExperimentalProtoPathTable() = default;
 ExperimentalProtoContentTable::~ExperimentalProtoContentTable() = default;
 
-// memory_tables.h
+// memory_tables_py.h
 MemorySnapshotTable::~MemorySnapshotTable() = default;
 ProcessMemorySnapshotTable::~ProcessMemorySnapshotTable() = default;
 MemorySnapshotNodeTable::~MemorySnapshotNodeTable() = default;
diff --git a/src/trace_processor/tables/trace_proto_tables.h b/src/trace_processor/tables/trace_proto_tables.h
index 04579ea..aa57b59 100644
--- a/src/trace_processor/tables/trace_proto_tables.h
+++ b/src/trace_processor/tables/trace_proto_tables.h
@@ -27,10 +27,10 @@
 #define PERFETTO_TP_EXPERIMENTAL_PROTO_PATH_TABLE_DEF(NAME, PARENT, C) \
   NAME(ExperimentalProtoPathTable, "experimental_proto_path")          \
   PERFETTO_TP_ROOT_TABLE(PARENT, C)                                    \
-  C(base::Optional<ExperimentalProtoPathTable::Id>, parent_id)         \
+  C(std::optional<ExperimentalProtoPathTable::Id>, parent_id)          \
   C(StringPool::Id, field_type)                                        \
-  C(base::Optional<StringPool::Id>, field_name)                        \
-  C(base::Optional<uint32_t>, arg_set_id)
+  C(std::optional<StringPool::Id>, field_name)                         \
+  C(std::optional<uint32_t>, arg_set_id)
 
 PERFETTO_TP_TABLE(PERFETTO_TP_EXPERIMENTAL_PROTO_PATH_TABLE_DEF);
 
diff --git a/src/trace_processor/tables/trace_proto_tables.py b/src/trace_processor/tables/trace_proto_tables.py
new file mode 100644
index 0000000..f6f5f9d
--- /dev/null
+++ b/src/trace_processor/tables/trace_proto_tables.py
@@ -0,0 +1,72 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Contains tables for relevant for TODO."""
+
+from python.generators.trace_processor_table.public import Column as C
+from python.generators.trace_processor_table.public import CppInt64
+from python.generators.trace_processor_table.public import CppOptional
+from python.generators.trace_processor_table.public import CppSelfTableId
+from python.generators.trace_processor_table.public import CppString
+from python.generators.trace_processor_table.public import Table
+from python.generators.trace_processor_table.public import TableDoc
+from python.generators.trace_processor_table.public import CppTableId
+from python.generators.trace_processor_table.public import CppUint32
+
+EXPERIMENTAL_PROTO_PATH_TABLE = Table(
+    class_name='ExperimentalProtoPathTable',
+    sql_name='experimental_proto_path',
+    columns=[
+        C('parent_id', CppOptional(CppSelfTableId())),
+        C('field_type', CppString()),
+        C('field_name', CppOptional(CppString())),
+        C('arg_set_id', CppOptional(CppUint32())),
+    ],
+    tabledoc=TableDoc(
+        doc='''
+          Experimental table, subject to arbitrary breaking changes.
+        ''',
+        group='Misc',
+        columns={
+            'parent_id': '''''',
+            'field_type': '''''',
+            'field_name': '''''',
+            'arg_set_id': ''''''
+        }))
+
+EXPERIMENTAL_PROTO_CONTENT_TABLE = Table(
+    class_name='ExperimentalProtoContentTable',
+    sql_name='experimental_proto_content',
+    columns=[
+        C('path', CppString()),
+        C('path_id', CppTableId(EXPERIMENTAL_PROTO_PATH_TABLE)),
+        C('total_size', CppInt64()),
+        C('size', CppInt64()),
+        C('count', CppInt64()),
+    ],
+    tabledoc=TableDoc(
+        doc='''''',
+        group='Misc',
+        columns={
+            'path': '''''',
+            'path_id': '''''',
+            'total_size': '''''',
+            'size': '''''',
+            'count': ''''''
+        }))
+
+# Keep this list sorted.
+ALL_TABLES = [
+    EXPERIMENTAL_PROTO_CONTENT_TABLE,
+    EXPERIMENTAL_PROTO_PATH_TABLE,
+]
diff --git a/src/trace_processor/trace_database_integrationtest.cc b/src/trace_processor/trace_database_integrationtest.cc
index 720389a..b675c80 100644
--- a/src/trace_processor/trace_database_integrationtest.cc
+++ b/src/trace_processor/trace_database_integrationtest.cc
@@ -16,11 +16,11 @@
 
 #include <algorithm>
 #include <map>
+#include <optional>
 #include <random>
 #include <string>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/trace_processor/trace_processor.h"
 #include "protos/perfetto/common/descriptor.pbzero.h"
diff --git a/src/trace_processor/trace_processor_context.cc b/src/trace_processor/trace_processor_context.cc
index 29fa474..b407e19 100644
--- a/src/trace_processor/trace_processor_context.cc
+++ b/src/trace_processor/trace_processor_context.cc
@@ -26,13 +26,13 @@
 #include "src/trace_processor/importers/common/event_tracker.h"
 #include "src/trace_processor/importers/common/flow_tracker.h"
 #include "src/trace_processor/importers/common/global_args_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/importers/common/process_tracker.h"
 #include "src/trace_processor/importers/common/slice_tracker.h"
 #include "src/trace_processor/importers/common/slice_translation_table.h"
 #include "src/trace_processor/importers/common/track_tracker.h"
 #include "src/trace_processor/importers/ftrace/ftrace_module.h"
 #include "src/trace_processor/importers/proto/heap_profile_tracker.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
 #include "src/trace_processor/importers/proto/perf_sample_tracker.h"
 #include "src/trace_processor/importers/proto/proto_importer_module.h"
 #include "src/trace_processor/importers/proto/proto_trace_parser.h"
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index ee0fd9c..742d7a2 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -33,6 +33,7 @@
 #include "perfetto/trace_processor/basic_types.h"
 #include "src/trace_processor/importers/android_bugreport/android_bugreport_parser.h"
 #include "src/trace_processor/importers/common/clock_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/importers/ftrace/sched_event_tracker.h"
 #include "src/trace_processor/importers/fuchsia/fuchsia_trace_parser.h"
 #include "src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.h"
@@ -43,7 +44,6 @@
 #include "src/trace_processor/importers/ninja/ninja_log_parser.h"
 #include "src/trace_processor/importers/proto/additional_modules.h"
 #include "src/trace_processor/importers/proto/content_analyzer.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
 #include "src/trace_processor/importers/systrace/systrace_trace_parser.h"
 #include "src/trace_processor/iterator_impl.h"
 #include "src/trace_processor/prelude/functions/create_function.h"
@@ -219,28 +219,10 @@
 void CreateBuiltinViews(sqlite3* db) {
   char* error = nullptr;
   sqlite3_exec(db,
-               "CREATE VIEW counter_definitions AS "
-               "SELECT "
-               "  *, "
-               "  id AS counter_id "
-               "FROM counter_track",
-               nullptr, nullptr, &error);
-  MaybeRegisterError(error);
-
-  sqlite3_exec(db,
-               "CREATE VIEW counter_values AS "
-               "SELECT "
-               "  *, "
-               "  track_id as counter_id "
-               "FROM counter",
-               nullptr, nullptr, &error);
-  MaybeRegisterError(error);
-
-  sqlite3_exec(db,
                "CREATE VIEW counters AS "
                "SELECT * "
-               "FROM counter_values v "
-               "INNER JOIN counter_track t "
+               "FROM counter v "
+               "JOIN counter_track t "
                "ON v.track_id = t.id "
                "ORDER BY ts;",
                nullptr, nullptr, &error);
@@ -274,8 +256,6 @@
                nullptr, nullptr, &error);
   MaybeRegisterError(error);
 
-  // Legacy view for "slice" table with a deprecated table name.
-  // TODO(eseckler): Remove this view when all users have switched to "slice".
   sqlite3_exec(db,
                "CREATE VIEW slices AS "
                "SELECT * FROM slice;",
@@ -320,22 +300,6 @@
                nullptr, nullptr, &error);
   MaybeRegisterError(error);
 
-  // TODO(lalitm): delete this any time after ~Feb 2023 when no version of the
-  // UI will be querying this anymore (describe_slice backing code was removed
-  // at end of November).
-  sqlite3_exec(db,
-               "CREATE TABLE describe_slice(id INT, type TEXT, "
-               "slice_id INT, description TEXT, doc_link TEXT);",
-               nullptr, nullptr, &error);
-  MaybeRegisterError(error);
-
-  sqlite3_exec(db,
-               "CREATE VIEW thread_slice AS "
-               "SELECT * FROM slice "
-               "WHERE thread_dur is NOT NULL",
-               nullptr, nullptr, &error);
-  MaybeRegisterError(error);
-
   sqlite3_exec(db,
                "CREATE VIEW ftrace_event AS "
                "SELECT * FROM raw "
@@ -1043,7 +1007,7 @@
 }
 
 bool TraceProcessorImpl::IsRootMetricField(const std::string& metric_name) {
-  base::Optional<uint32_t> desc_idx =
+  std::optional<uint32_t> desc_idx =
       pool_.FindDescriptorIdx(".perfetto.protos.TraceMetrics");
   if (!desc_idx.has_value())
     return false;
diff --git a/src/trace_processor/trace_processor_shell.cc b/src/trace_processor/trace_processor_shell.cc
index 0a0ba23..1b02b27 100644
--- a/src/trace_processor/trace_processor_shell.cc
+++ b/src/trace_processor/trace_processor_shell.cc
@@ -13,15 +13,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <sys/stat.h>
-
 #include <cctype>
 #include <cinttypes>
 #include <functional>
 #include <iostream>
+#include <optional>
 #include <string>
 #include <unordered_map>
 #include <unordered_set>
@@ -39,7 +40,6 @@
 #include "perfetto/ext/base/file_utils.h"
 #include "perfetto/ext/base/flat_hash_map.h"
 #include "perfetto/ext/base/getopt.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/string_splitter.h"
 #include "perfetto/ext/base/string_utils.h"
@@ -396,7 +396,7 @@
 
 struct MetricNameAndPath {
   std::string name;
-  base::Optional<std::string> no_ext_path;
+  std::optional<std::string> no_ext_path;
 };
 
 base::Status RunMetrics(const std::vector<MetricNameAndPath>& metrics,
@@ -1345,7 +1345,7 @@
     auto ext_idx = metric_or_path.rfind('.');
     if (ext_idx == std::string::npos) {
       name_and_path.emplace_back(
-          MetricNameAndPath{metric_or_path, base::nullopt});
+          MetricNameAndPath{metric_or_path, std::nullopt});
       continue;
     }
 
@@ -1453,7 +1453,7 @@
           PERFETTO_ELOG("%s", status.c_message());
         }
       } else if (strcmp(command, "width") == 0 && strlen(arg)) {
-        base::Optional<uint32_t> width = base::CStringToUInt32(arg);
+        std::optional<uint32_t> width = base::CStringToUInt32(arg);
         if (!width) {
           PERFETTO_ELOG("Invalid column width specified");
           continue;
diff --git a/src/trace_processor/trace_processor_storage_impl.cc b/src/trace_processor/trace_processor_storage_impl.cc
index 3bea7eb..75031f8 100644
--- a/src/trace_processor/trace_processor_storage_impl.cc
+++ b/src/trace_processor/trace_processor_storage_impl.cc
@@ -25,6 +25,7 @@
 #include "src/trace_processor/importers/common/clock_tracker.h"
 #include "src/trace_processor/importers/common/event_tracker.h"
 #include "src/trace_processor/importers/common/flow_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
 #include "src/trace_processor/importers/common/process_tracker.h"
 #include "src/trace_processor/importers/common/slice_tracker.h"
 #include "src/trace_processor/importers/common/slice_translation_table.h"
@@ -32,7 +33,6 @@
 #include "src/trace_processor/importers/proto/chrome_track_event.descriptor.h"
 #include "src/trace_processor/importers/proto/default_modules.h"
 #include "src/trace_processor/importers/proto/heap_profile_tracker.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
 #include "src/trace_processor/importers/proto/packet_analyzer.h"
 #include "src/trace_processor/importers/proto/perf_sample_tracker.h"
 #include "src/trace_processor/importers/proto/proto_importer_module.h"
@@ -60,7 +60,7 @@
   context_.flow_tracker.reset(new FlowTracker(&context_));
   context_.event_tracker.reset(new EventTracker(&context_));
   context_.process_tracker.reset(new ProcessTracker(&context_));
-  context_.clock_tracker.reset(new ClockTracker(context_.storage.get()));
+  context_.clock_tracker.reset(new ClockTracker(&context_));
   context_.heap_profile_tracker.reset(new HeapProfileTracker(&context_));
   context_.perf_sample_tracker.reset(new PerfSampleTracker(&context_));
   context_.global_stack_profile_tracker.reset(new GlobalStackProfileTracker());
diff --git a/src/trace_processor/types/gfp_flags.cc b/src/trace_processor/types/gfp_flags.cc
index acb52fb..a27ab10 100644
--- a/src/trace_processor/types/gfp_flags.cc
+++ b/src/trace_processor/types/gfp_flags.cc
@@ -215,7 +215,7 @@
 }  // namespace
 
 void WriteGfpFlag(uint64_t value,
-                  base::Optional<VersionNumber> version,
+                  std::optional<VersionNumber> version,
                   base::StringWriter* writer) {
   // On all kernel versions if this flag is not set, return GFP_NOWAIT.
   if (value == 0) {
diff --git a/src/trace_processor/types/gfp_flags.h b/src/trace_processor/types/gfp_flags.h
index fb0ae29..04936a8 100644
--- a/src/trace_processor/types/gfp_flags.h
+++ b/src/trace_processor/types/gfp_flags.h
@@ -17,7 +17,8 @@
 #ifndef SRC_TRACE_PROCESSOR_TYPES_GFP_FLAGS_H_
 #define SRC_TRACE_PROCESSOR_TYPES_GFP_FLAGS_H_
 
-#include "perfetto/ext/base/optional.h"
+#include <optional>
+
 #include "perfetto/ext/base/string_writer.h"
 #include "src/trace_processor/types/version_number.h"
 
@@ -28,7 +29,7 @@
 // the kernel version. This function writes a human readable version of the
 // flag.
 void WriteGfpFlag(uint64_t value,
-                  base::Optional<VersionNumber> version,
+                  std::optional<VersionNumber> version,
                   base::StringWriter* writer);
 
 }  // namespace trace_processor
diff --git a/src/trace_processor/types/task_state.cc b/src/trace_processor/types/task_state.cc
index 91df527..a13f5b9 100644
--- a/src/trace_processor/types/task_state.cc
+++ b/src/trace_processor/types/task_state.cc
@@ -18,6 +18,8 @@
 
 #include <string.h>
 
+#include "perfetto/base/logging.h"
+
 namespace perfetto {
 namespace trace_processor {
 namespace ftrace_utils {
@@ -25,7 +27,7 @@
 // static
 TaskState TaskState::FromRawPrevState(
     uint16_t raw_state,
-    base::Optional<VersionNumber> kernel_version) {
+    std::optional<VersionNumber> kernel_version) {
   return TaskState(raw_state, kernel_version);
 }
 
@@ -53,7 +55,7 @@
 // Note to maintainers: if changing the default kernel assumption or the 4.4
 // codepath, you'll need to update ToRawStateOnlyForSystraceConversions().
 TaskState::TaskState(uint16_t raw_state,
-                     base::Optional<VersionNumber> opt_version) {
+                     std::optional<VersionNumber> opt_version) {
   // Values up to and including 0x20 (EXIT_ZOMBIE) never changed, so map them
   // directly onto ParsedFlag (we use the same flag bits for convenience).
   parsed_ = raw_state & (0x40 - 1);
diff --git a/src/trace_processor/types/task_state.h b/src/trace_processor/types/task_state.h
index 89908dc..0662f72 100644
--- a/src/trace_processor/types/task_state.h
+++ b/src/trace_processor/types/task_state.h
@@ -19,8 +19,8 @@
 
 #include <stdint.h>
 #include <array>
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
 #include "src/trace_processor/types/version_number.h"
 
 namespace perfetto {
@@ -87,7 +87,7 @@
 
   static TaskState FromRawPrevState(
       uint16_t raw_state,
-      base::Optional<VersionNumber> kernel_version);
+      std::optional<VersionNumber> kernel_version);
   static TaskState FromSystrace(const char* state_str);
   static TaskState FromParsedFlags(uint16_t parsed_state);
 
@@ -115,7 +115,7 @@
  private:
   TaskState() = default;
   explicit TaskState(uint16_t raw_state,
-                     base::Optional<VersionNumber> kernel_version);
+                     std::optional<VersionNumber> kernel_version);
   explicit TaskState(const char* state_str);
 
   bool is_runnable() const { return !(parsed_ & ~kPreempted); }
diff --git a/src/trace_processor/types/task_state_unittests.cc b/src/trace_processor/types/task_state_unittests.cc
index decc199..e08fea2 100644
--- a/src/trace_processor/types/task_state_unittests.cc
+++ b/src/trace_processor/types/task_state_unittests.cc
@@ -25,7 +25,7 @@
 
 TEST(TaskStateUnittest, PrevStateDefaultsToKernelVersion4p4) {
   auto from_raw = [](uint16_t raw) {
-    return TaskState::FromRawPrevState(raw, base::nullopt);
+    return TaskState::FromRawPrevState(raw, std::nullopt);
   };
 
   // No kernel version -> default to 4.4
@@ -95,7 +95,7 @@
 TEST(TaskStateUnittest, PreemptedFlag) {
   // Historical TASK_STATE_MAX as of 4.4:
   {
-    TaskState state = TaskState::FromRawPrevState(0x0800, base::nullopt);
+    TaskState state = TaskState::FromRawPrevState(0x0800, std::nullopt);
     EXPECT_STREQ(state.ToString().data(), "R+");
   }
   // TASK_STATE_MAX moved due to TASK_NEW:
@@ -139,7 +139,7 @@
   auto roundtrip = [](const char* in) {
     uint16_t raw =
         TaskState::FromSystrace(in).ToRawStateOnlyForSystraceConversions();
-    return TaskState::FromRawPrevState(raw, base::nullopt).ToString('|');
+    return TaskState::FromRawPrevState(raw, std::nullopt).ToString('|');
   };
 
   EXPECT_STREQ(roundtrip("R").data(), "R");
diff --git a/src/trace_processor/util/annotated_callsites.cc b/src/trace_processor/util/annotated_callsites.cc
index 5e23130..b53e3cf 100644
--- a/src/trace_processor/util/annotated_callsites.cc
+++ b/src/trace_processor/util/annotated_callsites.cc
@@ -17,9 +17,9 @@
 #include "src/trace_processor/util/annotated_callsites.h"
 
 #include <iostream>
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
-#include "src/trace_processor/tables/profiler_tables.h"
+#include "src/trace_processor/tables/profiler_tables_py.h"
 #include "src/trace_processor/types/trace_processor_context.h"
 
 namespace perfetto {
@@ -30,13 +30,13 @@
       // String to identify trampoline frames. If the string does not exist in
       // TraceProcessor's StringPool (nullopt) then there will be no trampoline
       // frames in the trace so there is no point in adding it to the pool to do
-      // all comparisons, instead we initialize the member to nullopt and the
-      // string comparisons will all fail.
+      // all comparisons, instead we initialize the member to std::nullopt and
+      // the string comparisons will all fail.
       art_jni_trampoline_(
           context->storage->string_pool().GetId("art_jni_trampoline")) {}
 
 AnnotatedCallsites::State AnnotatedCallsites::GetState(
-    base::Optional<CallsiteId> id) {
+    std::optional<CallsiteId> id) {
   if (!id) {
     return State::kInitial;
   }
@@ -75,8 +75,8 @@
   // only the libart frames does not clean up all of the JNI-related frames.
   auto frame = *context_.storage->stack_profile_frame_table().FindById(
       callsite.frame_id());
-  // art_jni_trampoline_ could be nullopt if the string does not exist in the
-  // StringPool, but that also means no frame will ever have that name.
+  // art_jni_trampoline_ could be std::nullopt if the string does not exist in
+  // the StringPool, but that also means no frame will ever have that name.
   if (art_jni_trampoline_.has_value() &&
       frame.name() == art_jni_trampoline_.value()) {
     return {State::kKeepNext, CallsiteAnnotation::kCommonFrame};
diff --git a/src/trace_processor/util/annotated_callsites.h b/src/trace_processor/util/annotated_callsites.h
index 0fbb555..e68683c 100644
--- a/src/trace_processor/util/annotated_callsites.h
+++ b/src/trace_processor/util/annotated_callsites.h
@@ -17,8 +17,9 @@
 #ifndef SRC_TRACE_PROCESSOR_UTIL_ANNOTATED_CALLSITES_H_
 #define SRC_TRACE_PROCESSOR_UTIL_ANNOTATED_CALLSITES_H_
 
+#include <optional>
+
 #include <unordered_map>
-#include "perfetto/ext/base/optional.h"
 #include "src/trace_processor/containers/string_pool.h"
 #include "src/trace_processor/storage/trace_storage.h"
 
@@ -71,7 +72,7 @@
   // mode, based on the mapping.
   enum class State { kInitial, kEraseLibart, kKeepNext };
 
-  State GetState(base::Optional<CallsiteId> id);
+  State GetState(std::optional<CallsiteId> id);
 
   std::pair<State, CallsiteAnnotation> Get(
       const tables::StackProfileCallsiteTable::ConstRowReference& callsite);
@@ -80,7 +81,7 @@
   MapType ClassifyMap(NullTermStringView map);
 
   const TraceProcessorContext& context_;
-  const base::Optional<StringPool::Id> art_jni_trampoline_;
+  const std::optional<StringPool::Id> art_jni_trampoline_;
 
   std::unordered_map<MappingId, MapType> map_types_;
   std::unordered_map<CallsiteId, State> states_;
diff --git a/src/trace_processor/util/bump_allocator.cc b/src/trace_processor/util/bump_allocator.cc
index 1469525..48cf16d 100644
--- a/src/trace_processor/util/bump_allocator.cc
+++ b/src/trace_processor/util/bump_allocator.cc
@@ -15,11 +15,12 @@
  */
 
 #include "src/trace_processor/util/bump_allocator.h"
+
 #include <limits>
+#include <optional>
 
 #include "perfetto/base/compiler.h"
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/utils.h"
 
 namespace perfetto {
@@ -55,7 +56,7 @@
 
   // Fast path: check if we have space to service this allocation in the current
   // chunk.
-  base::Optional<AllocId> alloc_id = TryAllocInLastChunk(size);
+  std::optional<AllocId> alloc_id = TryAllocInLastChunk(size);
   if (alloc_id) {
     return *alloc_id;
   }
@@ -113,10 +114,10 @@
   return AllocId{LastChunkIndex(), chunks_.back().bump_offset};
 }
 
-base::Optional<BumpAllocator::AllocId> BumpAllocator::TryAllocInLastChunk(
+std::optional<BumpAllocator::AllocId> BumpAllocator::TryAllocInLastChunk(
     uint32_t size) {
   if (chunks_.empty()) {
-    return base::nullopt;
+    return std::nullopt;
   }
 
   // TODO(266983484): consider switching this to bump downwards instead of
@@ -134,7 +135,7 @@
   uint32_t alloc_offset = chunk.bump_offset;
   uint32_t new_bump_offset = chunk.bump_offset + size;
   if (new_bump_offset > kChunkSize) {
-    return base::nullopt;
+    return std::nullopt;
   }
 
   // Set the new offset equal to the end of this allocation and increment the
diff --git a/src/trace_processor/util/bump_allocator.h b/src/trace_processor/util/bump_allocator.h
index b7b3499..985b5bc 100644
--- a/src/trace_processor/util/bump_allocator.h
+++ b/src/trace_processor/util/bump_allocator.h
@@ -22,9 +22,10 @@
 #include <cstring>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <tuple>
+
 #include "perfetto/ext/base/circular_queue.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/utils.h"
 
 namespace perfetto {
@@ -165,8 +166,8 @@
   };
 
   // Tries to allocate |size| bytes in the final chunk in |chunks_|. Returns
-  // an AllocId if this was successful or base::nullopt otherwise.
-  base::Optional<AllocId> TryAllocInLastChunk(uint32_t size);
+  // an AllocId if this was successful or std::nullopt otherwise.
+  std::optional<AllocId> TryAllocInLastChunk(uint32_t size);
 
   uint64_t ChunkIndexToQueueIndex(uint64_t chunk_index) const {
     return chunk_index - erased_front_chunks_count_;
diff --git a/src/trace_processor/util/descriptors.cc b/src/trace_processor/util/descriptors.cc
index 16cbd66..98029da 100644
--- a/src/trace_processor/util/descriptors.cc
+++ b/src/trace_processor/util/descriptors.cc
@@ -46,7 +46,7 @@
       f_decoder.label() == FieldDescriptorProto::LABEL_REPEATED, is_extension);
 }
 
-base::Optional<uint32_t> DescriptorPool::ResolveShortType(
+std::optional<uint32_t> DescriptorPool::ResolveShortType(
     const std::string& parent_path,
     const std::string& short_type) {
   PERFETTO_DCHECK(!short_type.empty());
@@ -59,7 +59,7 @@
     return opt_idx;
 
   if (parent_path.empty())
-    return base::nullopt;
+    return std::nullopt;
 
   auto parent_dot_idx = parent_path.rfind('.');
   auto parent_substr = parent_dot_idx == std::string::npos
@@ -95,7 +95,7 @@
 util::Status DescriptorPool::AddNestedProtoDescriptors(
     const std::string& file_name,
     const std::string& package_name,
-    base::Optional<uint32_t> parent_idx,
+    std::optional<uint32_t> parent_idx,
     protozero::ConstBytes descriptor_proto,
     std::vector<ExtensionInfo>* extensions,
     bool merge_existing_messages) {
@@ -166,7 +166,7 @@
 util::Status DescriptorPool::AddEnumProtoDescriptors(
     const std::string& file_name,
     const std::string& package_name,
-    base::Optional<uint32_t> parent_idx,
+    std::optional<uint32_t> parent_idx,
     protozero::ConstBytes descriptor_proto,
     bool merge_existing_messages) {
   protos::pbzero::EnumDescriptorProto::Decoder decoder(descriptor_proto);
@@ -186,7 +186,7 @@
   if (!prev_idx.has_value()) {
     ProtoDescriptor proto_descriptor(file_name, package_name, full_name,
                                      ProtoDescriptor::Type::kEnum,
-                                     base::nullopt);
+                                     std::nullopt);
     prev_idx = AddProtoDescriptor(std::move(proto_descriptor));
   }
   ProtoDescriptor& proto_descriptor = descriptors_[*prev_idx];
@@ -226,13 +226,12 @@
     std::string package = "." + base::StringView(file.package()).ToStdString();
     for (auto message_it = file.message_type(); message_it; ++message_it) {
       RETURN_IF_ERROR(AddNestedProtoDescriptors(
-          file_name, package, base::nullopt, *message_it, &extensions,
+          file_name, package, std::nullopt, *message_it, &extensions,
           merge_existing_messages));
     }
     for (auto enum_it = file.enum_type(); enum_it; ++enum_it) {
-      RETURN_IF_ERROR(AddEnumProtoDescriptors(file_name, package, base::nullopt,
-                                              *enum_it,
-                                              merge_existing_messages));
+      RETURN_IF_ERROR(AddEnumProtoDescriptors(
+          file_name, package, std::nullopt, *enum_it, merge_existing_messages));
     }
     for (auto ext_it = file.extension(); ext_it; ++ext_it) {
       extensions.emplace_back(package, *ext_it);
@@ -271,11 +270,11 @@
   return util::OkStatus();
 }
 
-base::Optional<uint32_t> DescriptorPool::FindDescriptorIdx(
+std::optional<uint32_t> DescriptorPool::FindDescriptorIdx(
     const std::string& full_name) const {
   auto it = full_name_to_descriptor_index_.find(full_name);
   if (it == full_name_to_descriptor_index_.end()) {
-    return base::nullopt;
+    return std::nullopt;
   }
   return it->second;
 }
@@ -317,7 +316,7 @@
                                  std::string package_name,
                                  std::string full_name,
                                  Type type,
-                                 base::Optional<uint32_t> parent_id)
+                                 std::optional<uint32_t> parent_id)
     : file_name_(std::move(file_name)),
       package_name_(std::move(package_name)),
       full_name_(std::move(full_name)),
diff --git a/src/trace_processor/util/descriptors.h b/src/trace_processor/util/descriptors.h
index 71dd5cc..33dbcf0 100644
--- a/src/trace_processor/util/descriptors.h
+++ b/src/trace_processor/util/descriptors.h
@@ -18,13 +18,13 @@
 #define SRC_TRACE_PROCESSOR_UTIL_DESCRIPTORS_H_
 
 #include <algorithm>
+#include <optional>
 #include <set>
 #include <string>
 #include <unordered_map>
 #include <vector>
 
 #include "perfetto/base/status.h"
-#include "perfetto/ext/base/optional.h"
 #include "protos/perfetto/common/descriptor.pbzero.h"
 
 namespace protozero {
@@ -77,7 +77,7 @@
                   std::string package_name,
                   std::string full_name,
                   Type type,
-                  base::Optional<uint32_t> parent_id);
+                  std::optional<uint32_t> parent_id);
 
   void AddField(FieldDescriptor descriptor) {
     PERFETTO_DCHECK(type_ == Type::kMessage);
@@ -114,18 +114,18 @@
     return &it->second;
   }
 
-  base::Optional<std::string> FindEnumString(const int32_t value) const {
+  std::optional<std::string> FindEnumString(const int32_t value) const {
     PERFETTO_DCHECK(type_ == Type::kEnum);
     auto it = enum_names_by_value_.find(value);
-    return it == enum_names_by_value_.end() ? base::nullopt
-                                            : base::make_optional(it->second);
+    return it == enum_names_by_value_.end() ? std::nullopt
+                                            : std::make_optional(it->second);
   }
 
-  base::Optional<int32_t> FindEnumValue(const std::string& value) const {
+  std::optional<int32_t> FindEnumValue(const std::string& value) const {
     PERFETTO_DCHECK(type_ == Type::kEnum);
     auto it = enum_values_by_name_.find(value);
-    return it == enum_values_by_name_.end() ? base::nullopt
-                                            : base::make_optional(it->second);
+    return it == enum_values_by_name_.end() ? std::nullopt
+                                            : std::make_optional(it->second);
   }
 
   const std::string& file_name() const { return file_name_; }
@@ -148,7 +148,7 @@
   std::string package_name_;
   std::string full_name_;
   const Type type_;
-  base::Optional<uint32_t> parent_id_;
+  std::optional<uint32_t> parent_id_;
   std::unordered_map<uint32_t, FieldDescriptor> fields_;
   std::unordered_map<int32_t, std::string> enum_names_by_value_;
   std::unordered_map<std::string, int32_t> enum_values_by_name_;
@@ -166,8 +166,7 @@
       const std::vector<std::string>& skip_prefixes = {},
       bool merge_existing_messages = false);
 
-  base::Optional<uint32_t> FindDescriptorIdx(
-      const std::string& full_name) const;
+  std::optional<uint32_t> FindDescriptorIdx(const std::string& full_name) const;
 
   std::vector<uint8_t> SerializeAsDescriptorSet();
 
@@ -182,13 +181,13 @@
  private:
   base::Status AddNestedProtoDescriptors(const std::string& file_name,
                                          const std::string& package_name,
-                                         base::Optional<uint32_t> parent_idx,
+                                         std::optional<uint32_t> parent_idx,
                                          protozero::ConstBytes descriptor_proto,
                                          std::vector<ExtensionInfo>* extensions,
                                          bool merge_existing_messages);
   base::Status AddEnumProtoDescriptors(const std::string& file_name,
                                        const std::string& package_name,
-                                       base::Optional<uint32_t> parent_idx,
+                                       std::optional<uint32_t> parent_idx,
                                        protozero::ConstBytes descriptor_proto,
                                        bool merge_existing_messages);
 
@@ -197,8 +196,8 @@
 
   // Recursively searches for the given short type in all parent messages
   // and packages.
-  base::Optional<uint32_t> ResolveShortType(const std::string& parent_path,
-                                            const std::string& short_type);
+  std::optional<uint32_t> ResolveShortType(const std::string& parent_path,
+                                           const std::string& short_type);
 
   // Adds a new descriptor to the pool and returns its index. There must not be
   // already a descriptor with the same full_name in the pool.
diff --git a/src/trace_processor/util/glob.h b/src/trace_processor/util/glob.h
index 4a413bb..ab9eec9 100644
--- a/src/trace_processor/util/glob.h
+++ b/src/trace_processor/util/glob.h
@@ -17,9 +17,9 @@
 #ifndef SRC_TRACE_PROCESSOR_UTIL_GLOB_H_
 #define SRC_TRACE_PROCESSOR_UTIL_GLOB_H_
 
+#include <optional>
 #include <vector>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/small_vector.h"
 #include "perfetto/ext/base/string_splitter.h"
 #include "perfetto/ext/base/string_view.h"
diff --git a/src/trace_processor/util/profile_builder.cc b/src/trace_processor/util/profile_builder.cc
index 869d9a6..8856825 100644
--- a/src/trace_processor/util/profile_builder.cc
+++ b/src/trace_processor/util/profile_builder.cc
@@ -20,10 +20,10 @@
 #include <deque>
 #include <iostream>
 #include <iterator>
+#include <optional>
 #include <vector>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/ext/trace_processor/demangle.h"
@@ -200,6 +200,11 @@
     : context_(*context),
       string_table_(&result_, &context->storage->string_pool()),
       annotations_(context) {
+  // Make sure the empty function always gets id 0 which will be ignored when
+  // writing the proto file.
+  functions_.insert(
+      {Function{kEmptyStringIndex, kEmptyStringIndex, kEmptyStringIndex},
+       kNullFunctionId});
   WriteSampleTypes(sample_types);
 }
 
@@ -314,7 +319,7 @@
 
   const auto& cs_table = context_.storage->stack_profile_callsite_table();
 
-  base::Optional<tables::StackProfileCallsiteTable::ConstRowReference>
+  std::optional<tables::StackProfileCallsiteTable::ConstRowReference>
       start_ref = cs_table.FindById(callsite_id);
   if (!start_ref) {
     return location_ids;
@@ -324,7 +329,7 @@
       start_ref->frame_id(), annotated ? annotations_.GetAnnotation(*start_ref)
                                        : CallsiteAnnotation::kNone));
 
-  base::Optional<CallsiteId> parent_id = start_ref->parent_id();
+  std::optional<CallsiteId> parent_id = start_ref->parent_id();
   while (parent_id) {
     auto parent_ref = cs_table.FindById(*parent_id);
     location_ids.Append(WriteLocationIfNeeded(
@@ -409,8 +414,13 @@
     uint64_t mapping_id) {
   std::vector<Line> lines =
       GetLinesForSymbolSetId(frame.symbol_set_id(), annotation, mapping_id);
-  if (lines.empty()) {
-    uint64_t function_id = WriteFunctionIfNeeded(frame, annotation, mapping_id);
+  if (!lines.empty()) {
+    return lines;
+  }
+
+  if (uint64_t function_id =
+          WriteFunctionIfNeeded(frame, annotation, mapping_id);
+      function_id != kNullFunctionId) {
     lines.push_back({function_id, 0});
   }
 
@@ -418,7 +428,7 @@
 }
 
 std::vector<GProfileBuilder::Line> GProfileBuilder::GetLinesForSymbolSetId(
-    base::Optional<uint32_t> symbol_set_id,
+    std::optional<uint32_t> symbol_set_id,
     CallsiteAnnotation annotation,
     uint64_t mapping_id) {
   if (!symbol_set_id) {
@@ -441,8 +451,11 @@
 
   std::vector<GProfileBuilder::Line> lines;
   for (const RowRef& symbol : symbol_set) {
-    lines.push_back({WriteFunctionIfNeeded(symbol, annotation, mapping_id),
-                     symbol.line_number()});
+    if (uint64_t function_id =
+            WriteFunctionIfNeeded(symbol, annotation, mapping_id);
+        function_id != kNullFunctionId) {
+      lines.push_back({function_id, symbol.line_number()});
+    }
   }
 
   GetMapping(mapping_id).debug_info.has_inline_frames = true;
@@ -503,6 +516,11 @@
   return name;
 }
 
+int64_t GProfileBuilder::GetSystemNameForFrame(
+    const tables::StackProfileFrameTable::ConstRowReference& frame) {
+  return string_table_.InternString(frame.name());
+}
+
 uint64_t GProfileBuilder::WriteFunctionIfNeeded(
     const tables::StackProfileFrameTable::ConstRowReference& frame,
     CallsiteAnnotation annotation,
@@ -515,7 +533,7 @@
 
   auto ins = functions_.insert(
       {Function{GetNameForFrame(frame, annotation),
-                string_table_.InternString(frame.name()), kEmptyStringIndex},
+                GetSystemNameForFrame(frame), kEmptyStringIndex},
        functions_.size() + 1});
   uint64_t id = ins.first->second;
   seen_functions_.insert({key, id});
@@ -530,6 +548,9 @@
 
 void GProfileBuilder::WriteFunctions() {
   for (const auto& entry : functions_) {
+    if (entry.second == kNullFunctionId) {
+      continue;
+    }
     auto* func = result_->add_function();
     func->set_id(entry.second);
     if (entry.first.name != 0) {
@@ -580,7 +601,7 @@
 void GProfileBuilder::WriteMappings() {
   // The convention in pprof files is to write the mapping for the main binary
   // first. So lets do just that.
-  base::Optional<uint64_t> main_mapping_id = GuessMainBinary();
+  std::optional<uint64_t> main_mapping_id = GuessMainBinary();
   if (main_mapping_id) {
     WriteMapping(*main_mapping_id);
   }
@@ -594,7 +615,7 @@
   }
 }
 
-base::Optional<uint64_t> GProfileBuilder::GuessMainBinary() const {
+std::optional<uint64_t> GProfileBuilder::GuessMainBinary() const {
   std::vector<int64_t> mapping_scores;
 
   for (const auto& mapping : mappings_) {
@@ -604,7 +625,7 @@
   auto it = std::max_element(mapping_scores.begin(), mapping_scores.end());
 
   if (it == mapping_scores.end()) {
-    return base::nullopt;
+    return std::nullopt;
   }
 
   return static_cast<uint64_t>(std::distance(mapping_scores.begin(), it) + 1);
diff --git a/src/trace_processor/util/profile_builder.h b/src/trace_processor/util/profile_builder.h
index 9e1c873..cfd5406 100644
--- a/src/trace_processor/util/profile_builder.h
+++ b/src/trace_processor/util/profile_builder.h
@@ -17,7 +17,8 @@
 #ifndef SRC_TRACE_PROCESSOR_UTIL_PROFILE_BUILDER_H_
 #define SRC_TRACE_PROCESSOR_UTIL_PROFILE_BUILDER_H_
 
-#include "perfetto/ext/base/optional.h"
+#include <optional>
+
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/protozero/packed_repeated_fields.h"
 #include "perfetto/protozero/scattered_heap_buffer.h"
@@ -25,7 +26,7 @@
 #include "protos/third_party/pprof/profile.pbzero.h"
 #include "src/trace_processor/containers/string_pool.h"
 #include "src/trace_processor/storage/trace_storage.h"
-#include "src/trace_processor/tables/profiler_tables.h"
+#include "src/trace_processor/tables/profiler_tables_py.h"
 #include "src/trace_processor/util/annotated_callsites.h"
 
 #include <algorithm>
@@ -73,6 +74,7 @@
 
  private:
   static constexpr int64_t kEmptyStringIndex = 0;
+  static constexpr uint64_t kNullFunctionId = 0;
 
   // Strings are stored in the `Profile` in a table and referenced by their
   // index. This helper class takes care of all the book keeping.
@@ -256,7 +258,7 @@
       bool annotated);
 
   std::vector<Line> GetLinesForSymbolSetId(
-      base::Optional<uint32_t> symbol_set_id,
+      std::optional<uint32_t> symbol_set_id,
       CallsiteAnnotation annotation,
       uint64_t mapping_id);
 
@@ -269,6 +271,9 @@
       const tables::StackProfileFrameTable::ConstRowReference& frame,
       CallsiteAnnotation annotation);
 
+  int64_t GetSystemNameForFrame(
+      const tables::StackProfileFrameTable::ConstRowReference& frame);
+
   uint64_t WriteLocationIfNeeded(FrameId frame_id,
                                  CallsiteAnnotation annotation);
   uint64_t WriteFakeLocationIfNeeded(const std::string& name);
@@ -276,8 +281,8 @@
   uint64_t WriteFunctionIfNeeded(
       const tables::SymbolTable::ConstRowReference& symbol,
       CallsiteAnnotation annotation,
-
       uint64_t mapping_id);
+
   uint64_t WriteFunctionIfNeeded(
       const tables::StackProfileFrameTable::ConstRowReference& frame,
       CallsiteAnnotation annotation,
@@ -302,7 +307,7 @@
 
   // Goes over the list of staged mappings and tries to determine which is the
   // most likely main binary.
-  base::Optional<uint64_t> GuessMainBinary() const;
+  std::optional<uint64_t> GuessMainBinary() const;
 
   bool AddSample(const protozero::PackedVarInt& location_ids,
                  const protozero::PackedVarInt& values);
diff --git a/src/trace_processor/util/proto_profiler.cc b/src/trace_processor/util/proto_profiler.cc
index 1bcd3ff..d093de2 100644
--- a/src/trace_processor/util/proto_profiler.cc
+++ b/src/trace_processor/util/proto_profiler.cc
@@ -91,8 +91,8 @@
   field_path_.emplace_back(0, nullptr, root_message_idx_, descriptor);
 }
 
-base::Optional<size_t> SizeProfileComputer::GetNext() {
-  base::Optional<size_t> result;
+std::optional<size_t> SizeProfileComputer::GetNext() {
+  std::optional<size_t> result;
   if (state_stack_.empty())
     return result;
 
diff --git a/src/trace_processor/util/proto_profiler.h b/src/trace_processor/util/proto_profiler.h
index ebc3670..a5375de 100644
--- a/src/trace_processor/util/proto_profiler.h
+++ b/src/trace_processor/util/proto_profiler.h
@@ -78,9 +78,9 @@
   // TODO(kraskevich): consider switching to internal DescriptorPool.
   void Reset(const uint8_t* ptr, size_t size);
 
-  // Returns the next sample size, or nullopt if data is exhausted. The
+  // Returns the next sample size, or std::nullopt if data is exhausted. The
   // associated path can be queried with GetPath().
-  base::Optional<size_t> GetNext();
+  std::optional<size_t> GetNext();
 
   // Returns the field path associated with the last sample returned by
   // GetNext().
diff --git a/src/trace_processor/util/proto_to_args_parser.cc b/src/trace_processor/util/proto_to_args_parser.cc
index b462d3a..61a8d78 100644
--- a/src/trace_processor/util/proto_to_args_parser.cc
+++ b/src/trace_processor/util/proto_to_args_parser.cc
@@ -50,8 +50,8 @@
     : key_(other.key_),
       old_flat_key_length_(other.old_flat_key_length_),
       old_key_length_(other.old_key_length_) {
-  other.old_flat_key_length_ = base::nullopt;
-  other.old_key_length_ = base::nullopt;
+  other.old_flat_key_length_ = std::nullopt;
+  other.old_key_length_ = std::nullopt;
 }
 
 ProtoToArgsParser::ScopedNestedKeyContext::~ScopedNestedKeyContext() {
@@ -63,8 +63,8 @@
     key_.flat_key.resize(old_flat_key_length_.value());
   if (old_key_length_)
     key_.key.resize(old_key_length_.value());
-  old_flat_key_length_ = base::nullopt;
-  old_key_length_ = base::nullopt;
+  old_flat_key_length_ = std::nullopt;
+  old_key_length_ = std::nullopt;
 }
 
 ProtoToArgsParser::Delegate::~Delegate() = default;
@@ -171,7 +171,7 @@
 
   // If we have an override parser then use that instead and move onto the
   // next loop.
-  if (base::Optional<base::Status> status =
+  if (std::optional<base::Status> status =
           MaybeApplyOverrideForField(field, delegate)) {
     return *status;
   }
@@ -200,23 +200,23 @@
   type_overrides_[type] = std::move(func);
 }
 
-base::Optional<base::Status> ProtoToArgsParser::MaybeApplyOverrideForField(
+std::optional<base::Status> ProtoToArgsParser::MaybeApplyOverrideForField(
     const protozero::Field& field,
     Delegate& delegate) {
   auto it = field_overrides_.find(key_prefix_.flat_key);
   if (it == field_overrides_.end())
-    return base::nullopt;
+    return std::nullopt;
   return it->second(field, delegate);
 }
 
-base::Optional<base::Status> ProtoToArgsParser::MaybeApplyOverrideForType(
+std::optional<base::Status> ProtoToArgsParser::MaybeApplyOverrideForType(
     const std::string& message_type,
     ScopedNestedKeyContext& key,
     const protozero::ConstBytes& data,
     Delegate& delegate) {
   auto it = type_overrides_.find(message_type);
   if (it == type_overrides_.end())
-    return base::nullopt;
+    return std::nullopt;
   return it->second(key, data, delegate);
 }
 
diff --git a/src/trace_processor/util/proto_to_args_parser.h b/src/trace_processor/util/proto_to_args_parser.h
index 7252a0f..be359cd 100644
--- a/src/trace_processor/util/proto_to_args_parser.h
+++ b/src/trace_processor/util/proto_to_args_parser.h
@@ -17,6 +17,8 @@
 #ifndef SRC_TRACE_PROCESSOR_UTIL_PROTO_TO_ARGS_PARSER_H_
 #define SRC_TRACE_PROCESSOR_UTIL_PROTO_TO_ARGS_PARSER_H_
 
+#include <functional>
+
 #include "perfetto/base/status.h"
 #include "perfetto/protozero/field.h"
 #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
@@ -168,8 +170,8 @@
     struct ScopedStringAppender;
 
     Key& key_;
-    base::Optional<size_t> old_flat_key_length_ = base::nullopt;
-    base::Optional<size_t> old_key_length_ = base::nullopt;
+    std::optional<size_t> old_flat_key_length_ = std::nullopt;
+    std::optional<size_t> old_key_length_ = std::nullopt;
   };
 
   // These methods can be called from parsing overrides to enter nested
@@ -179,14 +181,14 @@
   ScopedNestedKeyContext EnterArray(size_t index);
 
   using ParsingOverrideForField =
-      std::function<base::Optional<base::Status>(const protozero::Field&,
-                                                 Delegate& delegate)>;
+      std::function<std::optional<base::Status>(const protozero::Field&,
+                                                Delegate& delegate)>;
 
   // Installs an override for the field at the specified path. We will invoke
   // |parsing_override| when the field is encountered.
   //
   // The return value of |parsing_override| indicates whether the override
-  // parsed the sub-message and ProtoToArgsParser should skip it (base::nullopt)
+  // parsed the sub-message and ProtoToArgsParser should skip it (std::nullopt)
   // or the sub-message should continue to be parsed by ProtoToArgsParser using
   // the descriptor (base::Status).
   //
@@ -207,7 +209,7 @@
   void AddParsingOverrideForField(const std::string& field_path,
                                   ParsingOverrideForField parsing_override);
 
-  using ParsingOverrideForType = std::function<base::Optional<base::Status>(
+  using ParsingOverrideForType = std::function<std::optional<base::Status>(
       ScopedNestedKeyContext& key,
       const protozero::ConstBytes& data,
       Delegate& delegate)>;
@@ -217,7 +219,7 @@
   // Note that the path-based overrides take precedence over type overrides.
   //
   // The return value of |parsing_override| indicates whether the override
-  // parsed the sub-message and ProtoToArgsParser should skip it (base::nullopt)
+  // parsed the sub-message and ProtoToArgsParser should skip it (std::nullopt)
   // or the sub-message should continue to be parsed by ProtoToArgsParser using
   // the descriptor (base::Status).
   //
@@ -247,11 +249,11 @@
                           Delegate& delegate,
                           int* unknown_extensions);
 
-  base::Optional<base::Status> MaybeApplyOverrideForField(
+  std::optional<base::Status> MaybeApplyOverrideForField(
       const protozero::Field&,
       Delegate& delegate);
 
-  base::Optional<base::Status> MaybeApplyOverrideForType(
+  std::optional<base::Status> MaybeApplyOverrideForType(
       const std::string& message_type,
       ScopedNestedKeyContext& key,
       const protozero::ConstBytes& data,
diff --git a/src/trace_processor/util/proto_to_args_parser_unittest.cc b/src/trace_processor/util/proto_to_args_parser_unittest.cc
index 22291ab..16120fc 100644
--- a/src/trace_processor/util/proto_to_args_parser_unittest.cc
+++ b/src/trace_processor/util/proto_to_args_parser_unittest.cc
@@ -311,7 +311,7 @@
         ++val;
         EXPECT_EQ(1, val);
         EXPECT_EQ(field.type(), protozero::proto_utils::ProtoWireType::kVarInt);
-        return base::nullopt;
+        return std::nullopt;
       });
 
   status = parser.ParseMessage(
@@ -358,13 +358,13 @@
   // multiple args rows.
   parser.AddParsingOverrideForField(
       "super_nested.value_c",
-      [](const protozero::Field& field, ProtoToArgsParser::Delegate& delegate)
-          -> base::Optional<base::Status> {
+      [](const protozero::Field& field,
+         ProtoToArgsParser::Delegate& delegate) -> std::optional<base::Status> {
         auto* decoder = delegate.GetInternedMessage(
             protos::pbzero::InternedData::kSourceLocations, field.as_uint64());
         if (!decoder) {
           // Lookup failed fall back on default behaviour.
-          return base::nullopt;
+          return std::nullopt;
         }
         delegate.AddString(ProtoToArgsParser::Key("file_name"),
                            protozero::ConstChars{"file", 4});
diff --git a/src/trace_processor/util/protozero_to_text.cc b/src/trace_processor/util/protozero_to_text.cc
index 90897ad..a7f9fcf 100644
--- a/src/trace_processor/util/protozero_to_text.cc
+++ b/src/trace_processor/util/protozero_to_text.cc
@@ -15,8 +15,8 @@
  */
 
 #include "src/trace_processor/util/protozero_to_text.h"
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/protozero/proto_decoder.h"
@@ -389,7 +389,7 @@
                              const DescriptorPool& pool,
                              std::string* indents,
                              std::string* output) {
-  base::Optional<uint32_t> opt_proto_desc_idx = pool.FindDescriptorIdx(type);
+  std::optional<uint32_t> opt_proto_desc_idx = pool.FindDescriptorIdx(type);
   const ProtoDescriptor* opt_proto_descriptor =
       opt_proto_desc_idx ? &pool.descriptors()[*opt_proto_desc_idx] : nullptr;
   const bool include_new_lines = new_lines_mode == kIncludeNewLines;
diff --git a/src/trace_processor/util/sql_argument.cc b/src/trace_processor/util/sql_argument.cc
index 3fc0b48..11cd010 100644
--- a/src/trace_processor/util/sql_argument.cc
+++ b/src/trace_processor/util/sql_argument.cc
@@ -27,7 +27,7 @@
   return std::find_if(str.begin(), str.end(), pred) == str.end();
 }
 
-base::Optional<Type> ParseType(base::StringView str) {
+std::optional<Type> ParseType(base::StringView str) {
   if (str == "BOOL") {
     return Type::kBool;
   } else if (str == "INT") {
@@ -47,7 +47,7 @@
   } else if (str == "BYTES") {
     return Type::kBytes;
   }
-  return base::nullopt;
+  return std::nullopt;
 }
 
 const char* TypeToHumanFriendlyString(sql_argument::Type type) {
diff --git a/src/trace_processor/util/sql_argument.h b/src/trace_processor/util/sql_argument.h
index 7b7b9b3..8876bed 100644
--- a/src/trace_processor/util/sql_argument.h
+++ b/src/trace_processor/util/sql_argument.h
@@ -16,9 +16,9 @@
 
 #ifndef SRC_TRACE_PROCESSOR_UTIL_SQL_ARGUMENT_H_
 #define SRC_TRACE_PROCESSOR_UTIL_SQL_ARGUMENT_H_
+#include <optional>
 
 #include "perfetto/base/status.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/trace_processor/basic_types.h"
 #include "src/trace_processor/containers/null_term_string_view.h"
 
@@ -79,8 +79,8 @@
 
 // Parses a string containing a type from SQL and converts it to a Type enum
 // value.
-// Returns base::nullopt if |type| did not correspond to any of the enum values.
-base::Optional<Type> ParseType(base::StringView type);
+// Returns std::nullopt if |type| did not correspond to any of the enum values.
+std::optional<Type> ParseType(base::StringView type);
 
 // Converts an argument type to a string for printing (e.g. in error messages
 // etc).
diff --git a/src/trace_processor/util/sql_argument_unittest.cc b/src/trace_processor/util/sql_argument_unittest.cc
index f75ceea..9f15859 100644
--- a/src/trace_processor/util/sql_argument_unittest.cc
+++ b/src/trace_processor/util/sql_argument_unittest.cc
@@ -49,7 +49,7 @@
 TEST(SqlArgumentTest, ParseType) {
   ASSERT_EQ(ParseType("PROTO"), Type::kProto);
   ASSERT_EQ(ParseType("BOOL"), Type::kBool);
-  ASSERT_EQ(ParseType("UNKNOWN"), base::nullopt);
+  ASSERT_EQ(ParseType("UNKNOWN"), std::nullopt);
   ASSERT_EQ(ParseType("UINT"), Type::kUint);
 }
 
diff --git a/src/trace_processor/views/slice_views.h b/src/trace_processor/views/slice_views.h
index 4c2d3bf..287fd02 100644
--- a/src/trace_processor/views/slice_views.h
+++ b/src/trace_processor/views/slice_views.h
@@ -18,8 +18,9 @@
 #define SRC_TRACE_PROCESSOR_VIEWS_SLICE_VIEWS_H_
 
 #include "src/trace_processor/db/view.h"
-#include "src/trace_processor/tables/metadata_tables.h"
+#include "src/trace_processor/tables/metadata_tables_py.h"
 #include "src/trace_processor/tables/slice_tables.h"
+#include "src/trace_processor/tables/slice_tables_py.h"
 #include "src/trace_processor/tables/track_tables_py.h"
 #include "src/trace_processor/views/macros.h"
 
diff --git a/src/traceconv/pprof_builder.cc b/src/traceconv/pprof_builder.cc
index 07aa6f9..1ca8654 100644
--- a/src/traceconv/pprof_builder.cc
+++ b/src/traceconv/pprof_builder.cc
@@ -159,10 +159,10 @@
   return ret;
 }
 
-base::Optional<int64_t> GetStatsEntry(
+std::optional<int64_t> GetStatsEntry(
     trace_processor::TraceProcessor* tp,
     const std::string& name,
-    base::Optional<uint64_t> idx = base::nullopt) {
+    std::optional<uint64_t> idx = std::nullopt) {
   std::string query = "select value from stats where name == '" + name + "'";
   if (idx.has_value())
     query += " and idx == " + std::to_string(idx.value());
@@ -172,12 +172,12 @@
     if (!it.Status().ok()) {
       PERFETTO_DFATAL_OR_ELOG("Invalid iterator: %s",
                               it.Status().message().c_str());
-      return base::nullopt;
+      return std::nullopt;
     }
     // some stats are not present unless non-zero
-    return base::make_optional(0);
+    return std::make_optional(0);
   }
-  return base::make_optional(it.Get(0).AsLong());
+  return std::make_optional(it.Get(0).AsLong());
 }
 
 // Interns Locations, Lines, and Functions. Interning is done by the entity's
@@ -340,9 +340,9 @@
       int64_t mapping_id = c_it.Get(2).AsLong();
       auto func_sysname = c_it.Get(3).is_null() ? "" : c_it.Get(3).AsString();
       auto func_name = c_it.Get(4).is_null() ? "" : c_it.Get(4).AsString();
-      base::Optional<int64_t> symbol_set_id =
-          c_it.Get(5).is_null() ? base::nullopt
-                                : base::make_optional(c_it.Get(5).AsLong());
+      std::optional<int64_t> symbol_set_id =
+          c_it.Get(5).is_null() ? std::nullopt
+                                : std::make_optional(c_it.Get(5).AsLong());
 
       Location loc(mapping_id, /*single_function_id=*/-1, {});
 
@@ -661,8 +661,8 @@
 
 static bool VerifyPIDStats(trace_processor::TraceProcessor* tp, uint64_t pid) {
   bool success = true;
-  base::Optional<int64_t> stat =
-      GetStatsEntry(tp, "heapprofd_buffer_corrupted", base::make_optional(pid));
+  std::optional<int64_t> stat =
+      GetStatsEntry(tp, "heapprofd_buffer_corrupted", std::make_optional(pid));
   if (!stat.has_value()) {
     PERFETTO_DFATAL_OR_ELOG("Failed to get heapprofd_buffer_corrupted stat");
   } else if (stat.value() > 0) {
@@ -673,8 +673,7 @@
                   " CLIENT MEMORY CORRUPTION.",
                   pid);
   }
-  stat =
-      GetStatsEntry(tp, "heapprofd_buffer_overran", base::make_optional(pid));
+  stat = GetStatsEntry(tp, "heapprofd_buffer_overran", std::make_optional(pid));
   if (!stat.has_value()) {
     PERFETTO_DFATAL_OR_ELOG("Failed to get heapprofd_buffer_overran stat");
   } else if (stat.value() > 0) {
@@ -861,7 +860,7 @@
 }
 
 static void LogTracePerfEventIssues(trace_processor::TraceProcessor* tp) {
-  base::Optional<int64_t> stat = GetStatsEntry(tp, "perf_samples_skipped");
+  std::optional<int64_t> stat = GetStatsEntry(tp, "perf_samples_skipped");
   if (!stat.has_value()) {
     PERFETTO_DFATAL_OR_ELOG("Failed to look up perf_samples_skipped stat");
   } else if (stat.value() > 0) {
diff --git a/src/traceconv/trace_to_hprof.cc b/src/traceconv/trace_to_hprof.cc
index d60e193..5bf1b01 100644
--- a/src/traceconv/trace_to_hprof.cc
+++ b/src/traceconv/trace_to_hprof.cc
@@ -18,6 +18,7 @@
 
 #include <algorithm>
 #include <limits>
+#include <optional>
 #include <string>
 #include <unordered_map>
 #include <unordered_set>
@@ -25,7 +26,6 @@
 
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/endian.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "src/traceconv/utils.h"
 
@@ -141,7 +141,7 @@
 // until S.
 class RawClassData {
  public:
-  void AddClass(uint64_t id, base::Optional<uint64_t> superclass_id) {
+  void AddClass(uint64_t id, std::optional<uint64_t> superclass_id) {
     ids_.push_back(std::make_pair(id, superclass_id));
   }
 
@@ -162,7 +162,7 @@
 
  private:
   // Pair contains class ID and super class ID.
-  std::vector<std::pair<uint64_t, base::Optional<uint64_t>>> ids_;
+  std::vector<std::pair<uint64_t, std::optional<uint64_t>>> ids_;
   // Class id of the template
   std::vector<uint64_t> template_ids_;
 };
@@ -217,10 +217,10 @@
       uint64_t name_id = IngestString(dname);
 
       auto raw_super_id = it.Get(2);
-      base::Optional<uint64_t> maybe_super_id =
+      std::optional<uint64_t> maybe_super_id =
           raw_super_id.is_null()
-              ? base::nullopt
-              : base::Optional<uint64_t>(
+              ? std::nullopt
+              : std::optional<uint64_t>(
                     static_cast<uint64_t>(raw_super_id.AsLong()));
 
       std::string location(it.Get(3).AsString());
diff --git a/src/traceconv/utils.cc b/src/traceconv/utils.cc
index d223d8d..1789bc4 100644
--- a/src/traceconv/utils.cc
+++ b/src/traceconv/utils.cc
@@ -20,13 +20,13 @@
 
 #include <cinttypes>
 #include <memory>
+#include <optional>
 #include <ostream>
 #include <set>
 #include <utility>
 
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/string_splitter.h"
 #include "perfetto/protozero/scattered_heap_buffer.h"
diff --git a/src/traceconv/utils.h b/src/traceconv/utils.h
index ce9f8ce..a261774 100644
--- a/src/traceconv/utils.h
+++ b/src/traceconv/utils.h
@@ -22,10 +22,10 @@
 #include <functional>
 #include <iostream>
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "perfetto/base/build_config.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/paged_memory.h"
 #include "src/profiling/deobfuscator.h"
 
diff --git a/src/traced/probes/android_game_intervention_list/android_game_intervention_list_data_source.cc b/src/traced/probes/android_game_intervention_list/android_game_intervention_list_data_source.cc
index 527195e..b3aa454 100644
--- a/src/traced/probes/android_game_intervention_list/android_game_intervention_list_data_source.cc
+++ b/src/traced/probes/android_game_intervention_list/android_game_intervention_list_data_source.cc
@@ -17,9 +17,9 @@
 #include "src/traced/probes/android_game_intervention_list/android_game_intervention_list_data_source.h"
 
 #include <stddef.h>
+#include <optional>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/string_splitter.h"
 #include "perfetto/ext/base/string_utils.h"
@@ -140,9 +140,9 @@
         break;
       }
       case 1: {
-        base::Optional<uint64_t> uid =
+        std::optional<uint64_t> uid =
             base::CStringToUInt64(string_splitter.cur_token());
-        if (uid == base::nullopt) {
+        if (uid == std::nullopt) {
           PERFETTO_DLOG("Failed to parse game_mode_intervention.list uid.");
           return false;
         }
@@ -150,9 +150,9 @@
         break;
       }
       case 2: {
-        base::Optional<uint32_t> cur_mode =
+        std::optional<uint32_t> cur_mode =
             base::CStringToUInt32(string_splitter.cur_token());
-        if (cur_mode == base::nullopt) {
+        if (cur_mode == std::nullopt) {
           PERFETTO_DLOG(
               "Failed to parse game_mode_intervention.list cur_mode.");
           return false;
@@ -163,9 +163,9 @@
       case 3:
       case 5:
       case 7: {
-        base::Optional<uint32_t> game_mode =
+        std::optional<uint32_t> game_mode =
             base::CStringToUInt32(string_splitter.cur_token());
-        if (game_mode == base::nullopt) {
+        if (game_mode == std::nullopt) {
           PERFETTO_DLOG(
               "Failed to parse game_mode_intervention.list game_mode.");
           return false;
@@ -186,9 +186,9 @@
           char* key = value_splitter.cur_token();
           if (strcmp(key, "angle") == 0) {
             value_splitter.Next();
-            base::Optional<uint32_t> use_angle =
+            std::optional<uint32_t> use_angle =
                 base::CStringToUInt32(value_splitter.cur_token());
-            if (use_angle == base::nullopt) {
+            if (use_angle == std::nullopt) {
               PERFETTO_DLOG(
                   "Failed to parse game_mode_intervention.list use_angle.");
               return false;
@@ -196,9 +196,9 @@
             game_mode_info->set_use_angle(use_angle.value());
           } else if (strcmp(key, "scaling") == 0) {
             value_splitter.Next();
-            base::Optional<double> resolution_downscale =
+            std::optional<double> resolution_downscale =
                 base::CStringToDouble(value_splitter.cur_token());
-            if (resolution_downscale == base::nullopt) {
+            if (resolution_downscale == std::nullopt) {
               PERFETTO_DLOG(
                   "Failed to parse game_mode_intervention.list "
                   "resolution_downscale.");
@@ -208,9 +208,9 @@
                 static_cast<float>(resolution_downscale.value()));
           } else if (strcmp(key, "fps") == 0) {
             value_splitter.Next();
-            base::Optional<double> fps =
+            std::optional<double> fps =
                 base::CStringToDouble(value_splitter.cur_token());
-            if (fps == base::nullopt) {
+            if (fps == std::nullopt) {
               PERFETTO_DLOG("Failed to parse game_mode_intervention.list fps.");
               return false;
             }
diff --git a/src/traced/probes/android_log/android_log_data_source.cc b/src/traced/probes/android_log/android_log_data_source.cc
index 2d4d264..f53cda5 100644
--- a/src/traced/probes/android_log/android_log_data_source.cc
+++ b/src/traced/probes/android_log/android_log_data_source.cc
@@ -15,12 +15,12 @@
  */
 
 #include "src/traced/probes/android_log/android_log_data_source.h"
+#include <optional>
 
 #include "perfetto/base/logging.h"
 #include "perfetto/base/task_runner.h"
 #include "perfetto/base/time.h"
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/string_splitter.h"
 #include "perfetto/ext/base/string_view.h"
diff --git a/src/traced/probes/android_system_property/android_system_property_data_source.cc b/src/traced/probes/android_system_property/android_system_property_data_source.cc
index b9ba2b8..2cf351e 100644
--- a/src/traced/probes/android_system_property/android_system_property_data_source.cc
+++ b/src/traced/probes/android_system_property/android_system_property_data_source.cc
@@ -15,11 +15,11 @@
  */
 
 #include "src/traced/probes/android_system_property/android_system_property_data_source.h"
+#include <optional>
 
 #include "perfetto/base/task_runner.h"
 #include "perfetto/base/time.h"
 #include "perfetto/ext/base/android_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/tracing/core/data_source_config.h"
 
@@ -100,7 +100,7 @@
   packet->set_timestamp(static_cast<uint64_t>(base::GetBootTimeNs().count()));
   auto* properties = packet->set_android_system_property();
   for (const auto& name : property_names_) {
-    const base::Optional<std::string> value = ReadProperty(name);
+    const std::optional<std::string> value = ReadProperty(name);
     if (value) {
       auto* property = properties->add_values();
       property->set_name(name);
@@ -118,20 +118,20 @@
 }
 
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-const base::Optional<std::string> AndroidSystemPropertyDataSource::ReadProperty(
+const std::optional<std::string> AndroidSystemPropertyDataSource::ReadProperty(
     const std::string& name) {
   std::string value = base::GetAndroidProp(name.c_str());
   if (value.empty()) {
     PERFETTO_LOG("Unable to read %s", name.c_str());
-    return base::nullopt;
+    return std::nullopt;
   }
-  return base::make_optional(value);
+  return std::make_optional(value);
 }
 #else
-const base::Optional<std::string> AndroidSystemPropertyDataSource::ReadProperty(
+const std::optional<std::string> AndroidSystemPropertyDataSource::ReadProperty(
     const std::string&) {
   PERFETTO_ELOG("Android System Properties only supported on Android.");
-  return base::nullopt;
+  return std::nullopt;
 }
 #endif
 
diff --git a/src/traced/probes/android_system_property/android_system_property_data_source.h b/src/traced/probes/android_system_property/android_system_property_data_source.h
index ec7db0e..04dd3e5 100644
--- a/src/traced/probes/android_system_property/android_system_property_data_source.h
+++ b/src/traced/probes/android_system_property/android_system_property_data_source.h
@@ -18,9 +18,9 @@
 #define SRC_TRACED_PROBES_ANDROID_SYSTEM_PROPERTY_ANDROID_SYSTEM_PROPERTY_DATA_SOURCE_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/weak_ptr.h"
 #include "perfetto/ext/tracing/core/trace_writer.h"
 #include "src/traced/probes/probes_data_source.h"
@@ -45,7 +45,7 @@
   void Flush(FlushRequestID, std::function<void()> callback) override;
 
   // Virtual for testing.
-  virtual const base::Optional<std::string> ReadProperty(
+  virtual const std::optional<std::string> ReadProperty(
       const std::string& name);
 
  private:
diff --git a/src/traced/probes/android_system_property/android_system_property_data_source_unittest.cc b/src/traced/probes/android_system_property/android_system_property_data_source_unittest.cc
index 89d89e6..0014e49 100644
--- a/src/traced/probes/android_system_property/android_system_property_data_source_unittest.cc
+++ b/src/traced/probes/android_system_property/android_system_property_data_source_unittest.cc
@@ -45,7 +45,7 @@
                                         std::move(writer)) {}
 
   MOCK_METHOD1(ReadProperty,
-               const base::Optional<std::string>(const std::string&));
+               const std::optional<std::string>(const std::string&));
 };
 
 class AndroidSystemPropertyDataSourceTest : public ::testing::Test {
@@ -79,9 +79,9 @@
   auto data_source = CreateAndroidSystemPropertyDataSource(BuildConfig(
       {"debug.tracing.screen_state", "debug.tracing.screen_brightness"}));
   EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_state"))
-      .WillOnce(Return(base::make_optional("2")));
+      .WillOnce(Return(std::make_optional("2")));
   EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_brightness"))
-      .WillOnce(Return(base::make_optional("0.123456")));
+      .WillOnce(Return(std::make_optional("0.123456")));
   data_source->Start();
 
   protos::gen::TracePacket packet = writer_raw_->GetOnlyTracePacket();
@@ -112,9 +112,9 @@
   auto data_source = CreateAndroidSystemPropertyDataSource(BuildConfig(
       {"debug.tracing.screen_state", "debug.tracing.screen_brightness"}));
   EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_state"))
-      .WillOnce(Return(base::nullopt));
+      .WillOnce(Return(std::nullopt));
   EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_brightness"))
-      .WillOnce(Return(base::nullopt));
+      .WillOnce(Return(std::nullopt));
   data_source->Start();
 
   protos::gen::TracePacket packet = writer_raw_->GetOnlyTracePacket();
diff --git a/src/traced/probes/ftrace/atrace_wrapper.cc b/src/traced/probes/ftrace/atrace_wrapper.cc
index 632c131..7254325 100644
--- a/src/traced/probes/ftrace/atrace_wrapper.cc
+++ b/src/traced/probes/ftrace/atrace_wrapper.cc
@@ -24,12 +24,12 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
+#include <optional>
 
 #include "perfetto/base/build_config.h"
 #include "perfetto/base/logging.h"
 #include "perfetto/base/time.h"
 #include "perfetto/ext/base/android_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/pipe.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/utils.h"
@@ -39,7 +39,7 @@
 namespace {
 
 RunAtraceFunction g_run_atrace_for_testing = nullptr;
-base::Optional<bool> g_is_old_atrace_for_testing{};
+std::optional<bool> g_is_old_atrace_for_testing{};
 
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
 // Args should include "atrace" for argv[0].
diff --git a/src/traced/probes/ftrace/compact_sched.cc b/src/traced/probes/ftrace/compact_sched.cc
index cd2d117..16cb848 100644
--- a/src/traced/probes/ftrace/compact_sched.cc
+++ b/src/traced/probes/ftrace/compact_sched.cc
@@ -17,8 +17,8 @@
 #include "src/traced/probes/ftrace/compact_sched.h"
 
 #include <stdint.h>
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
 #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
 #include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
 #include "protos/perfetto/trace/ftrace/sched.pbzero.h"
@@ -32,7 +32,7 @@
 // Pre-parse the format of sched_switch, checking if our simplifying
 // assumptions about possible widths/signedness hold, and record the subset
 // of the format that will be used during parsing.
-base::Optional<CompactSchedSwitchFormat> ValidateSchedSwitchFormat(
+std::optional<CompactSchedSwitchFormat> ValidateSchedSwitchFormat(
     const Event& event) {
   using protos::pbzero::SchedSwitchFtraceEvent;
 
@@ -85,15 +85,15 @@
 
   if (!prev_state_valid || !next_pid_valid || !next_prio_valid ||
       !next_comm_valid) {
-    return base::nullopt;
+    return std::nullopt;
   }
-  return base::make_optional(switch_format);
+  return std::make_optional(switch_format);
 }
 
 // Pre-parse the format of sched_waking, checking if our simplifying
 // assumptions about possible widths/signedness hold, and record the subset
 // of the format that will be used during parsing.
-base::Optional<CompactSchedWakingFormat> ValidateSchedWakingFormat(
+std::optional<CompactSchedWakingFormat> ValidateSchedWakingFormat(
     const Event& event) {
   using protos::pbzero::SchedWakingFtraceEvent;
 
@@ -143,9 +143,9 @@
   }
 
   if (!pid_valid || !target_cpu_valid || !prio_valid || !comm_valid) {
-    return base::nullopt;
+    return std::nullopt;
   }
-  return base::make_optional(waking_format);
+  return std::make_optional(waking_format);
 }
 
 }  // namespace
@@ -157,8 +157,8 @@
     const std::vector<Event>& events) {
   using protos::pbzero::FtraceEvent;
 
-  base::Optional<CompactSchedSwitchFormat> switch_format;
-  base::Optional<CompactSchedWakingFormat> waking_format;
+  std::optional<CompactSchedSwitchFormat> switch_format;
+  std::optional<CompactSchedWakingFormat> waking_format;
   for (const Event& event : events) {
     if (event.proto_field_id == FtraceEvent::kSchedSwitchFieldNumber) {
       switch_format = ValidateSchedSwitchFormat(event);
diff --git a/src/traced/probes/ftrace/cpu_reader.cc b/src/traced/probes/ftrace/cpu_reader.cc
index b4c1758..c38627c 100644
--- a/src/traced/probes/ftrace/cpu_reader.cc
+++ b/src/traced/probes/ftrace/cpu_reader.cc
@@ -21,12 +21,12 @@
 #include <signal.h>
 
 #include <algorithm>
+#include <optional>
 #include <utility>
 
 #include "perfetto/base/build_config.h"
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/metatrace.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_splitter.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/utils.h"
@@ -267,7 +267,7 @@
       // prematurely.
       static constexpr size_t kRoughlyAPage = base::kPageSize - 512;
       const uint8_t* scratch_ptr = curr_page;
-      base::Optional<PageHeader> hdr =
+      std::optional<PageHeader> hdr =
           ParsePageHeader(&scratch_ptr, table_->page_header_size_len());
       PERFETTO_DCHECK(hdr && hdr->size > 0 && hdr->size <= base::kPageSize);
       if (!hdr.has_value()) {
@@ -426,7 +426,7 @@
     const uint8_t* curr_page = parsing_buf + (pages_parsed * base::kPageSize);
     const uint8_t* curr_page_end = curr_page + base::kPageSize;
     const uint8_t* parse_pos = curr_page;
-    base::Optional<PageHeader> page_header =
+    std::optional<PageHeader> page_header =
         ParsePageHeader(&parse_pos, table->page_header_size_len());
 
     if (!page_header.has_value() || page_header->size == 0 ||
@@ -477,7 +477,7 @@
 // flag (RB_MISSED_STORED).
 //
 // static
-base::Optional<CpuReader::PageHeader> CpuReader::ParsePageHeader(
+std::optional<CpuReader::PageHeader> CpuReader::ParsePageHeader(
     const uint8_t** ptr,
     uint16_t page_header_size_len) {
   // Mask for the data length portion of the |commit| field. Note that the
@@ -493,7 +493,7 @@
   PageHeader page_header;
   if (!CpuReader::ReadAndAdvance<uint64_t>(ptr, end_of_page,
                                            &page_header.timestamp))
-    return base::nullopt;
+    return std::nullopt;
 
   uint32_t size_and_flags;
 
@@ -501,7 +501,7 @@
   // number later.
   if (!CpuReader::ReadAndAdvance<uint32_t>(
           ptr, end_of_page, base::AssumeLittleEndian(&size_and_flags)))
-    return base::nullopt;
+    return std::nullopt;
 
   page_header.size = size_and_flags & kDataSizeMask;
   page_header.lost_events = bool(size_and_flags & kMissedEventsFlag);
@@ -513,7 +513,7 @@
   PERFETTO_DCHECK(page_header_size_len >= 4);
   *ptr += page_header_size_len - 4;
 
-  return base::make_optional(page_header);
+  return std::make_optional(page_header);
 }
 
 // A raw ftrace buffer page consists of a header followed by a sequence of
diff --git a/src/traced/probes/ftrace/cpu_reader.h b/src/traced/probes/ftrace/cpu_reader.h
index e0953d6..91e54ee 100644
--- a/src/traced/probes/ftrace/cpu_reader.h
+++ b/src/traced/probes/ftrace/cpu_reader.h
@@ -23,10 +23,10 @@
 #include <array>
 #include <atomic>
 #include <memory>
+#include <optional>
 #include <set>
 #include <thread>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/paged_memory.h"
 #include "perfetto/ext/base/pipe.h"
 #include "perfetto/ext/base/scoped_file.h"
@@ -174,7 +174,7 @@
   }
 
   // Returns a parsed representation of the given raw ftrace page's header.
-  static base::Optional<CpuReader::PageHeader> ParsePageHeader(
+  static std::optional<CpuReader::PageHeader> ParsePageHeader(
       const uint8_t** ptr,
       uint16_t page_header_size_len);
 
diff --git a/src/traced/probes/ftrace/cpu_reader_benchmark.cc b/src/traced/probes/ftrace/cpu_reader_benchmark.cc
index a029bc7..8b487b6 100644
--- a/src/traced/probes/ftrace/cpu_reader_benchmark.cc
+++ b/src/traced/probes/ftrace/cpu_reader_benchmark.cc
@@ -823,7 +823,7 @@
 
 void DoParse(const ExamplePage& test_case,
              const std::vector<GroupAndName>& enabled_events,
-             base::Optional<FtraceConfig::PrintFilter> print_filter,
+             std::optional<FtraceConfig::PrintFilter> print_filter,
              benchmark::State& state) {
   ScatteredStreamWriterNullDelegate delegate(base::kPageSize);
   ScatteredStreamWriter stream(&delegate);
@@ -835,7 +835,7 @@
   FtraceDataSourceConfig ds_config{EventFilter{},
                                    EventFilter{},
                                    DisabledCompactSchedConfigForTesting(),
-                                   base::nullopt,
+                                   std::nullopt,
                                    {},
                                    {},
                                    false /*symbolize_ksyms*/,
@@ -858,7 +858,7 @@
     std::unique_ptr<CompactSchedBuffer> compact_buffer(
         new CompactSchedBuffer());
     const uint8_t* parse_pos = page.get();
-    base::Optional<CpuReader::PageHeader> page_header =
+    std::optional<CpuReader::PageHeader> page_header =
         CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
 
     if (!page_header.has_value())
@@ -874,12 +874,12 @@
 
 void BM_ParsePageFullOfSchedSwitch(benchmark::State& state) {
   DoParse(g_full_page_sched_switch, {GroupAndName("sched", "sched_switch")},
-          base::nullopt, state);
+          std::nullopt, state);
 }
 BENCHMARK(BM_ParsePageFullOfSchedSwitch);
 
 void BM_ParsePageFullOfPrint(benchmark::State& state) {
-  DoParse(g_full_page_print, {GroupAndName("ftrace", "print")}, base::nullopt,
+  DoParse(g_full_page_print, {GroupAndName("ftrace", "print")}, std::nullopt,
           state);
 }
 BENCHMARK(BM_ParsePageFullOfPrint);
@@ -898,7 +898,7 @@
 
 void BM_ParsePageFullOfAtracePrint(benchmark::State& state) {
   DoParse(g_full_page_atrace_print, {GroupAndName("ftrace", "print")},
-          base::nullopt, state);
+          std::nullopt, state);
 }
 BENCHMARK(BM_ParsePageFullOfAtracePrint);
 
diff --git a/src/traced/probes/ftrace/cpu_reader_fuzzer.cc b/src/traced/probes/ftrace/cpu_reader_fuzzer.cc
index 76908c9..f9dd522 100644
--- a/src/traced/probes/ftrace/cpu_reader_fuzzer.cc
+++ b/src/traced/probes/ftrace/cpu_reader_fuzzer.cc
@@ -57,7 +57,7 @@
   FtraceDataSourceConfig ds_config{EventFilter{},
                                    EventFilter{},
                                    DisabledCompactSchedConfigForTesting(),
-                                   base::nullopt,
+                                   std::nullopt,
                                    {},
                                    {},
                                    /*symbolize_ksyms=*/false,
diff --git a/src/traced/probes/ftrace/cpu_reader_unittest.cc b/src/traced/probes/ftrace/cpu_reader_unittest.cc
index 2466109..ba77921 100644
--- a/src/traced/probes/ftrace/cpu_reader_unittest.cc
+++ b/src/traced/probes/ftrace/cpu_reader_unittest.cc
@@ -68,7 +68,7 @@
   return FtraceDataSourceConfig{EventFilter{},
                                 EventFilter{},
                                 DisabledCompactSchedConfigForTesting(),
-                                base::nullopt,
+                                std::nullopt,
                                 {},
                                 {},
                                 false /*symbolize_ksyms*/,
@@ -393,7 +393,7 @@
   FtraceMetadata metadata{};
   std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
   const uint8_t* parse_pos = page.get();
-  base::Optional<CpuReader::PageHeader> page_header =
+  std::optional<CpuReader::PageHeader> page_header =
       CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
 
   const uint8_t* page_end = page.get() + base::kPageSize;
@@ -521,7 +521,7 @@
   std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
 
   const uint8_t* parse_pos = page.get();
-  base::Optional<CpuReader::PageHeader> page_header =
+  std::optional<CpuReader::PageHeader> page_header =
       CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
 
   const uint8_t* page_end = page.get() + base::kPageSize;
@@ -569,7 +569,7 @@
   FtraceMetadata metadata{};
   std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
   const uint8_t* parse_pos = page.get();
-  base::Optional<CpuReader::PageHeader> page_header =
+  std::optional<CpuReader::PageHeader> page_header =
       CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
 
   const uint8_t* page_end = page.get() + base::kPageSize;
@@ -617,7 +617,7 @@
   FtraceMetadata metadata{};
   std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
   const uint8_t* parse_pos = page.get();
-  base::Optional<CpuReader::PageHeader> page_header =
+  std::optional<CpuReader::PageHeader> page_header =
       CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
 
   const uint8_t* page_end = page.get() + base::kPageSize;
@@ -653,7 +653,7 @@
   FtraceMetadata metadata{};
   std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
   const uint8_t* parse_pos = page.get();
-  base::Optional<CpuReader::PageHeader> page_header =
+  std::optional<CpuReader::PageHeader> page_header =
       CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
 
   ASSERT_TRUE(page_header.has_value());
@@ -718,7 +718,7 @@
   FtraceMetadata metadata{};
   std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
   const uint8_t* parse_pos = page.get();
-  base::Optional<CpuReader::PageHeader> page_header =
+  std::optional<CpuReader::PageHeader> page_header =
       CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
 
   const uint8_t* page_end = page.get() + base::kPageSize;
@@ -767,7 +767,7 @@
   FtraceMetadata metadata{};
   std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
   const uint8_t* parse_pos = page.get();
-  base::Optional<CpuReader::PageHeader> page_header =
+  std::optional<CpuReader::PageHeader> page_header =
       CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
 
   const uint8_t* page_end = page.get() + base::kPageSize;
@@ -907,7 +907,7 @@
   FtraceMetadata metadata{};
   std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
   const uint8_t* parse_pos = page.get();
-  base::Optional<CpuReader::PageHeader> page_header =
+  std::optional<CpuReader::PageHeader> page_header =
       CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
 
   const uint8_t* page_end = page.get() + base::kPageSize;
@@ -948,7 +948,7 @@
   FtraceDataSourceConfig ds_config{EventFilter{},
                                    EventFilter{},
                                    EnabledCompactSchedConfigForTesting(),
-                                   base::nullopt,
+                                   std::nullopt,
                                    {},
                                    {},
                                    false /* symbolize_ksyms*/,
@@ -960,7 +960,7 @@
   FtraceMetadata metadata{};
   std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
   const uint8_t* parse_pos = page.get();
-  base::Optional<CpuReader::PageHeader> page_header =
+  std::optional<CpuReader::PageHeader> page_header =
       CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
 
   const uint8_t* page_end = page.get() + base::kPageSize;
@@ -1705,7 +1705,7 @@
   FtraceMetadata metadata{};
   std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
   const uint8_t* parse_pos = page.get();
-  base::Optional<CpuReader::PageHeader> page_header =
+  std::optional<CpuReader::PageHeader> page_header =
       CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
 
   const uint8_t* page_end = page.get() + base::kPageSize;
@@ -2193,7 +2193,7 @@
   FtraceMetadata metadata{};
   std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
   const uint8_t* parse_pos = page.get();
-  base::Optional<CpuReader::PageHeader> page_header =
+  std::optional<CpuReader::PageHeader> page_header =
       CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
 
   const uint8_t* page_end = page.get() + base::kPageSize;
@@ -2281,7 +2281,7 @@
   FtraceMetadata metadata{};
   std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
   const uint8_t* parse_pos = page.get();
-  base::Optional<CpuReader::PageHeader> page_header =
+  std::optional<CpuReader::PageHeader> page_header =
       CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
   ASSERT_TRUE(page_header.has_value());
 
@@ -2725,7 +2725,7 @@
   FtraceMetadata metadata{};
   std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
   const uint8_t* parse_pos = page.get();
-  base::Optional<CpuReader::PageHeader> page_header =
+  std::optional<CpuReader::PageHeader> page_header =
       CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
 
   const uint8_t* page_end = page.get() + base::kPageSize;
@@ -2834,7 +2834,7 @@
   FtraceMetadata metadata{};
   std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
   const uint8_t* parse_pos = page.get();
-  base::Optional<CpuReader::PageHeader> page_header =
+  std::optional<CpuReader::PageHeader> page_header =
       CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
 
   const uint8_t* page_end = page.get() + base::kPageSize;
@@ -3140,7 +3140,7 @@
   FtraceMetadata metadata{};
   std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
   const uint8_t* parse_pos = page.get();
-  base::Optional<CpuReader::PageHeader> page_header =
+  std::optional<CpuReader::PageHeader> page_header =
       CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
 
   const uint8_t* page_end = page.get() + base::kPageSize;
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer.cc b/src/traced/probes/ftrace/ftrace_config_muxer.cc
index 61a26dd..0be1842 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer.cc
+++ b/src/traced/probes/ftrace/ftrace_config_muxer.cc
@@ -523,7 +523,7 @@
   }
 
   for (const std::string& syscall : request.syscall_events()) {
-    base::Optional<size_t> id = syscalls_.GetByName(syscall);
+    std::optional<size_t> id = syscalls_.GetByName(syscall);
     if (!id.has_value()) {
       PERFETTO_ELOG("Can't enable %s, syscall not known", syscall.c_str());
       continue;
@@ -744,7 +744,7 @@
   auto compact_sched =
       CreateCompactSchedConfig(request, table_->compact_sched_format());
 
-  base::Optional<FtracePrintFilterConfig> ftrace_print_filter;
+  std::optional<FtracePrintFilterConfig> ftrace_print_filter;
   if (request.has_print_filter()) {
     ftrace_print_filter =
         FtracePrintFilterConfig::Create(request.print_filter(), table_);
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer.h b/src/traced/probes/ftrace/ftrace_config_muxer.h
index 49a5989..67176b2 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer.h
+++ b/src/traced/probes/ftrace/ftrace_config_muxer.h
@@ -18,9 +18,9 @@
 #define SRC_TRACED_PROBES_FTRACE_FTRACE_CONFIG_MUXER_H_
 
 #include <map>
+#include <optional>
 #include <set>
 
-#include "perfetto/ext/base/optional.h"
 #include "src/kernel_utils/syscall_table.h"
 #include "src/traced/probes/ftrace/compact_sched.h"
 #include "src/traced/probes/ftrace/ftrace_config_utils.h"
@@ -44,7 +44,7 @@
   FtraceDataSourceConfig(EventFilter _event_filter,
                          EventFilter _syscall_filter,
                          CompactSchedConfig _compact_sched,
-                         base::Optional<FtracePrintFilterConfig> _print_filter,
+                         std::optional<FtracePrintFilterConfig> _print_filter,
                          std::vector<std::string> _atrace_apps,
                          std::vector<std::string> _atrace_categories,
                          bool _symbolize_ksyms,
@@ -72,7 +72,7 @@
 
   // Optional configuration that's used to filter "ftrace/print" events based on
   // the content of their "buf" field.
-  base::Optional<FtracePrintFilterConfig> print_filter;
+  std::optional<FtracePrintFilterConfig> print_filter;
 
   // Used only in Android for ATRACE_EVENT/os.Trace() userspace annotations.
   std::vector<std::string> atrace_apps;
diff --git a/src/traced/probes/ftrace/ftrace_controller.cc b/src/traced/probes/ftrace/ftrace_controller.cc
index 49d4080..907e772 100644
--- a/src/traced/probes/ftrace/ftrace_controller.cc
+++ b/src/traced/probes/ftrace/ftrace_controller.cc
@@ -96,13 +96,13 @@
   return !!fd;
 }
 
-base::Optional<int64_t> ReadFtraceNowTs(const base::ScopedFile& cpu_stats_fd) {
+std::optional<int64_t> ReadFtraceNowTs(const base::ScopedFile& cpu_stats_fd) {
   PERFETTO_CHECK(cpu_stats_fd);
 
   char buf[512];
   ssize_t res = PERFETTO_EINTR(pread(*cpu_stats_fd, buf, sizeof(buf) - 1, 0));
   if (res <= 0)
-    return base::nullopt;
+    return std::nullopt;
   buf[res] = '\0';
 
   FtraceCpuStats stats{};
@@ -635,7 +635,7 @@
 // TODO(rsavitski): dedupe with FtraceController::Create.
 std::unique_ptr<FtraceController::FtraceInstanceState>
 FtraceController::CreateSecondaryInstance(const std::string& instance_name) {
-  base::Optional<std::string> instance_path = AbsolutePathForInstance(
+  std::optional<std::string> instance_path = AbsolutePathForInstance(
       primary_.ftrace_procfs->GetRootPath(), instance_name);
   if (!instance_path.has_value()) {
     PERFETTO_ELOG("Invalid ftrace instance name: \"%s\"",
@@ -675,12 +675,12 @@
 // to be careful to distinguish the tracefs mount point from the default
 // instance path.
 // static
-base::Optional<std::string> FtraceController::AbsolutePathForInstance(
+std::optional<std::string> FtraceController::AbsolutePathForInstance(
     const std::string& tracefs_root,
     const std::string& raw_cfg_name) {
   if (base::Contains(raw_cfg_name, '/') ||
       base::StartsWith(raw_cfg_name, "..")) {
-    return base::nullopt;
+    return std::nullopt;
   }
 
   // ARM64 pKVM hypervisor tracing emulates an instance, but is not under
@@ -690,7 +690,7 @@
     PERFETTO_LOG(
         "Config specified reserved \"hyp\" instance name, using %s for events.",
         hyp_path.c_str());
-    return base::make_optional(hyp_path);
+    return std::make_optional(hyp_path);
   }
 
   return tracefs_root + "instances/" + raw_cfg_name + "/";
diff --git a/src/traced/probes/ftrace/ftrace_controller.h b/src/traced/probes/ftrace/ftrace_controller.h
index 9318f2a..e4f3848 100644
--- a/src/traced/probes/ftrace/ftrace_controller.h
+++ b/src/traced/probes/ftrace/ftrace_controller.h
@@ -88,7 +88,7 @@
   }
 
   // public for testing
-  static base::Optional<std::string> AbsolutePathForInstance(
+  static std::optional<std::string> AbsolutePathForInstance(
       const std::string& tracefs_root,
       const std::string& raw_cfg_name);
 
diff --git a/src/traced/probes/ftrace/ftrace_controller_unittest.cc b/src/traced/probes/ftrace/ftrace_controller_unittest.cc
index 0d41004..02bb3cf 100644
--- a/src/traced/probes/ftrace/ftrace_controller_unittest.cc
+++ b/src/traced/probes/ftrace/ftrace_controller_unittest.cc
@@ -756,7 +756,7 @@
 }
 
 TEST(FtraceControllerTest, TracefsInstanceFilepaths) {
-  base::Optional<std::string> path;
+  std::optional<std::string> path;
   path = FtraceController::AbsolutePathForInstance("/root/", "test");
   EXPECT_EQ(*path, "/root/instances/test/");
 
diff --git a/src/traced/probes/ftrace/ftrace_print_filter.cc b/src/traced/probes/ftrace/ftrace_print_filter.cc
index 5080fca..316a017 100644
--- a/src/traced/probes/ftrace/ftrace_print_filter.cc
+++ b/src/traced/probes/ftrace/ftrace_print_filter.cc
@@ -108,12 +108,12 @@
 }
 
 // static
-base::Optional<FtracePrintFilterConfig> FtracePrintFilterConfig::Create(
+std::optional<FtracePrintFilterConfig> FtracePrintFilterConfig::Create(
     const protos::gen::FtraceConfig::PrintFilter& config,
     ProtoTranslationTable* table) {
   const Event* print_event = table->GetEvent(GroupAndName("ftrace", "print"));
   if (!print_event) {
-    return base::nullopt;
+    return std::nullopt;
   }
   const Field* buf_field = nullptr;
   for (const Field& field : print_event->fields) {
@@ -123,11 +123,11 @@
     }
   }
   if (!buf_field) {
-    return base::nullopt;
+    return std::nullopt;
   }
 
   if (buf_field->strategy != kCStringToString) {
-    return base::nullopt;
+    return std::nullopt;
   }
   FtracePrintFilterConfig ret{FtracePrintFilter{config}};
   ret.event_id_ = print_event->ftrace_event_id;
diff --git a/src/traced/probes/ftrace/ftrace_print_filter.h b/src/traced/probes/ftrace/ftrace_print_filter.h
index 707bb3e..419bcbf 100644
--- a/src/traced/probes/ftrace/ftrace_print_filter.h
+++ b/src/traced/probes/ftrace/ftrace_print_filter.h
@@ -17,10 +17,10 @@
 #ifndef SRC_TRACED_PROBES_FTRACE_FTRACE_PRINT_FILTER_H_
 #define SRC_TRACED_PROBES_FTRACE_FTRACE_PRINT_FILTER_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
-#include "perfetto/ext/base/optional.h"
 #include "src/traced/probes/ftrace/proto_translation_table.h"
 
 namespace perfetto {
@@ -62,7 +62,7 @@
 
 class FtracePrintFilterConfig {
  public:
-  static base::Optional<FtracePrintFilterConfig> Create(
+  static std::optional<FtracePrintFilterConfig> Create(
       const protos::gen::FtraceConfig_PrintFilter&,
       ProtoTranslationTable* table);
 
diff --git a/src/traced/probes/ftrace/ftrace_procfs.cc b/src/traced/probes/ftrace/ftrace_procfs.cc
index 7cf3b07..6112487 100644
--- a/src/traced/probes/ftrace/ftrace_procfs.cc
+++ b/src/traced/probes/ftrace/ftrace_procfs.cc
@@ -590,7 +590,7 @@
   if (str.size() && str[str.size() - 1] == '\n')
     str.resize(str.size() - 1);
 
-  base::Optional<uint32_t> id = base::StringToUInt32(str);
+  std::optional<uint32_t> id = base::StringToUInt32(str);
   if (!id)
     return 0;
   return *id;
diff --git a/src/traced/probes/ftrace/printk_formats_parser.cc b/src/traced/probes/ftrace/printk_formats_parser.cc
index 9a36dab..99dc856 100644
--- a/src/traced/probes/ftrace/printk_formats_parser.cc
+++ b/src/traced/probes/ftrace/printk_formats_parser.cc
@@ -19,10 +19,10 @@
 #include <stdio.h>
 
 #include <cinttypes>
+#include <optional>
 
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_splitter.h"
 #include "perfetto/ext/base/string_utils.h"
 
@@ -52,7 +52,7 @@
     if (name.empty())
       continue;
 
-    base::Optional<uint64_t> address = base::StringToUInt64(raw_address, 16);
+    std::optional<uint64_t> address = base::StringToUInt64(raw_address, 16);
     if (address && address.value() != 0)
       mapping.insert(address.value(), name);
   }
diff --git a/src/traced/probes/initial_display_state/initial_display_state_data_source.cc b/src/traced/probes/initial_display_state/initial_display_state_data_source.cc
index d08cfd4..f7d3e58 100644
--- a/src/traced/probes/initial_display_state/initial_display_state_data_source.cc
+++ b/src/traced/probes/initial_display_state/initial_display_state_data_source.cc
@@ -15,11 +15,11 @@
  */
 
 #include "src/traced/probes/initial_display_state/initial_display_state_data_source.h"
+#include <optional>
 
 #include "perfetto/base/task_runner.h"
 #include "perfetto/base/time.h"
 #include "perfetto/ext/base/android_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/tracing/core/data_source_config.h"
 
@@ -87,15 +87,15 @@
 void InitialDisplayStateDataSource::WriteState() {
   auto packet = writer_->NewTracePacket();
   packet->set_timestamp(static_cast<uint64_t>(base::GetBootTimeNs().count()));
-  const base::Optional<std::string> screen_state_str =
+  const std::optional<std::string> screen_state_str =
       ReadProperty("debug.tracing.screen_state");
-  const base::Optional<std::string> screen_brightness_str =
+  const std::optional<std::string> screen_brightness_str =
       ReadProperty("debug.tracing.screen_brightness");
-  const base::Optional<int> screen_state =
-      screen_state_str ? base::StringToInt32(*screen_state_str) : base::nullopt;
-  const base::Optional<double> screen_brightness =
+  const std::optional<int> screen_state =
+      screen_state_str ? base::StringToInt32(*screen_state_str) : std::nullopt;
+  const std::optional<double> screen_brightness =
       screen_brightness_str ? base::StringToDouble(*screen_brightness_str)
-                            : base::nullopt;
+                            : std::nullopt;
   if (screen_state || screen_brightness) {
     auto* state = packet->set_initial_display_state();
     if (screen_state) {
@@ -116,20 +116,20 @@
 }
 
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-const base::Optional<std::string> InitialDisplayStateDataSource::ReadProperty(
+const std::optional<std::string> InitialDisplayStateDataSource::ReadProperty(
     const std::string name) {
   std::string value = base::GetAndroidProp(name.c_str());
   if (value.empty()) {
     PERFETTO_ELOG("Unable to read %s", name.c_str());
-    return base::nullopt;
+    return std::nullopt;
   }
-  return base::make_optional(value);
+  return std::make_optional(value);
 }
 #else
-const base::Optional<std::string> InitialDisplayStateDataSource::ReadProperty(
+const std::optional<std::string> InitialDisplayStateDataSource::ReadProperty(
     const std::string name __attribute__((unused))) {
   PERFETTO_ELOG("Initial display state only supported on Android.");
-  return base::nullopt;
+  return std::nullopt;
 }
 #endif
 
diff --git a/src/traced/probes/initial_display_state/initial_display_state_data_source.h b/src/traced/probes/initial_display_state/initial_display_state_data_source.h
index b235c75..acb8789 100644
--- a/src/traced/probes/initial_display_state/initial_display_state_data_source.h
+++ b/src/traced/probes/initial_display_state/initial_display_state_data_source.h
@@ -18,8 +18,8 @@
 #define SRC_TRACED_PROBES_INITIAL_DISPLAY_STATE_INITIAL_DISPLAY_STATE_DATA_SOURCE_H_
 
 #include <memory>
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/weak_ptr.h"
 #include "perfetto/ext/tracing/core/trace_writer.h"
 #include "src/traced/probes/probes_data_source.h"
@@ -44,8 +44,7 @@
   void Flush(FlushRequestID, std::function<void()> callback) override;
 
   // Virtual for testing.
-  virtual const base::Optional<std::string> ReadProperty(
-      const std::string name);
+  virtual const std::optional<std::string> ReadProperty(const std::string name);
 
  private:
   void Tick();
diff --git a/src/traced/probes/initial_display_state/initial_display_state_data_source_unittest.cc b/src/traced/probes/initial_display_state/initial_display_state_data_source_unittest.cc
index f851ae6..6cb5f86 100644
--- a/src/traced/probes/initial_display_state/initial_display_state_data_source_unittest.cc
+++ b/src/traced/probes/initial_display_state/initial_display_state_data_source_unittest.cc
@@ -41,7 +41,7 @@
                                       std::move(writer)) {}
 
   MOCK_METHOD1(ReadProperty,
-               const base::Optional<std::string>(const std::string));
+               const std::optional<std::string>(const std::string));
 };
 
 class InitialDisplayStateDataSourceTest : public ::testing::Test {
@@ -65,9 +65,9 @@
   ASSERT_TRUE(true);
   auto data_source = GetInitialDisplayStateDataSource(DataSourceConfig());
   EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_state"))
-      .WillOnce(Return(base::make_optional("2")));
+      .WillOnce(Return(std::make_optional("2")));
   EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_brightness"))
-      .WillOnce(Return(base::make_optional("0.123456")));
+      .WillOnce(Return(std::make_optional("0.123456")));
   data_source->Start();
 
   protos::gen::TracePacket packet = writer_raw_->GetOnlyTracePacket();
@@ -81,9 +81,9 @@
   ASSERT_TRUE(true);
   auto data_source = GetInitialDisplayStateDataSource(DataSourceConfig());
   EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_state"))
-      .WillOnce(Return(base::make_optional("2")));
+      .WillOnce(Return(std::make_optional("2")));
   EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_brightness"))
-      .WillOnce(Return(base::make_optional("gotta wear shades")));
+      .WillOnce(Return(std::make_optional("gotta wear shades")));
   data_source->Start();
 
   protos::gen::TracePacket packet = writer_raw_->GetOnlyTracePacket();
@@ -97,9 +97,9 @@
   ASSERT_TRUE(true);
   auto data_source = GetInitialDisplayStateDataSource(DataSourceConfig());
   EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_state"))
-      .WillOnce(Return(base::nullopt));
+      .WillOnce(Return(std::nullopt));
   EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_brightness"))
-      .WillOnce(Return(base::nullopt));
+      .WillOnce(Return(std::nullopt));
   data_source->Start();
 
   protos::gen::TracePacket packet = writer_raw_->GetOnlyTracePacket();
diff --git a/src/traced/probes/power/android_power_data_source.cc b/src/traced/probes/power/android_power_data_source.cc
index 3f2866e..c67a8b2 100644
--- a/src/traced/probes/power/android_power_data_source.cc
+++ b/src/traced/probes/power/android_power_data_source.cc
@@ -16,12 +16,12 @@
 
 #include "src/traced/probes/power/android_power_data_source.h"
 
+#include <optional>
 #include <vector>
 
 #include "perfetto/base/logging.h"
 #include "perfetto/base/task_runner.h"
 #include "perfetto/base/time.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/tracing/core/trace_packet.h"
 #include "perfetto/ext/tracing/core/trace_writer.h"
@@ -70,13 +70,13 @@
   PERFETTO_LAZY_LOAD(android_internal::GetPowerEntityStateResidency,
                      get_power_entity_state_residency_);
 
-  base::Optional<int64_t> GetCounter(android_internal::BatteryCounter counter) {
+  std::optional<int64_t> GetCounter(android_internal::BatteryCounter counter) {
     if (!get_battery_counter_)
-      return base::nullopt;
+      return std::nullopt;
     int64_t value = 0;
     if (get_battery_counter_(counter, &value))
-      return base::make_optional(value);
-    return base::nullopt;
+      return std::make_optional(value);
+    return std::nullopt;
   }
 
   std::vector<android_internal::RailDescriptor> GetRailDescriptors() {
diff --git a/src/traced/probes/power/linux_power_sysfs_data_source.cc b/src/traced/probes/power/linux_power_sysfs_data_source.cc
index 9d4365b..ceeeec7 100644
--- a/src/traced/probes/power/linux_power_sysfs_data_source.cc
+++ b/src/traced/probes/power/linux_power_sysfs_data_source.cc
@@ -18,12 +18,12 @@
 
 #include <dirent.h>
 #include <sys/types.h>
+#include <optional>
 
 #include "perfetto/base/logging.h"
 #include "perfetto/base/task_runner.h"
 #include "perfetto/base/time.h"
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/tracing/core/trace_packet.h"
@@ -38,10 +38,10 @@
 namespace {
 constexpr uint32_t kDefaultPollIntervalMs = 1000;
 
-base::Optional<int64_t> ReadFileAsInt64(std::string path) {
+std::optional<int64_t> ReadFileAsInt64(std::string path) {
   std::string buf;
   if (!base::ReadFile(path, &buf))
-    return base::nullopt;
+    return std::nullopt;
   return base::StringToInt64(base::StripSuffix(buf, "\n"));
 }
 }  // namespace
@@ -76,7 +76,7 @@
   return sysfs_battery_subdirs_.size();
 }
 
-base::Optional<int64_t>
+std::optional<int64_t>
 LinuxPowerSysfsDataSource::BatteryInfo::GetChargeCounterUah(
     size_t battery_idx) {
   PERFETTO_CHECK(battery_idx < sysfs_battery_subdirs_.size());
@@ -84,7 +84,7 @@
                          sysfs_battery_subdirs_[battery_idx] + "/charge_now");
 }
 
-base::Optional<int64_t>
+std::optional<int64_t>
 LinuxPowerSysfsDataSource::BatteryInfo::GetEnergyCounterUah(
     size_t battery_idx) {
   PERFETTO_CHECK(battery_idx < sysfs_battery_subdirs_.size());
@@ -92,28 +92,28 @@
                          sysfs_battery_subdirs_[battery_idx] + "/energy_now");
 }
 
-base::Optional<int64_t> LinuxPowerSysfsDataSource::BatteryInfo::GetVoltageUv(
+std::optional<int64_t> LinuxPowerSysfsDataSource::BatteryInfo::GetVoltageUv(
     size_t battery_idx) {
   PERFETTO_CHECK(battery_idx < sysfs_battery_subdirs_.size());
   return ReadFileAsInt64(power_supply_dir_path_ + "/" +
                          sysfs_battery_subdirs_[battery_idx] + "/voltage_now");
 }
 
-base::Optional<int64_t>
+std::optional<int64_t>
 LinuxPowerSysfsDataSource::BatteryInfo::GetCapacityPercent(size_t battery_idx) {
   PERFETTO_CHECK(battery_idx < sysfs_battery_subdirs_.size());
   return ReadFileAsInt64(power_supply_dir_path_ + "/" +
                          sysfs_battery_subdirs_[battery_idx] + "/capacity");
 }
 
-base::Optional<int64_t> LinuxPowerSysfsDataSource::BatteryInfo::GetCurrentNowUa(
+std::optional<int64_t> LinuxPowerSysfsDataSource::BatteryInfo::GetCurrentNowUa(
     size_t battery_idx) {
   PERFETTO_CHECK(battery_idx < sysfs_battery_subdirs_.size());
   return ReadFileAsInt64(power_supply_dir_path_ + "/" +
                          sysfs_battery_subdirs_[battery_idx] + "/current_now");
 }
 
-base::Optional<int64_t>
+std::optional<int64_t>
 LinuxPowerSysfsDataSource::BatteryInfo::GetAverageCurrentUa(
     size_t battery_idx) {
   PERFETTO_CHECK(battery_idx < sysfs_battery_subdirs_.size());
diff --git a/src/traced/probes/power/linux_power_sysfs_data_source.h b/src/traced/probes/power/linux_power_sysfs_data_source.h
index 058ccd6..7916534 100644
--- a/src/traced/probes/power/linux_power_sysfs_data_source.h
+++ b/src/traced/probes/power/linux_power_sysfs_data_source.h
@@ -17,7 +17,8 @@
 #ifndef SRC_TRACED_PROBES_POWER_LINUX_POWER_SYSFS_DATA_SOURCE_H_
 #define SRC_TRACED_PROBES_POWER_LINUX_POWER_SYSFS_DATA_SOURCE_H_
 
-#include "perfetto/ext/base/optional.h"
+#include <optional>
+
 #include "perfetto/ext/base/weak_ptr.h"
 #include "perfetto/tracing/core/data_source_config.h"
 #include "src/traced/probes/probes_data_source.h"
@@ -39,22 +40,22 @@
     ~BatteryInfo();
 
     // The current coloumb counter value in µAh.
-    base::Optional<int64_t> GetChargeCounterUah(size_t battery_idx);
+    std::optional<int64_t> GetChargeCounterUah(size_t battery_idx);
 
     // The current energy counter in µWh.
-    base::Optional<int64_t> GetEnergyCounterUah(size_t battery_idx);
+    std::optional<int64_t> GetEnergyCounterUah(size_t battery_idx);
 
     // The voltage in µV.
-    base::Optional<int64_t> GetVoltageUv(size_t battery_idx);
+    std::optional<int64_t> GetVoltageUv(size_t battery_idx);
 
     // The battery capacity in percent.
-    base::Optional<int64_t> GetCapacityPercent(size_t battery_idx);
+    std::optional<int64_t> GetCapacityPercent(size_t battery_idx);
 
     // The current reading of the battery in µA.
-    base::Optional<int64_t> GetCurrentNowUa(size_t battery_idx);
+    std::optional<int64_t> GetCurrentNowUa(size_t battery_idx);
 
     // The smoothed current reading of the battery in µA.
-    base::Optional<int64_t> GetAverageCurrentUa(size_t battery_idx);
+    std::optional<int64_t> GetAverageCurrentUa(size_t battery_idx);
 
     // Name of the battery.
     std::string GetBatteryName(size_t battery_idx);
diff --git a/src/traced/probes/power/linux_power_sysfs_data_source_unittest.cc b/src/traced/probes/power/linux_power_sysfs_data_source_unittest.cc
index 2c1c8aa..442d767 100644
--- a/src/traced/probes/power/linux_power_sysfs_data_source_unittest.cc
+++ b/src/traced/probes/power/linux_power_sysfs_data_source_unittest.cc
@@ -59,9 +59,9 @@
 
   EXPECT_EQ(battery_info_->num_batteries(), 1u);
   EXPECT_EQ(*battery_info_->GetCapacityPercent(0), 88);
-  EXPECT_EQ(battery_info_->GetCurrentNowUa(0), base::nullopt);
-  EXPECT_EQ(battery_info_->GetAverageCurrentUa(0), base::nullopt);
-  EXPECT_EQ(battery_info_->GetChargeCounterUah(0), base::nullopt);
+  EXPECT_EQ(battery_info_->GetCurrentNowUa(0), std::nullopt);
+  EXPECT_EQ(battery_info_->GetAverageCurrentUa(0), std::nullopt);
+  EXPECT_EQ(battery_info_->GetChargeCounterUah(0), std::nullopt);
 }
 
 TEST(LinuxPowerSysfsDataSourceTest, MultipleBatteries) {
@@ -92,11 +92,11 @@
   size_t second_battery_idx = main_battery_idx == 0 ? 1 : 0;
 
   EXPECT_EQ(*battery_info_->GetCapacityPercent(second_battery_idx), 88);
-  EXPECT_EQ(battery_info_->GetCurrentNowUa(second_battery_idx), base::nullopt);
+  EXPECT_EQ(battery_info_->GetCurrentNowUa(second_battery_idx), std::nullopt);
   EXPECT_EQ(battery_info_->GetAverageCurrentUa(second_battery_idx),
-            base::nullopt);
+            std::nullopt);
   EXPECT_EQ(battery_info_->GetChargeCounterUah(second_battery_idx),
-            base::nullopt);
+            std::nullopt);
 
   EXPECT_EQ(*battery_info_->GetCapacityPercent(main_battery_idx), 95);
   EXPECT_EQ(*battery_info_->GetCurrentNowUa(main_battery_idx), 245000);
diff --git a/src/traced/probes/statsd_client/statsd_binder_data_source.cc b/src/traced/probes/statsd_client/statsd_binder_data_source.cc
index b05451b..9b79fca 100644
--- a/src/traced/probes/statsd_client/statsd_binder_data_source.cc
+++ b/src/traced/probes/statsd_client/statsd_binder_data_source.cc
@@ -20,10 +20,10 @@
 
 #include <map>
 #include <mutex>
+#include <optional>
 
 #include "perfetto/base/time.h"
 #include "perfetto/ext/base/no_destructor.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/protozero/scattered_heap_buffer.h"
 #include "perfetto/tracing/core/data_source_config.h"
diff --git a/src/traced/probes/sys_stats/sys_stats_data_source.cc b/src/traced/probes/sys_stats/sys_stats_data_source.cc
index 9543d7c..e5c02a9 100644
--- a/src/traced/probes/sys_stats/sys_stats_data_source.cc
+++ b/src/traced/probes/sys_stats/sys_stats_data_source.cc
@@ -253,7 +253,7 @@
       if (index == 2) {  // index for device name (string)
         disk_stat->set_device_name(words.cur_token());
       } else if (index >= 5) {  // integer values from index 5
-        base::Optional<uint64_t> value_address =
+        std::optional<uint64_t> value_address =
             base::CStringToUInt64(words.cur_token());
         uint64_t value = value_address ? *value_address : 0;
 
diff --git a/src/tracing/console_interceptor.cc b/src/tracing/console_interceptor.cc
index bb700f1..2c3221f 100644
--- a/src/tracing/console_interceptor.cc
+++ b/src/tracing/console_interceptor.cc
@@ -20,11 +20,11 @@
 
 #include <algorithm>
 #include <cmath>
+#include <optional>
 #include <tuple>
 
 #include "perfetto/ext/base/file_utils.h"
 #include "perfetto/ext/base/hash.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/utils.h"
@@ -129,7 +129,7 @@
   using SelfHandle = LockedHandle<ConsoleInterceptor>;
 
   InterceptorContext& context_;
-  base::Optional<SelfHandle> locked_self_;
+  std::optional<SelfHandle> locked_self_;
 };
 
 ConsoleInterceptor::~ConsoleInterceptor() = default;
@@ -157,7 +157,7 @@
   if (locked_self_.has_value())
     return &locked_self_.value()->session_state_;
   locked_self_ =
-      base::make_optional<SelfHandle>(context_.GetInterceptorLocked());
+      std::make_optional<SelfHandle>(context_.GetInterceptorLocked());
   return &locked_self_.value()->session_state_;
 }
 
diff --git a/src/tracing/core/tracing_service_impl.cc b/src/tracing/core/tracing_service_impl.cc
index a590837..8299500 100644
--- a/src/tracing/core/tracing_service_impl.cc
+++ b/src/tracing/core/tracing_service_impl.cc
@@ -102,15 +102,6 @@
 
 namespace perfetto {
 
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
-    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-// These are the only SELinux approved dir for trace files that are created
-// directly by traced.
-const char* kTraceDirBasePath = "/data/misc/perfetto-traces/";
-const char* kAndroidProductionBugreportTracePath =
-    "/data/misc/perfetto-traces/bugreport/systrace.pftrace";
-#endif
-
 namespace {
 constexpr int kMaxBuffersPerConsumer = 128;
 constexpr uint32_t kDefaultSnapshotsIntervalMs = 10 * 1000;
@@ -241,9 +232,7 @@
   return filter_matches || filter_regex_matches;
 }
 
-// Used when:
-// 1. TraceConfig.write_into_file == true and output_path is not empty.
-// 2. Calling SaveTraceForBugreport(), from perfetto --save-for-bugreport.
+// Used when TraceConfig.write_into_file == true and output_path is not empty.
 base::ScopedFile CreateTraceFile(const std::string& path, bool overwrite) {
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
     PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
@@ -251,6 +240,9 @@
   // It just improves the actionability of the error when people try to save the
   // trace in a location that is not SELinux-allowed (a generic "permission
   // denied" vs "don't put it here, put it there").
+  // These are the only SELinux approved dir for trace files that are created
+  // directly by traced.
+  static const char* kTraceDirBasePath = "/data/misc/perfetto-traces/";
   if (!base::StartsWith(path, kTraceDirBasePath)) {
     PERFETTO_ELOG("Invalid output_path %s. On Android it must be within %s.",
                   path.c_str(), kTraceDirBasePath);
@@ -271,10 +263,6 @@
   return fd;
 }
 
-std::string GetBugreportTmpPath() {
-  return GetBugreportPath() + ".tmp";
-}
-
 bool ShouldLogEvent(const TraceConfig& cfg) {
   switch (cfg.statsd_logging()) {
     case TraceConfig::STATSD_LOGGING_ENABLED:
@@ -320,16 +308,6 @@
 constexpr uint8_t TracingServiceImpl::kSyncMarker[];
 #endif
 
-std::string GetBugreportPath() {
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
-    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-  return kAndroidProductionBugreportTracePath;
-#else
-  // Only for tests, SaveTraceForBugreport is not used on other OSes.
-  return base::GetSysTempDir() + "/bugreport.pftrace";
-#endif
-}
-
 // static
 std::unique_ptr<TracingService> TracingService::CreateInstance(
     std::unique_ptr<SharedMemory::Factory> shm_factory,
@@ -623,6 +601,15 @@
         cfg.trigger_config().trigger_timeout_ms());
   }
 
+  // This check has been introduced in May 2023 after finding b/274931668.
+  if (static_cast<int>(cfg.trigger_config().trigger_mode()) >
+      TraceConfig::TriggerConfig::TriggerMode_MAX) {
+    MaybeLogUploadEvent(
+        cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidTriggerMode);
+    return PERFETTO_SVC_ERR(
+        "The trace config specified an invalid trigger_mode");
+  }
+
   if (has_trigger_config && cfg.duration_ms() != 0) {
     MaybeLogUploadEvent(
         cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingDurationWithTrigger);
@@ -982,6 +969,9 @@
       tracing_session->config.set_duration_ms(
           cfg.trigger_config().trigger_timeout_ms());
       break;
+
+      // The case of unknown modes (coming from future versions of the service)
+      // is handled few lines above (search for TriggerMode_MAX).
   }
 
   tracing_session->state = TracingSession::CONFIGURED;
@@ -1680,11 +1670,6 @@
     ReadBuffersIntoFile(tracing_session->id);
   }
 
-  if (tracing_session->on_disable_callback_for_bugreport) {
-    std::move(tracing_session->on_disable_callback_for_bugreport)();
-    tracing_session->on_disable_callback_for_bugreport = nullptr;
-  }
-
   MaybeLogUploadEvent(tracing_session->config, tracing_session->trace_uuid,
                       PerfettoStatsdAtom::kTracedNotifyTracingDisabled);
 
@@ -1917,7 +1902,7 @@
       // reset to 0 by the service when the chunk was freed).
 
       WriterID writer_id = chunk.writer_id();
-      base::Optional<BufferID> target_buffer_id =
+      std::optional<BufferID> target_buffer_id =
           producer->buffer_id_for_writer(writer_id);
 
       // We can only scrape this chunk if we know which log buffer to copy it
@@ -2066,21 +2051,6 @@
     return false;
   }
 
-  // If a bugreport request happened and the trace was stolen for that, give
-  // an empty trace with a clear signal to the consumer. This deals only with
-  // the case of readback-from-IPC. A similar code-path deals with the
-  // write_into_file case in MaybeSaveTraceForBugreport().
-  if (tracing_session->seized_for_bugreport) {
-    std::vector<TracePacket> packets;
-    if (!tracing_session->config.builtin_data_sources()
-             .disable_service_events()) {
-      EmitSeizedForBugreportLifecycleEvent(&packets);
-    }
-    EmitLifecycleEvents(tracing_session, &packets);
-    consumer->consumer_->OnTraceData(std::move(packets), /*has_more=*/false);
-    return true;
-  }
-
   if (IsWaitingForTrigger(tracing_session))
     return false;
 
@@ -2129,8 +2099,7 @@
   if (!tracing_session->write_into_file)
     return false;
 
-  if (!tracing_session->seized_for_bugreport &&
-      IsWaitingForTrigger(tracing_session))
+  if (IsWaitingForTrigger(tracing_session))
     return false;
 
   // ReadBuffers() can allocate memory internally, for filtering. By limiting
@@ -2489,25 +2458,22 @@
   bool is_long_trace =
       (tracing_session->config.write_into_file() &&
        tracing_session->config.file_write_period_ms() < kMillisPerDay);
-  bool seized_for_bugreport = tracing_session->seized_for_bugreport;
   tracing_sessions_.erase(tsid);
   tracing_session = nullptr;
   UpdateMemoryGuardrail();
 
   PERFETTO_LOG("Tracing session %" PRIu64 " ended, total sessions:%zu", tsid,
                tracing_sessions_.size());
-
 #if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD) && \
     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-  if (notify_traceur && (seized_for_bugreport || is_long_trace)) {
+  if (notify_traceur && is_long_trace) {
     PERFETTO_LAZY_LOAD(android_internal::NotifyTraceSessionEnded, notify_fn);
-    if (!notify_fn || !notify_fn(seized_for_bugreport))
+    if (!notify_fn || !notify_fn(/*session_stolen=*/false))
       PERFETTO_ELOG("Failed to notify Traceur long tracing has ended");
   }
 #else
   base::ignore_result(notify_traceur);
   base::ignore_result(is_long_trace);
-  base::ignore_result(seized_for_bugreport);
 #endif
 }
 
@@ -2867,7 +2833,7 @@
 
   // If the writer was registered by the producer, it should only write into the
   // buffer it was registered with.
-  base::Optional<BufferID> associated_buffer =
+  std::optional<BufferID> associated_buffer =
       producer->buffer_id_for_writer(writer_id);
   if (associated_buffer && *associated_buffer != buffer_id) {
     PERFETTO_ELOG("Writer %" PRIu16 " of producer %" PRIu16
@@ -2971,6 +2937,23 @@
   return &it->second;
 }
 
+TracingServiceImpl::TracingSession*
+TracingServiceImpl::FindTracingSessionWithMaxBugreportScore() {
+  TracingSession* max_session = nullptr;
+  for (auto& session_id_and_session : tracing_sessions_) {
+    auto& session = session_id_and_session.second;
+    const int32_t score = session.config.bugreport_score();
+    // Exclude sessions with 0 (or below) score. By default tracing sessions
+    // should NOT be eligible to be attached to bugreports.
+    if (score <= 0 || session.state != TracingSession::STARTED)
+      continue;
+
+    if (!max_session || score > max_session->config.bugreport_score())
+      max_session = &session;
+  }
+  return max_session;
+}
+
 ProducerID TracingServiceImpl::GetNextProducerID() {
   PERFETTO_DCHECK_THREAD(thread_checker_);
   PERFETTO_CHECK(producers_.size() < kMaxProducerID);
@@ -3351,7 +3334,7 @@
   }
 
   std::string sdk_str_value = base::GetAndroidProp("ro.build.version.sdk");
-  base::Optional<uint64_t> sdk_value = base::StringToUInt64(sdk_str_value);
+  std::optional<uint64_t> sdk_value = base::StringToUInt64(sdk_str_value);
   if (sdk_value.has_value()) {
     info->set_android_sdk_version(*sdk_value);
   } else {
@@ -3399,18 +3382,6 @@
     SerializeAndAppendPacket(packets, std::move(pair.second));
 }
 
-void TracingServiceImpl::EmitSeizedForBugreportLifecycleEvent(
-    std::vector<TracePacket>* packets) {
-  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
-  packet->set_timestamp(static_cast<uint64_t>(base::GetBootTimeNs().count()));
-  packet->set_trusted_uid(static_cast<int32_t>(uid_));
-  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
-  auto* service_event = packet->set_service_event();
-  service_event->AppendVarInt(
-      protos::pbzero::TracingServiceEvent::kSeizedForBugreportFieldNumber, 1);
-  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
-}
-
 void TracingServiceImpl::MaybeEmitReceivedTriggers(
     TracingSession* tracing_session,
     std::vector<TracePacket>* packets) {
@@ -3433,91 +3404,6 @@
   }
 }
 
-bool TracingServiceImpl::MaybeSaveTraceForBugreport(
-    std::function<void()> callback) {
-  TracingSession* max_session = nullptr;
-  TracingSessionID max_tsid = 0;
-  for (auto& session_id_and_session : tracing_sessions_) {
-    auto& session = session_id_and_session.second;
-    const int32_t score = session.config.bugreport_score();
-    // Exclude sessions with 0 (or below) score. By default tracing sessions
-    // should NOT be eligible to be attached to bugreports.
-    if (score <= 0 || session.state != TracingSession::STARTED)
-      continue;
-
-    // Also don't try to steal long traces with write_into_file if their content
-    // has been already partially written into a file, as we would get partial
-    // traces on both sides. We can't just copy the original file into the
-    // bugreport because the file could be too big (GBs) for bugreports.
-    // The only case where it's legit to steal traces with write_into_file, is
-    // when the consumer specified a very large write_period_ms (e.g. 24h),
-    // meaning that this is effectively a ring-buffer trace. Traceur (the
-    // Android System Tracing app), which uses --detach, does this to have a
-    // consistent invocation path for long-traces and ring-buffer-mode traces.
-    if (session.write_into_file && session.bytes_written_into_file > 0)
-      continue;
-
-    // If we are already in the process of finalizing another trace for
-    // bugreport, don't even start another one, as they would try to write onto
-    // the same file.
-    if (session.on_disable_callback_for_bugreport)
-      return false;
-
-    if (!max_session || score > max_session->config.bugreport_score()) {
-      max_session = &session;
-      max_tsid = session_id_and_session.first;
-    }
-  }
-
-  // No eligible trace found.
-  if (!max_session)
-    return false;
-
-  PERFETTO_LOG("Seizing trace for bugreport. tsid:%" PRIu64
-               " state:%d wf:%d score:%d name:\"%s\"",
-               max_tsid, max_session->state, !!max_session->write_into_file,
-               max_session->config.bugreport_score(),
-               max_session->config.unique_session_name().c_str());
-
-  auto br_fd = CreateTraceFile(GetBugreportTmpPath(), /*overwrite=*/true);
-  if (!br_fd)
-    return false;
-
-  if (max_session->write_into_file) {
-    auto fd = *max_session->write_into_file;
-    // If we are stealing a write_into_file session, add a marker that explains
-    // why the trace has been stolen rather than creating an empty file. This is
-    // only for write_into_file traces. A similar code path deals with the case
-    // of reading-back a seized trace from IPC in ReadBuffersIntoConsumer().
-    if (!max_session->config.builtin_data_sources().disable_service_events()) {
-      std::vector<TracePacket> packets;
-      EmitSeizedForBugreportLifecycleEvent(&packets);
-      for (auto& packet : packets) {
-        char* preamble;
-        size_t preamble_size = 0;
-        std::tie(preamble, preamble_size) = packet.GetProtoPreamble();
-        base::WriteAll(fd, preamble, preamble_size);
-        for (const Slice& slice : packet.slices()) {
-          base::WriteAll(fd, slice.start, slice.size);
-        }
-      }  // for (packets)
-    }    // if (!disable_service_events())
-  }      // if (max_session->write_into_file)
-  max_session->write_into_file = std::move(br_fd);
-  max_session->on_disable_callback_for_bugreport = std::move(callback);
-  max_session->seized_for_bugreport = true;
-
-  // Post a task to avoid that early FlushAndDisableTracing() failures invoke
-  // the callback before we return. That would re-enter in a weird way the
-  // callstack of the calling ConsumerEndpointImpl::SaveTraceForBugreport().
-  auto weak_this = weak_ptr_factory_.GetWeakPtr();
-  task_runner_->PostTask([weak_this, max_tsid] {
-    if (weak_this)
-      weak_this->FlushAndDisableTracing(max_tsid);
-  });
-  return true;
-}
-
 void TracingServiceImpl::MaybeLogUploadEvent(const TraceConfig& cfg,
                                              const base::Uuid& uuid,
                                              PerfettoStatsdAtom atom,
@@ -3559,6 +3445,17 @@
 void TracingServiceImpl::FlushAndCloneSession(ConsumerEndpointImpl* consumer,
                                               TracingSessionID tsid) {
   PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  if (tsid == kBugreportSessionId) {
+    TracingSession* session = FindTracingSessionWithMaxBugreportScore();
+    if (!session) {
+      consumer->consumer_->OnSessionCloned(
+          false, "No tracing sessions eligible for bugreport found");
+      return;
+    }
+    tsid = session->id;
+  }
+
   auto weak_this = weak_ptr_factory_.GetWeakPtr();
   auto weak_consumer = consumer->GetWeakPtr();
   Flush(tsid, 0, [weak_this, tsid, weak_consumer](bool final_flush_outcome) {
@@ -3577,6 +3474,7 @@
                                                 bool final_flush_outcome) {
   PERFETTO_DLOG("CloneSession(%" PRIu64 ") started, consumer uid: %d", src_tsid,
                 static_cast<int>(consumer->uid_));
+
   TracingSession* src = GetTracingSession(src_tsid);
 
   // The session might be gone by the time we try to clone it.
@@ -3650,6 +3548,11 @@
         new protozero::MessageFilter(*src->trace_filter));
   }
 
+  SnapshotLifecyleEvent(
+      cloned_session,
+      protos::pbzero::TracingServiceEvent::kTracingDisabledFieldNumber,
+      true /* snapshot_clocks */);
+
   PERFETTO_DLOG("Consumer (uid:%d) cloned tracing session %" PRIu64
                 " -> %" PRIu64,
                 static_cast<int>(consumer->uid_), src_tsid, tsid);
@@ -3970,21 +3873,9 @@
 
 void TracingServiceImpl::ConsumerEndpointImpl::SaveTraceForBugreport(
     SaveTraceForBugreportCallback consumer_callback) {
-  PERFETTO_DCHECK_THREAD(thread_checker_);
-  auto on_complete_callback = [consumer_callback] {
-    if (rename(GetBugreportTmpPath().c_str(), GetBugreportPath().c_str())) {
-      consumer_callback(false, "rename(" + GetBugreportTmpPath() + ", " +
-                                   GetBugreportPath() + ") failed (" +
-                                   strerror(errno) + ")");
-    } else {
-      consumer_callback(true, GetBugreportPath());
-    }
-  };
-  if (!service_->MaybeSaveTraceForBugreport(std::move(on_complete_callback))) {
-    consumer_callback(false,
-                      "No trace with TraceConfig.bugreport_score > 0 eligible "
-                      "for bug reporting was found");
-  }
+  consumer_callback(false,
+                    "SaveTraceForBugreport is deprecated. Use "
+                    "CloneSession(kBugreportSessionId) instead.");
 }
 
 void TracingServiceImpl::ConsumerEndpointImpl::CloneSession(
diff --git a/src/tracing/core/tracing_service_impl.h b/src/tracing/core/tracing_service_impl.h
index 4800559..7cefb9b 100644
--- a/src/tracing/core/tracing_service_impl.h
+++ b/src/tracing/core/tracing_service_impl.h
@@ -22,6 +22,7 @@
 #include <map>
 #include <memory>
 #include <mutex>
+#include <optional>
 #include <random>
 #include <set>
 #include <utility>
@@ -31,7 +32,6 @@
 #include "perfetto/base/status.h"
 #include "perfetto/base/time.h"
 #include "perfetto/ext/base/circular_queue.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/periodic_task.h"
 #include "perfetto/ext/base/uuid.h"
 #include "perfetto/ext/base/weak_ptr.h"
@@ -143,11 +143,11 @@
       return allowed_target_buffers_.count(buffer_id);
     }
 
-    base::Optional<BufferID> buffer_id_for_writer(WriterID writer_id) const {
+    std::optional<BufferID> buffer_id_for_writer(WriterID writer_id) const {
       const auto it = writers_.find(writer_id);
       if (it != writers_.end())
         return it->second;
-      return base::nullopt;
+      return std::nullopt;
     }
 
     uid_t uid() const { return uid_; }
@@ -632,11 +632,6 @@
     uint64_t max_file_size_bytes = 0;
     uint64_t bytes_written_into_file = 0;
 
-    // Set when using SaveTraceForBugreport(). This callback will be called
-    // when the tracing session ends and the data has been saved into the file.
-    std::function<void()> on_disable_callback_for_bugreport;
-    bool seized_for_bugreport = false;
-
     // Periodic task for snapshotting service events (e.g. clocks, sync markers
     // etc)
     base::PeriodicTask snapshot_periodic_task;
@@ -680,6 +675,10 @@
   // session doesn't exists.
   TracingSession* GetTracingSession(TracingSessionID);
 
+  // Returns a pointer to the tracing session that has the highest
+  // TraceConfig.bugreport_score, if any, or nullptr.
+  TracingSession* FindTracingSessionWithMaxBugreportScore();
+
   // Returns a pointer to the |tracing_sessions_| entry, matching the given
   // uid and detach key, or nullptr if no such session exists.
   TracingSession* GetDetachedSession(uid_t, const std::string& key);
@@ -708,12 +707,10 @@
   void EmitStats(TracingSession*, std::vector<TracePacket>*);
   TraceStats GetTraceStats(TracingSession*);
   void EmitLifecycleEvents(TracingSession*, std::vector<TracePacket>*);
-  void EmitSeizedForBugreportLifecycleEvent(std::vector<TracePacket>*);
   void MaybeEmitUuidAndTraceConfig(TracingSession*, std::vector<TracePacket>*);
   void MaybeEmitSystemInfo(TracingSession*, std::vector<TracePacket>*);
   void MaybeEmitReceivedTriggers(TracingSession*, std::vector<TracePacket>*);
   void MaybeNotifyAllDataSourcesStarted(TracingSession*);
-  bool MaybeSaveTraceForBugreport(std::function<void()> callback);
   void OnFlushTimeout(TracingSessionID, FlushRequestID);
   void OnDisableTracingTimeout(TracingSessionID);
   void DisableTracingNotifyConsumerAndFlushFile(TracingSession*);
diff --git a/src/tracing/core/tracing_service_impl_unittest.cc b/src/tracing/core/tracing_service_impl_unittest.cc
index 8b8c62c..b66e502 100644
--- a/src/tracing/core/tracing_service_impl_unittest.cc
+++ b/src/tracing/core/tracing_service_impl_unittest.cc
@@ -432,6 +432,31 @@
   EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
 }
 
+// Regression test for b/274931668. An unkonwn trigger should not cause a trace
+// that runs indefinitely.
+TEST_F(TracingServiceImplTest, FailOnUnknownTrigger) {
+  std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
+  consumer->Connect(svc.get());
+
+  std::unique_ptr<MockProducer> producer = CreateMockProducer();
+  producer->Connect(svc.get(), "mock_producer");
+  producer->RegisterDataSource("ds_1");
+
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(128);
+  trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
+  auto* trigger_config = trace_config.mutable_trigger_config();
+  trigger_config->set_trigger_mode(
+      static_cast<TraceConfig::TriggerConfig::TriggerMode>(
+          TraceConfig::TriggerConfig::TriggerMode_MAX + 1));
+  auto* trigger = trigger_config->add_triggers();
+  trigger->set_name("trigger_from_the_future");
+  trigger_config->set_trigger_timeout_ms(1);
+
+  consumer->EnableTracing(trace_config);
+  consumer->WaitForTracingDisabled();
+}
+
 // Creates a tracing session with a START_TRACING trigger and checks that
 // the session is not started when the configured trigger producer is different
 // than the producer that sent the trigger.
diff --git a/src/tracing/internal/tracing_muxer_impl_integrationtest.cc b/src/tracing/internal/tracing_muxer_impl_integrationtest.cc
index e1cfbfd..5711d73 100644
--- a/src/tracing/internal/tracing_muxer_impl_integrationtest.cc
+++ b/src/tracing/internal/tracing_muxer_impl_integrationtest.cc
@@ -1,8 +1,8 @@
 #include "perfetto/tracing/tracing.h"
 
 #include <stdio.h>
+#include <optional>
 
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/thread_task_runner.h"
 #include "perfetto/ext/base/waitable_event.h"
 #include "perfetto/ext/tracing/ipc/service_ipc_host.h"
@@ -53,7 +53,7 @@
 
   struct EnvVar {
     const char* name;
-    base::Optional<std::string> value;
+    std::optional<std::string> value;
   };
   // Stores previous values of environment variables overridden by tests. We
   // need to to this because some android integration tests need to talk to the
diff --git a/src/tracing/test/mock_consumer.cc b/src/tracing/test/mock_consumer.cc
index dc44b31..e24ffcc 100644
--- a/src/tracing/test/mock_consumer.cc
+++ b/src/tracing/test/mock_consumer.cc
@@ -39,8 +39,9 @@
   task_runner_->RunUntilCheckpoint(checkpoint_name);
 }
 
-void MockConsumer::Connect(TracingService* svc, uid_t uid) {
-  service_endpoint_ = svc->ConnectConsumer(this, uid);
+void MockConsumer::Connect(
+    std::unique_ptr<TracingService::ConsumerEndpoint> service_endpoint) {
+  service_endpoint_ = std::move(service_endpoint);
   static int i = 0;
   auto checkpoint_name = "on_consumer_connect_" + std::to_string(i++);
   auto on_connect = task_runner_->CreateCheckpoint(checkpoint_name);
@@ -48,6 +49,14 @@
   task_runner_->RunUntilCheckpoint(checkpoint_name);
 }
 
+void MockConsumer::Connect(TracingService* svc, uid_t uid) {
+  Connect(svc->ConnectConsumer(this, uid));
+}
+
+void MockConsumer::ForceDisconnect() {
+  service_endpoint_.reset();
+}
+
 void MockConsumer::EnableTracing(const TraceConfig& trace_config,
                                  base::ScopedFile write_into_file) {
   service_endpoint_->EnableTracing(trace_config, std::move(write_into_file));
diff --git a/src/tracing/test/mock_consumer.h b/src/tracing/test/mock_consumer.h
index a840349..f18671e 100644
--- a/src/tracing/test/mock_consumer.h
+++ b/src/tracing/test/mock_consumer.h
@@ -47,7 +47,9 @@
   explicit MockConsumer(base::TestTaskRunner*);
   ~MockConsumer() override;
 
+  void Connect(std::unique_ptr<TracingService::ConsumerEndpoint>);
   void Connect(TracingService* svc, uid_t = 0);
+  void ForceDisconnect();
   void EnableTracing(const TraceConfig&, base::ScopedFile = base::ScopedFile());
   void StartTracing();
   void ChangeTraceConfig(const TraceConfig&);
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 768b8ad..6b995ed 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -38,6 +38,7 @@
       "../protos/perfetto/trace/sys_stats:cpp",
       "../src/base:base",
       "../src/base:test_support",
+      "../src/perfetto_cmd:bugreport_path",
     ]
     if (enable_perfetto_traced_probes) {
       deps += [
diff --git a/test/android_integrationtest.cc b/test/android_integrationtest.cc
index 19e894d..9d4e543 100644
--- a/test/android_integrationtest.cc
+++ b/test/android_integrationtest.cc
@@ -63,33 +63,6 @@
 using ::testing::Property;
 using ::testing::SizeIs;
 
-// For the SaveForBugreport* tests.
-void SetTraceConfigForBugreportTest(TraceConfig* trace_config) {
-  trace_config->add_buffers()->set_size_kb(4096);
-  trace_config->set_duration_ms(60000);  // Will never hit this.
-  trace_config->set_bugreport_score(10);
-  auto* ds_config = trace_config->add_data_sources()->mutable_config();
-  ds_config->set_name("android.perfetto.FakeProducer");
-  ds_config->mutable_for_testing()->set_message_count(3);
-  ds_config->mutable_for_testing()->set_message_size(10);
-  ds_config->mutable_for_testing()->set_send_batch_on_register(true);
-}
-
-// For the SaveForBugreport* tests.
-static void VerifyBugreportTraceContents() {
-  // Read the trace written in the fixed location (/data/misc/perfetto-traces/
-  // on Android, /tmp/ on Linux/Mac) and make sure it has the right contents.
-  std::string trace_str;
-  base::ReadFile(GetBugreportPath(), &trace_str);
-  ASSERT_FALSE(trace_str.empty());
-  protos::gen::Trace trace;
-  ASSERT_TRUE(trace.ParseFromString(trace_str));
-  int test_packets = 0;
-  for (const auto& p : trace.packet())
-    test_packets += p.has_for_testing() ? 1 : 0;
-  ASSERT_EQ(test_packets, 3);
-}
-
 }  // namespace
 
 TEST(PerfettoAndroidIntegrationTest, TestKmemActivity) {
@@ -283,125 +256,6 @@
   ASSERT_TRUE(has_battery_packet);
 }
 
-TEST(PerfettoAndroidIntegrationTest, SaveForBugreport) {
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-  helper.ConnectFakeProducer();
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  TraceConfig trace_config;
-  SetTraceConfigForBugreportTest(&trace_config);
-
-  helper.StartTracing(trace_config);
-  helper.WaitForProducerEnabled();
-
-  EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
-  helper.WaitForTracingDisabled();
-
-  VerifyBugreportTraceContents();
-
-  // Now read the trace returned to the consumer via ReadBuffers. This should
-  // be always empty because --save-for-bugreport takes it over and makes the
-  // buffers unreadable by the consumer (by virtue of force-setting
-  // write_into_file, which is incompatible with ReadBuffers()). The only
-  // content should be the |seized_for_bugreport| flag.
-  helper.ReadData();
-  helper.WaitForReadData();
-  const auto& packets = helper.full_trace();
-  ASSERT_EQ(packets.size(), 1u);
-  for (const auto& p : packets) {
-    ASSERT_TRUE(p.has_service_event());
-    ASSERT_TRUE(p.service_event().seized_for_bugreport());
-  }
-}
-
-// Tests that the SaveForBugreport logic works also for traces with
-// write_into_file = true (with a passed file descriptor).
-TEST(PerfettoAndroidIntegrationTest, SaveForBugreport_WriteIntoFile) {
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-  helper.ConnectFakeProducer();
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  TraceConfig trace_config;
-  SetTraceConfigForBugreportTest(&trace_config);
-  trace_config.set_file_write_period_ms(60000);  // Will never hit this.
-  trace_config.set_write_into_file(true);
-
-  auto pipe_pair = base::Pipe::Create();
-  helper.StartTracing(trace_config, std::move(pipe_pair.wr));
-  helper.WaitForProducerEnabled();
-
-  EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
-  helper.WaitForTracingDisabled();
-
-  VerifyBugreportTraceContents();
-
-  // Now read the original file descriptor passed in.
-  std::string trace_bytes;
-  ASSERT_TRUE(base::ReadPlatformHandle(*pipe_pair.rd, &trace_bytes));
-  protos::gen::Trace trace;
-  ASSERT_TRUE(trace.ParseFromString(trace_bytes));
-  ASSERT_EQ(trace.packet().size(), 1u);
-  for (const auto& p : trace.packet()) {
-    ASSERT_TRUE(p.has_service_event());
-    ASSERT_TRUE(p.service_event().seized_for_bugreport());
-  }
-}
-
-// Tests that SaveTraceForBugreport() works also if the trace has triggers
-// defined and those triggers have not been hit. This is a regression test for
-// b/188008375 .
-#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-// Disabled due to b/191940560
-#define MAYBE_SaveForBugreport_Triggers DISABLED_SaveForBugreport_Triggers
-#else
-#define MAYBE_SaveForBugreport_Triggers SaveForBugreport_Triggers
-#endif
-TEST(PerfettoAndroidIntegrationTest, MAYBE_SaveForBugreport_Triggers) {
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-  helper.ConnectFakeProducer();
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  TraceConfig trace_config;
-  SetTraceConfigForBugreportTest(&trace_config);
-  trace_config.set_duration_ms(0);  // set_trigger_timeout_ms is used instead.
-  auto* trigger_config = trace_config.mutable_trigger_config();
-  trigger_config->set_trigger_timeout_ms(8.64e+7);
-  trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
-  auto* trigger = trigger_config->add_triggers();
-  trigger->set_name("trigger_name");
-  trigger->set_stop_delay_ms(1);
-
-  helper.StartTracing(trace_config);
-  helper.WaitForProducerEnabled();
-
-  EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
-  helper.WaitForTracingDisabled();
-
-  VerifyBugreportTraceContents();
-
-  // Now read the original trace.
-  helper.ReadData();
-  helper.WaitForReadData();
-  const auto& packets = helper.full_trace();
-  ASSERT_EQ(packets.size(), 1u);
-  for (const auto& p : packets) {
-    ASSERT_TRUE(p.has_service_event());
-    ASSERT_TRUE(p.service_event().seized_for_bugreport());
-  }
-}
-
 }  // namespace perfetto
 
 #endif  // PERFETTO_OS_ANDROID
diff --git a/test/cmdline_integrationtest.cc b/test/cmdline_integrationtest.cc
index 0747789..cbc3555 100644
--- a/test/cmdline_integrationtest.cc
+++ b/test/cmdline_integrationtest.cc
@@ -27,6 +27,7 @@
 #include "perfetto/protozero/scattered_heap_buffer.h"
 #include "src/base/test/test_task_runner.h"
 #include "src/base/test/utils.h"
+#include "src/perfetto_cmd/bugreport_path.h"
 #include "test/gtest_and_gmock.h"
 #include "test/test_helper.h"
 
@@ -66,6 +67,19 @@
   return path;
 }
 
+// For the SaveForBugreport* tests.
+TraceConfig CreateTraceConfigForBugreportTest() {
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(4096);
+  trace_config.set_duration_ms(60000);  // Will never hit this.
+  trace_config.set_bugreport_score(10);
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.perfetto.FakeProducer");
+  ds_config->mutable_for_testing()->set_message_count(3);
+  ds_config->mutable_for_testing()->set_message_size(10);
+  return trace_config;
+}
+
 class PerfettoCmdlineTest : public ::testing::Test {
  public:
   void SetUp() override {
@@ -120,6 +134,68 @@
     return Exec("trigger_perfetto", std::move(args), std::move(std_in));
   }
 
+  // This is in common to the 3 TEST_F SaveForBugreport* fixtures, which differ
+  // only in the config, passed here as input.
+  void RunBugreportTest(protos::gen::TraceConfig trace_config,
+                        bool check_original_trace = true) {
+    const std::string path = RandomTraceFileName();
+
+    auto perfetto_proc = ExecPerfetto(
+        {
+            "-o",
+            path,
+            "-c",
+            "-",
+        },
+        trace_config.SerializeAsString());
+
+    auto perfetto_br_proc = ExecPerfetto({
+        "--save-for-bugreport",
+    });
+
+    // Start the service and connect a simple fake producer.
+    StartServiceIfRequiredNoNewExecsAfterThis();
+
+    auto* fake_producer = ConnectFakeProducer();
+    ASSERT_TRUE(fake_producer);
+
+    std::thread background_trace([&perfetto_proc]() {
+      std::string stderr_str;
+      ASSERT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
+    });
+
+    // Wait for the producer to start, and then write out packets.
+    WaitForProducerEnabled();
+    auto on_data_written = task_runner_.CreateCheckpoint("data_written");
+    fake_producer->ProduceEventBatch(WrapTask(on_data_written));
+    task_runner_.RunUntilCheckpoint("data_written");
+
+    ASSERT_EQ(0, perfetto_br_proc.Run(&stderr_)) << "stderr: " << stderr_;
+    perfetto_proc.SendSigterm();
+    background_trace.join();
+
+    auto check_trace_contents = [](std::string trace_path) {
+      // Read the trace written in the fixed location
+      // (/data/misc/perfetto-traces/ on Android, /tmp/ on Linux/Mac) and make
+      // sure it has the right contents.
+      std::string trace_str;
+      base::ReadFile(trace_path, &trace_str);
+      ASSERT_FALSE(trace_str.empty());
+      protos::gen::Trace trace;
+      ASSERT_TRUE(trace.ParseFromString(trace_str));
+      int test_packets = 0;
+      for (const auto& p : trace.packet())
+        test_packets += p.has_for_testing() ? 1 : 0;
+      ASSERT_EQ(test_packets, 3) << trace_path;
+    };
+
+    // Verify that both the original trace and the cloned bugreport contain
+    // the expected contents.
+    check_trace_contents(GetBugreportTracePath());
+    if (check_original_trace)
+      check_trace_contents(path);
+  }
+
   // Tests are allowed to freely use these variables.
   std::string stderr_;
   base::TestTaskRunner task_runner_;
@@ -760,4 +836,37 @@
   }
 }
 
+TEST_F(PerfettoCmdlineTest, SaveForBugreport) {
+  TraceConfig trace_config = CreateTraceConfigForBugreportTest();
+  RunBugreportTest(std::move(trace_config));
+}
+
+TEST_F(PerfettoCmdlineTest, SaveForBugreport_WriteIntoFile) {
+  TraceConfig trace_config = CreateTraceConfigForBugreportTest();
+  trace_config.set_file_write_period_ms(60000);  // Will never hit this.
+  trace_config.set_write_into_file(true);
+  RunBugreportTest(std::move(trace_config));
+}
+
+// Tests that SaveTraceForBugreport() works also if the trace has triggers
+// defined and those triggers have not been hit. This is a regression test for
+// b/188008375 .
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+// Disabled due to b/191940560
+#define MAYBE_SaveForBugreport_Triggers DISABLED_SaveForBugreport_Triggers
+#else
+#define MAYBE_SaveForBugreport_Triggers SaveForBugreport_Triggers
+#endif
+TEST_F(PerfettoCmdlineTest, MAYBE_SaveForBugreport_Triggers) {
+  TraceConfig trace_config = CreateTraceConfigForBugreportTest();
+  trace_config.set_duration_ms(0);  // set_trigger_timeout_ms is used instead.
+  auto* trigger_config = trace_config.mutable_trigger_config();
+  trigger_config->set_trigger_timeout_ms(8.64e+7);
+  trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
+  auto* trigger = trigger_config->add_triggers();
+  trigger->set_name("trigger_name");
+  trigger->set_stop_delay_ms(1);
+  RunBugreportTest(std::move(trace_config), /*check_original_trace=*/false);
+}
+
 }  // namespace perfetto
diff --git a/test/configs/bugreport.cfg b/test/configs/bugreport.cfg
new file mode 100644
index 0000000..d42fd61
--- /dev/null
+++ b/test/configs/bugreport.cfg
@@ -0,0 +1,30 @@
+bugreport_score: 100
+duration_ms: 600000
+
+buffers {
+  size_kb: 32768
+  fill_policy: RING_BUFFER
+}
+
+data_sources {
+  config {
+    name: "linux.ftrace"
+    target_buffer: 0
+    ftrace_config {
+      ftrace_events: "sched/sched_switch"
+      ftrace_events: "power/suspend_resume"
+      ftrace_events: "sched/sched_process_exit"
+      ftrace_events: "sched/sched_process_free"
+      ftrace_events: "task/task_newtask"
+      ftrace_events: "task/task_rename"
+      ftrace_events: "sched/sched_wakeup"
+    }
+  }
+}
+
+data_sources {
+  config {
+    name: "linux.process_stats"
+    target_buffer: 0
+  }
+}
diff --git a/test/data/perf_sample_no_functions.pb.sha256 b/test/data/perf_sample_no_functions.pb.sha256
new file mode 100644
index 0000000..2800d93
--- /dev/null
+++ b/test/data/perf_sample_no_functions.pb.sha256
@@ -0,0 +1 @@
+45e09c54d964d390f92f60b673e3ff8fe83e4d7e904898a4b872ceb2e260af87
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256 b/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256
index ee11f6b..2c8417a 100644
--- a/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256
+++ b/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256
@@ -1 +1 @@
-3142c75d3c652460c6f76261b59191afb89be996a234a9e5700bb4147b18537f
\ No newline at end of file
+f4ac288ac3467e6e845d9f76497174bde312575af494d72845514c9e84ea6881
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-android_trace_30s_load.png.sha256 b/test/data/ui-screenshots/ui-android_trace_30s_load.png.sha256
index 6d5d8a4..742cbd9 100644
--- a/test/data/ui-screenshots/ui-android_trace_30s_load.png.sha256
+++ b/test/data/ui-screenshots/ui-android_trace_30s_load.png.sha256
@@ -1 +1 @@
-d3b1e5b4cd1496c31bd7ba1550cd247b46207e2d7af525f92586818d208f5c15
\ No newline at end of file
+a1f6f0291048912ec521abee9fdf2b6a36a78b02bd9fd7b642561e860b4d86ea
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_missing_track_names_load.png.sha256 b/test/data/ui-screenshots/ui-chrome_missing_track_names_load.png.sha256
index 3c01ea1..d350c05 100644
--- a/test/data/ui-screenshots/ui-chrome_missing_track_names_load.png.sha256
+++ b/test/data/ui-screenshots/ui-chrome_missing_track_names_load.png.sha256
@@ -1 +1 @@
-7a1c2f39a589f1cc5cee95f84a35d93b326edd5a9d36d77d9c44ff7ca7c41cb9
\ No newline at end of file
+6fc0295f4576311c64227a0bc683cfb2ac1b4ec3a8b567dd99015e2898a94fc8
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256 b/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256
index 522dd5c..3248c66 100644
--- a/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256
+++ b/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256
@@ -1 +1 @@
-52d63aeedf9d4a264b1230aab81efb53e40bf313e82c7cc5cc0db659953984d1
\ No newline at end of file
+4f4a860d0a7d5e9dcd059a928952ae21b5e1d40720bf0e302add744c99adc6ec
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_rendering_desktop_load.png.sha256 b/test/data/ui-screenshots/ui-chrome_rendering_desktop_load.png.sha256
index 3a5ea66..28168d6 100644
--- a/test/data/ui-screenshots/ui-chrome_rendering_desktop_load.png.sha256
+++ b/test/data/ui-screenshots/ui-chrome_rendering_desktop_load.png.sha256
@@ -1 +1 @@
-de48e637855336d5f219ff3384dacb90e9b068098883dbb4cedcb0fde5cbaae8
\ No newline at end of file
+2f5a704450f1d0a830ed957e8f67cfe78ee19ddacc7aef4f188b33797aacb7f4
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256 b/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
index 6ad18ce..ca4c662 100644
--- a/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
+++ b/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
@@ -1 +1 @@
-9539db7b9fdd624066e360dbc65a3fa33b9771c0cd4a105f411a25f6df77a828
\ No newline at end of file
+9c416089e3ae480d5f2f2807d0607949903dc83a01da998c5930c49f66c92859
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-modal_dialog_dismiss_2.png.sha256 b/test/data/ui-screenshots/ui-modal_dialog_dismiss_2.png.sha256
index 102a59b..d35785f 100644
--- a/test/data/ui-screenshots/ui-modal_dialog_dismiss_2.png.sha256
+++ b/test/data/ui-screenshots/ui-modal_dialog_dismiss_2.png.sha256
@@ -1 +1 @@
-0690737a791ad7fc869a041574e220eed6cca864f5d93740c44ff2e36b4fe4d5
\ No newline at end of file
+29beac68a6251a7494052ce7c34ccf57d39a54270ab7e1e52f3bad42c17f6e72
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-modal_dialog_switch_page_no_dialog.png.sha256 b/test/data/ui-screenshots/ui-modal_dialog_switch_page_no_dialog.png.sha256
index 98dcc39..cb25d82 100644
--- a/test/data/ui-screenshots/ui-modal_dialog_switch_page_no_dialog.png.sha256
+++ b/test/data/ui-screenshots/ui-modal_dialog_switch_page_no_dialog.png.sha256
@@ -1 +1 @@
-c9769de63b7caa32bda648b08a7e302a80e8bf1a9138c9e508faec5713e0964c
\ No newline at end of file
+a40f62ca3cd81053ce62b9555737f02d4db6ea66eca979dc9cf9edded76e5db3
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_trace_and_go_back_to_landing_page.png.sha256 b/test/data/ui-screenshots/ui-routing_open_trace_and_go_back_to_landing_page.png.sha256
index 8b7fa76..f05c632 100644
--- a/test/data/ui-screenshots/ui-routing_open_trace_and_go_back_to_landing_page.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_open_trace_and_go_back_to_landing_page.png.sha256
@@ -1 +1 @@
-02f6f3a46d79569187fb0bcff051dda39055ac72f95701f14b8f99e29ad9c968
\ No newline at end of file
+eb8eb39e18e49f42789aef8ab16a1475e7b868afcc6c16441d97324088be973a
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_access_subpage_then_go_back.png.sha256 b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_access_subpage_then_go_back.png.sha256
index 808a45f..fcb7e6f 100644
--- a/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_access_subpage_then_go_back.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_access_subpage_then_go_back.png.sha256
@@ -1 +1 @@
-1c86e64cc43b77ba43ba4e1635282b4b6c57313d3ce0e5a92af09468be535629
\ No newline at end of file
+e667dc846d1e560aedc5b3cb27f8c81136f04ab18f103ee3dac0ea13b59fec59
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_second_trace_from_url.png.sha256 b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_second_trace_from_url.png.sha256
index 808a45f..fcb7e6f 100644
--- a/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_second_trace_from_url.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_second_trace_from_url.png.sha256
@@ -1 +1 @@
-1c86e64cc43b77ba43ba4e1635282b4b6c57313d3ce0e5a92af09468be535629
\ No newline at end of file
+e667dc846d1e560aedc5b3cb27f8c81136f04ab18f103ee3dac0ea13b59fec59
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_go_back_to_first_trace.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_go_back_to_first_trace.png.sha256
index 4388532..8845e06 100644
--- a/test/data/ui-screenshots/ui-routing_start_from_no_trace_go_back_to_first_trace.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_go_back_to_first_trace.png.sha256
@@ -1 +1 @@
-1055a3d79b7be443f8364f1c78fed95fc8317fc309428f0ca0ae9e440bcd7457
\ No newline at end of file
+180392b9f68b3bf7522e2f44985fb16abf8d1581a71e58289ad07c924d553f04
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_trace_.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_trace_.png.sha256
index 808a45f..fcb7e6f 100644
--- a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_trace_.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_trace_.png.sha256
@@ -1 +1 @@
-1c86e64cc43b77ba43ba4e1635282b4b6c57313d3ce0e5a92af09468be535629
\ No newline at end of file
+e667dc846d1e560aedc5b3cb27f8c81136f04ab18f103ee3dac0ea13b59fec59
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_refresh.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_refresh.png.sha256
index 808a45f..fcb7e6f 100644
--- a/test/data/ui-screenshots/ui-routing_start_from_no_trace_refresh.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_refresh.png.sha256
@@ -1 +1 @@
-1c86e64cc43b77ba43ba4e1635282b4b6c57313d3ce0e5a92af09468be535629
\ No newline at end of file
+e667dc846d1e560aedc5b3cb27f8c81136f04ab18f103ee3dac0ea13b59fec59
\ No newline at end of file
diff --git a/test/end_to_end_shared_memory_fuzzer.cc b/test/end_to_end_shared_memory_fuzzer.cc
index 91f3629..adde520 100644
--- a/test/end_to_end_shared_memory_fuzzer.cc
+++ b/test/end_to_end_shared_memory_fuzzer.cc
@@ -132,7 +132,7 @@
   }
 
  private:
-  base::Optional<base::ThreadTaskRunner> runner_;  // Keep first.
+  std::optional<base::ThreadTaskRunner> runner_;  // Keep first.
 
   std::unique_ptr<FakeProducer> producer_;
   const uint8_t* data_;
diff --git a/test/ftrace_integrationtest.cc b/test/ftrace_integrationtest.cc
index ab86dd5..318b308 100644
--- a/test/ftrace_integrationtest.cc
+++ b/test/ftrace_integrationtest.cc
@@ -319,7 +319,7 @@
   const auto& packets = helper.trace();
   ASSERT_GT(packets.size(), 0u);
 
-  base::Optional<protos::gen::FtraceStats> stats;
+  std::optional<protos::gen::FtraceStats> stats;
   for (const auto& packet : packets) {
     if (!packet.has_ftrace_stats() ||
         packet.ftrace_stats().phase() !=
diff --git a/test/test_helper.cc b/test/test_helper.cc
index 2267dc0..cbc3aca 100644
--- a/test/test_helper.cc
+++ b/test/test_helper.cc
@@ -156,18 +156,6 @@
   return success;
 }
 
-bool TestHelper::SaveTraceForBugreportAndWait() {
-  bool success = false;
-  auto checkpoint = CreateCheckpoint("bugreport");
-  auto callback = [&success, checkpoint](bool s, const std::string&) {
-    success = s;
-    checkpoint();
-  };
-  endpoint_->SaveTraceForBugreport(callback);
-  RunUntilCheckpoint("bugreport");
-  return success;
-}
-
 void TestHelper::CreateProducerProvidedSmb() {
   fake_producer_thread_.CreateProducerProvidedSmb();
 }
diff --git a/test/test_helper.h b/test/test_helper.h
index fda54b0..dd18b4c 100644
--- a/test/test_helper.h
+++ b/test/test_helper.h
@@ -19,10 +19,10 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <optional>
 
 #include "perfetto/base/build_config.h"
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/subprocess.h"
 #include "perfetto/ext/base/thread_task_runner.h"
@@ -40,6 +40,8 @@
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
 #include "src/tracing/ipc/shared_memory_windows.h"
 #else
+#include <signal.h>
+
 #include "src/traced/probes/probes_producer.h"
 #include "src/tracing/ipc/posix_shared_memory.h"
 #endif
@@ -107,7 +109,7 @@
  private:
   struct Var {
     const char* name;
-    base::Optional<std::string> value;
+    std::optional<std::string> value;
   };
   std::vector<Var> prev_state_;
 };
@@ -157,7 +159,7 @@
   base::ThreadTaskRunner* runner() { return runner_ ? &*runner_ : nullptr; }
 
  private:
-  base::Optional<base::ThreadTaskRunner> runner_;  // Keep first.
+  std::optional<base::ThreadTaskRunner> runner_;  // Keep first.
 
   std::string producer_socket_;
   std::string consumer_socket_;
@@ -194,7 +196,7 @@
   }
 
  private:
-  base::Optional<base::ThreadTaskRunner> runner_;  // Keep first.
+  std::optional<base::ThreadTaskRunner> runner_;  // Keep first.
 
   std::string producer_socket_;
   std::unique_ptr<ProbesProducer> producer_;
@@ -251,7 +253,7 @@
   }
 
  private:
-  base::Optional<base::ThreadTaskRunner> runner_;  // Keep first.
+  std::optional<base::ThreadTaskRunner> runner_;  // Keep first.
 
   std::string producer_socket_;
   std::unique_ptr<FakeProducer> producer_;
@@ -309,7 +311,6 @@
   void FreeBuffers();
   void DetachConsumer(const std::string& key);
   bool AttachConsumer(const std::string& key);
-  bool SaveTraceForBugreportAndWait();
   void CreateProducerProvidedSmb();
   bool IsShmemProvidedByProducer();
   void ProduceStartupEventBatch(const protos::gen::TestConfig& config);
@@ -427,6 +428,12 @@
     constexpr bool kUseSystemBinaries = true;
 #endif
 
+    auto pass_env = [](const std::string& var, base::Subprocess* proc) {
+      const char* val = getenv(var.c_str());
+      if (val)
+        proc->args.env.push_back(var + "=" + val);
+    };
+
     std::vector<std::string>& cmd = subprocess_.args.exec_cmd;
     if (kUseSystemBinaries) {
       PERFETTO_CHECK(TestHelper::kDefaultMode ==
@@ -442,6 +449,9 @@
       subprocess_.args.env.push_back(
           std::string("PERFETTO_CONSUMER_SOCK_NAME=") +
           TestHelper::GetDefaultModeConsumerSocketName());
+      pass_env("TMPDIR", &subprocess_);
+      pass_env("TMP", &subprocess_);
+      pass_env("TEMP", &subprocess_);
       cmd.push_back(base::GetCurExecutableDir() + "/" + argv0);
       cmd.insert(cmd.end(), args.begin(), args.end());
     }
@@ -479,6 +489,16 @@
     sync_pipe_.rd.reset();
   }
 
+  void SendSigterm() {
+#ifdef SIGTERM
+    kill(subprocess_.pid(), SIGTERM);
+#else
+    // This code is never used on Windows tests, not bothering.
+    if (subprocess_.pid())  // Always true, but avoids Wnoreturn compile errors.
+      PERFETTO_FATAL("SendSigterm() not implemented on this platform");
+#endif
+  }
+
  private:
   base::Subprocess subprocess_;
   base::Pipe sync_pipe_;
diff --git a/test/trace_processor/diff_tests/functions/tests.py b/test/trace_processor/diff_tests/functions/tests.py
index d68159a..7f952ed 100644
--- a/test/trace_processor/diff_tests/functions/tests.py
+++ b/test/trace_processor/diff_tests/functions/tests.py
@@ -31,6 +31,8 @@
         stack.append("{name} ({address})".format(
             name=profile.string_table[function.name],
             address=hex(location.address)))
+      if len(location.line) == 0:
+        stack.append("({address})".format(address=hex(location.address)))
     samples.append('Sample:\nValues: {values}\nStack:\n{stack}'.format(
         values=', '.join(map(str, s.value)), stack='\n'.join(stack)))
   return '\n\n'.join(sorted(samples)) + '\n'
@@ -287,6 +289,42 @@
               }
         """))
 
+  def test_profile_no_functions(self):
+    return DiffTestBlueprint(
+        trace=DataPath("perf_sample_no_functions.pb"),
+        query="""
+        SELECT HEX(
+          EXPERIMENTAL_PROFILE(STACK_FROM_STACK_PROFILE_CALLSITE(callsite_id))
+        )
+        FROM PERF_SAMPLE
+    """,
+        out=BinaryProto(
+            message_type="perfetto.third_party.perftools.profiles.Profile",
+            post_processing=PrintProfileProto,
+            contents="""
+        Sample:
+          Values: 1
+          Stack:
+            (0x7a4167d3f8)
+            (0x783153c8e4)
+            (0x7a4161ef8c)
+            (0x7a42c3d8b0)
+            (0x7a4167d9f4)
+            (0x7a4163bc44)
+            (0x7a4172f330)
+            (0x7a4177a658)
+            (0x7a4162b3a0)
+
+        Sample:
+          Values: 1
+          Stack:
+            (0x7a4167d9f8)
+            (0x7a4163bc44)
+            (0x7a4172f330)
+            (0x7a4177a658)
+            (0x7a4162b3a0)
+        """))
+
   def test_profile_default_sample_types(self):
     return DiffTestBlueprint(
         trace=DataPath("perf_sample.pb"),
diff --git a/test/trace_processor/diff_tests/parsing/chrome_metadata.out b/test/trace_processor/diff_tests/parsing/chrome_metadata.out
index 7346e41..873e349 100644
--- a/test/trace_processor/diff_tests/parsing/chrome_metadata.out
+++ b/test/trace_processor/diff_tests/parsing/chrome_metadata.out
@@ -1,9 +1,10 @@
 "id","type","name","key_type","int_value","str_value"
-0,"metadata","trace_uuid","single","[NULL]","00000000-0000-0000-dcce-849205cfb03e"
-1,"metadata","cr-playstore_version_code","single",101,"[NULL]"
-2,"metadata","cr-enabled_categories","single","[NULL]","cat1,cat2,cat3"
-3,"metadata","cr-background_tracing_metadata","single","[NULL]","CgUlDsAbXx2RziSz"
-4,"metadata","cr-scenario_name_hash","single",3005533841,"[NULL]"
-5,"metadata","cr-triggered_rule_name_hash","single",1595654158,"[NULL]"
-6,"metadata","trace_size_bytes","single",64,"[NULL]"
-7,"metadata","trace_type","single","[NULL]","proto"
+0,"metadata","trace_uuid","single","[NULL]","00000000-0000-0000-dcce-849205cfb03e" 
+1,"metadata","trace_time_clock_id","single",6,"[NULL]"
+2,"metadata","cr-playstore_version_code","single",101,"[NULL]"
+3,"metadata","cr-enabled_categories","single","[NULL]","cat1,cat2,cat3"
+4,"metadata","cr-background_tracing_metadata","single","[NULL]","CgUlDsAbXx2RziSz"
+5,"metadata","cr-scenario_name_hash","single",3005533841,"[NULL]"
+6,"metadata","cr-triggered_rule_name_hash","single",1595654158,"[NULL]"
+7,"metadata","trace_size_bytes","single",64,"[NULL]"
+8,"metadata","trace_type","single","[NULL]","proto"
diff --git a/test/trace_processor/diff_tests/startup/android_startup.out b/test/trace_processor/diff_tests/startup/android_startup.out
index f804a34..48fa752 100644
--- a/test/trace_processor/diff_tests/startup/android_startup.out
+++ b/test/trace_processor/diff_tests/startup/android_startup.out
@@ -62,6 +62,7 @@
       installd_dur_ns: 0
       dex2oat_dur_ns: 0
     }
+    slow_start_reason: "Main Thread - Time spent in Runnable state"
     startup_type: "warm"
   }
 }
diff --git a/test/trace_processor/diff_tests/startup/android_startup_attribution_slow.out b/test/trace_processor/diff_tests/startup/android_startup_attribution_slow.out
index 2257cb0..ea33f96 100644
--- a/test/trace_processor/diff_tests/startup/android_startup_attribution_slow.out
+++ b/test/trace_processor/diff_tests/startup/android_startup_attribution_slow.out
@@ -32,7 +32,7 @@
         dur_ns: 40000000000
         dur_ms: 40000
       }
-      jit_compiled_methods: 41
+      jit_compiled_methods: 71
       time_jit_thread_pool_on_cpu {
         dur_ns: 20000000000
         dur_ms: 20000
@@ -74,8 +74,6 @@
       dex2oat_dur_ns: 0
     }
     startup_type: "hot"
-    slow_start_reason: "Time spent in OpenDexFilesFromOat*"
-    slow_start_reason: "Time spent verifying classes"
     slow_start_reason: "JIT Activity"
     slow_start_reason: "GC Activity"
     slow_start_reason: "JIT compiled methods"
diff --git a/test/trace_processor/diff_tests/startup/android_startup_attribution_slow.py b/test/trace_processor/diff_tests/startup/android_startup_attribution_slow.py
index aa81cca..93e652f 100644
--- a/test/trace_processor/diff_tests/startup/android_startup_attribution_slow.py
+++ b/test/trace_processor/diff_tests/startup/android_startup_attribution_slow.py
@@ -123,7 +123,7 @@
     ts=to_s(260), pid=APP_PID, tid=SECOND_APP_TID, buf='VerifyClass vp')
 trace.add_atrace_end(ts=to_s(280), pid=APP_PID, tid=SECOND_APP_TID)
 
-for t in range(100, 160, 2):
+for t in range(100, 160, 1):
   # JIT compilation slices
   trace.add_atrace_begin(
       ts=to_s(t), pid=APP_PID, tid=JIT_TID, buf='JIT compiling someting')
diff --git a/test/trace_processor/diff_tests/startup/android_startup_breakdown.out b/test/trace_processor/diff_tests/startup/android_startup_breakdown.out
index 132aad8..5baa172 100644
--- a/test/trace_processor/diff_tests/startup/android_startup_breakdown.out
+++ b/test/trace_processor/diff_tests/startup/android_startup_breakdown.out
@@ -102,8 +102,6 @@
       installd_dur_ns: 0
       dex2oat_dur_ns: 0
     }
-    slow_start_reason: "Main Thread - Time spent in Running state"
-    slow_start_reason: "Main Thread - Time spent in Runnable state"
     slow_start_reason: "Time spent in bindApplication"
     slow_start_reason: "Time spent in view inflation"
     slow_start_reason: "Time spent in ResourcesManager#getResources"
diff --git a/test/trace_processor/diff_tests/startup/android_startup_breakdown_slow.out b/test/trace_processor/diff_tests/startup/android_startup_breakdown_slow.out
index 2974f88..c58d970 100644
--- a/test/trace_processor/diff_tests/startup/android_startup_breakdown_slow.out
+++ b/test/trace_processor/diff_tests/startup/android_startup_breakdown_slow.out
@@ -102,8 +102,6 @@
       installd_dur_ns: 0
       dex2oat_dur_ns: 0
     }
-    slow_start_reason: "Main Thread - Time spent in Running state"
-    slow_start_reason: "Main Thread - Time spent in Runnable state"
     slow_start_reason: "Time spent in bindApplication"
     slow_start_reason: "Time spent in view inflation"
     slow_start_reason: "Time spent in ResourcesManager#getResources"
diff --git a/test/trace_processor/diff_tests/startup/android_startup_broadcast_multiple.out b/test/trace_processor/diff_tests/startup/android_startup_broadcast_multiple.out
index 8f50a7d..c0b245c 100644
--- a/test/trace_processor/diff_tests/startup/android_startup_broadcast_multiple.out
+++ b/test/trace_processor/diff_tests/startup/android_startup_broadcast_multiple.out
@@ -24,8 +24,8 @@
     system_state {
       dex2oat_running: false
       installd_running: false
-      broadcast_dispatched_count: 12
-      broadcast_received_count: 11
+      broadcast_dispatched_count: 24
+      broadcast_received_count: 52
       installd_dur_ns: 0
       dex2oat_dur_ns: 0
     }
diff --git a/test/trace_processor/diff_tests/startup/android_startup_broadcast_multiple.py b/test/trace_processor/diff_tests/startup/android_startup_broadcast_multiple.py
index 4b5f5b2..da3fab6 100644
--- a/test/trace_processor/diff_tests/startup/android_startup_broadcast_multiple.py
+++ b/test/trace_processor/diff_tests/startup/android_startup_broadcast_multiple.py
@@ -31,7 +31,7 @@
 trace.add_atrace_async_begin(ts=100, tid=2, pid=2, buf='launchingActivity#1')
 trace.add_atrace_async_end(ts=200, tid=2, pid=2, buf='launchingActivity#1')
 
-for t in range(105, 129, 2):
+for t in range(105, 129, 1):
   trace.add_atrace_begin(
       ts=t,
       tid=1,
@@ -39,7 +39,7 @@
       buf='Broadcast dispatched from android (2005:system/1000) x')
   trace.add_atrace_end(ts=t + 1, tid=1, pid=1)
 
-for t in range(130, 152, 2):
+for t in range(100, 152, 1):
   trace.add_atrace_begin(ts=t, tid=2, pid=2, buf='broadcastReceiveReg: x')
   trace.add_atrace_end(ts=t + 1, tid=2, pid=2)
 
diff --git a/test/trace_processor/diff_tests/startup/android_startup_installd_dex2oat.out b/test/trace_processor/diff_tests/startup/android_startup_installd_dex2oat.out
index 48aa205..f2b6285 100644
--- a/test/trace_processor/diff_tests/startup/android_startup_installd_dex2oat.out
+++ b/test/trace_processor/diff_tests/startup/android_startup_installd_dex2oat.out
@@ -61,6 +61,7 @@
       installd_dur_ns: 0
       dex2oat_dur_ns: 5
     }
+    slow_start_reason: "dex2oat running during launch"
   }
   startup {
     startup_id: 3
@@ -93,6 +94,7 @@
       installd_dur_ns: 5
       dex2oat_dur_ns: 0
     }
+    slow_start_reason: "installd running during launch"
   }
   startup {
     startup_id: 4
@@ -126,5 +128,7 @@
       installd_dur_ns: 5
       dex2oat_dur_ns: 5
     }
+    slow_start_reason: "dex2oat running during launch"
+    slow_start_reason: "installd running during launch"
   }
 }
diff --git a/test/trace_processor/diff_tests/startup/android_startup_lock_contention_slow.out b/test/trace_processor/diff_tests/startup/android_startup_lock_contention_slow.out
index 09a342a..cd5dc6c 100644
--- a/test/trace_processor/diff_tests/startup/android_startup_lock_contention_slow.out
+++ b/test/trace_processor/diff_tests/startup/android_startup_lock_contention_slow.out
@@ -33,12 +33,12 @@
         dur_ms: 2000.0
       }
       time_lock_contention_thread_main {
-        dur_ns: 20000000000
-        dur_ms: 20000.0
+        dur_ns: 27000000000
+        dur_ms: 27000.0
       }
       time_monitor_contention_thread_main {
-        dur_ns: 10000000000
-        dur_ms: 10000.0
+        dur_ns: 17000000000
+        dur_ms: 17000.0
       }
     }
     activity_hosting_process_count: 1
diff --git a/test/trace_processor/diff_tests/startup/android_startup_lock_contention_slow.py b/test/trace_processor/diff_tests/startup/android_startup_lock_contention_slow.py
index c447b08..482549c 100644
--- a/test/trace_processor/diff_tests/startup/android_startup_lock_contention_slow.py
+++ b/test/trace_processor/diff_tests/startup/android_startup_lock_contention_slow.py
@@ -60,7 +60,7 @@
     tid=3,
     pid=3,
     buf='Lock contention on a monitor lock (owner tid: 2)')
-trace.add_atrace_end(ts=to_s(150), tid=3, pid=3)
+trace.add_atrace_end(ts=to_s(157), tid=3, pid=3)
 
 # Lock contention on non-main thread should not be counted.
 trace.add_atrace_begin(
diff --git a/test/trace_processor/diff_tests/startup/android_startup_slow.out b/test/trace_processor/diff_tests/startup/android_startup_slow.out
index 22f2d90..3b5d1ab 100644
--- a/test/trace_processor/diff_tests/startup/android_startup_slow.out
+++ b/test/trace_processor/diff_tests/startup/android_startup_slow.out
@@ -63,7 +63,6 @@
       dex2oat_dur_ns: 0
     }
     startup_type: "warm"
-    slow_start_reason: "Main Thread - Time spent in Running state"
     slow_start_reason: "Main Thread - Time spent in Runnable state"
     slow_start_reason: "Main Thread - Time spent in interruptible sleep state"
     slow_start_reason: "Main Thread - Time spent in Blocking I/O"
diff --git a/tools/gen_tp_table_docs.py b/tools/gen_tp_table_docs.py
index 583f339..8b8565a 100755
--- a/tools/gen_tp_table_docs.py
+++ b/tools/gen_tp_table_docs.py
@@ -16,73 +16,71 @@
 import argparse
 import json
 import os
-import runpy
 import sys
 from typing import Any
 from typing import Dict
-from typing import List
 from typing import Optional
-from typing import Union
 
 # Allow importing of root-relative modules.
 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 sys.path.append(os.path.join(ROOT_DIR))
 
-from python.generators.trace_processor_table.public import Column
+#pylint: disable=wrong-import-position
 from python.generators.trace_processor_table.public import ColumnDoc
-from python.generators.trace_processor_table.public import Table
 import python.generators.trace_processor_table.util as util
+from python.generators.trace_processor_table.util import ParsedTable
+from python.generators.trace_processor_table.util import ParsedColumn
+#pylint: enable=wrong-import-position
 
 
-def gen_json_for_column(table: Table, col: Column,
-                        doc: Union[ColumnDoc, str]) -> Optional[Dict[str, Any]]:
+def gen_json_for_column(table: ParsedTable,
+                        col: ParsedColumn) -> Optional[Dict[str, Any]]:
   """Generates the JSON documentation for a column in a table."""
+  assert table.table.tabledoc
 
   # id and type columns should be skipped if the table specifies so.
-  is_skippable_col = col._is_auto_added_id or col._is_auto_added_type
-  if table.tabledoc.skip_id_and_type and is_skippable_col:
+  is_skippable_col = col.is_implicit_id or col.is_implicit_type
+  if table.table.tabledoc.skip_id_and_type and is_skippable_col:
     return None
 
   # Our default assumption is the documentation for a column is a plain string
   # so just make the comment for the column equal to that.
 
-  if isinstance(doc, ColumnDoc):
-    comment = doc.doc
-    if doc.joinable:
-      join_table, join_type = doc.joinable.split('.')
+  if isinstance(col.doc, ColumnDoc):
+    comment = col.doc.doc
+    if col.doc.joinable:
+      join_table, join_col = col.doc.joinable.split('.')
     else:
-      join_table, join_type = None, None
-  elif isinstance(doc, str):
-    comment = doc
-    join_table, join_type = None, None
+      join_table, join_col = None, None
+  elif isinstance(col.doc, str):
+    comment = col.doc
+    join_table, join_col = None, None
   else:
-    raise Exception('Unknown column documentation type')
+    raise Exception('Unknown column documentation type '
+                    f'{table.table.class_name}::{col.column.name}')
 
-  parsed_type = util.parse_type(table, col.type)
+  parsed_type = table.parse_type(col.column.type)
   docs_type = parsed_type.cpp_type
   if docs_type == 'StringPool::Id':
     docs_type = 'string'
 
   ref_class_name = None
-  if parsed_type.id_table and not col._is_auto_added_id:
-    id_table_name = util.public_sql_name_for_table(parsed_type.id_table)
+  if parsed_type.id_table and not col.is_implicit_id:
+    id_table_name = util.public_sql_name(parsed_type.id_table)
     ref_class_name = parsed_type.id_table.class_name
 
-    # We shouldn't really specify the join tables when it's a simple id join.
-    assert join_table is None
-    assert join_type is None
-
-    join_table = id_table_name
-    join_type = "id"
+    if not join_table and not join_col:
+      join_table = id_table_name
+      join_col = "id"
 
   return {
-      'name': col.name,
+      'name': col.column.name,
       'type': docs_type,
       'comment': comment,
       'optional': parsed_type.is_optional,
       'refTableCppName': ref_class_name,
       'joinTable': join_table,
-      'joinCol': join_type,
+      'joinCol': join_col,
   }
 
 
@@ -92,21 +90,18 @@
   parser.add_argument('inputs', nargs='*')
   args = parser.parse_args()
 
-  tables: List[Table] = []
-  for in_path in args.inputs:
-    tables.extend(runpy.run_path(in_path)['ALL_TABLES'])
-  for table in tables:
-    util.normalize_table_columns(table)
-
+  tables = util.parse_tables_from_files(args.inputs)
   table_docs = []
-  for table in tables:
+  for parsed in tables:
+    table = parsed.table
     doc = table.tabledoc
+    assert doc
     cols = (
-        gen_json_for_column(table, c, doc.columns[c.name])
-        for c in table.columns
-        if c._is_self_column)
+        gen_json_for_column(parsed, c)
+        for c in parsed.columns
+        if not c.is_ancestor)
     table_docs.append({
-        'name': util.public_sql_name_for_table(table),
+        'name': util.public_sql_name(table),
         'cppClassName': table.class_name,
         'defMacro': table.class_name,
         'comment': '\n'.join(l.strip() for l in doc.doc.splitlines()),
diff --git a/tools/gen_tp_table_headers.py b/tools/gen_tp_table_headers.py
index 2f4f8c4..1ce0963 100755
--- a/tools/gen_tp_table_headers.py
+++ b/tools/gen_tp_table_headers.py
@@ -17,8 +17,8 @@
 from dataclasses import dataclass
 import os
 import re
-import runpy
 import sys
+from typing import Dict
 from typing import List
 from typing import Set
 
@@ -27,12 +27,9 @@
 sys.path.append(os.path.join(ROOT_DIR))
 
 #pylint: disable=wrong-import-position
-from python.generators.trace_processor_table.public import Alias
-from python.generators.trace_processor_table.public import Table
 from python.generators.trace_processor_table.serialize import serialize_header
-from python.generators.trace_processor_table.util import find_table_deps
-from python.generators.trace_processor_table.util import normalize_table_columns
-from python.generators.trace_processor_table.util import topological_sort_tables
+from python.generators.trace_processor_table.util import ParsedTable
+from python.generators.trace_processor_table.util import parse_tables_from_files
 #pylint: enable=wrong-import-position
 
 
@@ -41,7 +38,7 @@
   """Represents a Python module which will be converted to a header."""
   out_path: str
   relout_path: str
-  tables: List[Table]
+  tables: List[ParsedTable]
 
 
 def main():
@@ -50,54 +47,46 @@
   parser.add_argument('--gen-dir', required=True)
   parser.add_argument('--inputs', required=True, nargs='*')
   parser.add_argument('--outputs', required=True, nargs='*')
+  parser.add_argument('--header-prefix')
   args = parser.parse_args()
 
   if len(args.inputs) != len(args.outputs):
     raise Exception('Number of inputs must match number of outputs')
 
-  headers: List[Header] = []
-  for (in_path, out_path) in zip(args.inputs, args.outputs):
-    tables = runpy.run_path(in_path)['ALL_TABLES']
-    relout_path = os.path.relpath(out_path, args.gen_dir)
-    headers.append(Header(out_path, relout_path, tables))
+  header_prefix = args.header_prefix if args.header_prefix else ''
+  in_to_out = dict(zip(args.inputs, args.outputs))
+  headers: Dict[str, Header] = {}
+  for table in parse_tables_from_files(args.inputs):
+    out_path = in_to_out[table.input_path]
+    relout_path = os.path.join(header_prefix,
+                               os.path.relpath(out_path, args.gen_dir))
+
+    header = headers.get(table.input_path, Header(out_path, relout_path, []))
+    header.tables.append(table)
+    headers[table.input_path] = header
 
   # Build a mapping from table class name to the output path of the header
   # which will be generated for it. This is used to include one header into
   # another for Id dependencies.
-  table_class_name_to_relout = {}
-  for header in headers:
+  table_class_name_to_relout: Dict[str, str] = {}
+  for header in headers.values():
     for table in header.tables:
-      table_class_name_to_relout[table.class_name] = header.relout_path
+      table_class_name_to_relout[table.table.class_name] = header.relout_path
 
-  for header in headers:
-    # Remove any alias columns. Today these are handled in SQL not C++: this may
-    # change in the future.
-    for table in header.tables:
-      table.columns = [
-          c for c in table.columns if not isinstance(c.type, Alias)
-      ]
-
-    # Topologically sort the tables in this header to ensure that any deps are
-    # defined *before* the table itself.
-    sorted_tables = topological_sort_tables(header.tables)
-
-    # Normalize all the columns to ensure that they are ready for serialization.
-    for table in sorted_tables:
-      normalize_table_columns(table)
-
+  for header in headers.values():
     # Find all headers depended on by this table. These will be #include-ed when
     # generating the header file below so ensure we remove ourself.
     header_relout_deps: Set[str] = set()
-    for table in sorted_tables:
-      header_relout_deps.union(
-          table_class_name_to_relout[c] for c in find_table_deps(table))
+    for table in header.tables:
+      header_relout_deps = header_relout_deps.union(
+          [table_class_name_to_relout[c] for c in table.find_table_deps()])
     header_relout_deps.discard(header.relout_path)
 
     with open(header.out_path, 'w', encoding='utf8') as out:
       ifdef_guard = re.sub(r'[^a-zA-Z0-9_-]', '_',
                            header.relout_path).upper() + '_'
       out.write(
-          serialize_header(ifdef_guard, sorted_tables,
+          serialize_header(ifdef_guard, header.tables,
                            sorted(header_relout_deps)))
       out.write('\n')
 
diff --git a/tools/install-build-deps b/tools/install-build-deps
index e694fda..68c5518 100755
--- a/tools/install-build-deps
+++ b/tools/install-build-deps
@@ -327,7 +327,7 @@
 # This variable is updated by tools/roll-catapult-trace-viewer.
 CATAPULT_SHA256 = 'b30108e05268ce6c65bb4126b65f6bfac165d17f5c1fd285046e7e6fd76c209f'
 
-TYPEFACES_SHA256 = '727fc9d7fd2f7b4b77d89a4e048ed210ef63497546411c2ec9e4f44bb9744519'
+TYPEFACES_SHA256 = '1065172aaf0e9c22bc4f206ed9fdf5f1b4355d233fb21f9f26a89cd66c941940'
 
 UI_DEPS = [
     Dependency(
diff --git a/ui/build.js b/ui/build.js
index 9a0ded5..eeca3bc 100644
--- a/ui/build.js
+++ b/ui/build.js
@@ -135,27 +135,27 @@
 
 async function main() {
   const parser = new argparse.ArgumentParser();
-  parser.addArgument('--out', {help: 'Output directory'});
-  parser.addArgument(['--watch', '-w'], {action: 'storeTrue'});
-  parser.addArgument(['--serve', '-s'], {action: 'storeTrue'});
-  parser.addArgument('--serve-host', {help: '--serve bind host'});
-  parser.addArgument('--serve-port', {help: '--serve bind port', type: 'int'});
-  parser.addArgument(['--verbose', '-v'], {action: 'storeTrue'});
-  parser.addArgument(['--no-build', '-n'], {action: 'storeTrue'});
-  parser.addArgument(['--no-wasm', '-W'], {action: 'storeTrue'});
-  parser.addArgument(['--run-unittests', '-t'], {action: 'storeTrue'});
-  parser.addArgument(['--run-integrationtests', '-T'], {action: 'storeTrue'});
-  parser.addArgument(['--debug', '-d'], {action: 'storeTrue'});
-  parser.addArgument(['--interactive', '-i'], {action: 'storeTrue'});
-  parser.addArgument(['--rebaseline', '-r'], {action: 'storeTrue'});
-  parser.addArgument(['--no-depscheck'], {action: 'storeTrue'});
-  parser.addArgument('--cross-origin-isolation', {action: 'storeTrue'});
-  parser.addArgument(
-      ['--test-filter', '-f'],
-      {help: 'filter Jest tests by regex, e.g. \'chrome_render\''});
-  parser.addArgument(['--no-override-gn-args'], {action: 'storeTrue'});
+  parser.add_argument('--out', {help: 'Output directory'});
+  parser.add_argument('--watch', '-w', {action: 'store_true'});
+  parser.add_argument('--serve', '-s', {action: 'store_true'});
+  parser.add_argument('--serve-host', {help: '--serve bind host'});
+  parser.add_argument('--serve-port', {help: '--serve bind port', type: 'int'});
+  parser.add_argument('--verbose', '-v', {action: 'store_true'});
+  parser.add_argument('--no-build', '-n', {action: 'store_true'});
+  parser.add_argument('--no-wasm', '-W', {action: 'store_true'});
+  parser.add_argument('--run-unittests', '-t', {action: 'store_true'});
+  parser.add_argument('--run-integrationtests', '-T', {action: 'store_true'});
+  parser.add_argument('--debug', '-d', {action: 'store_true'});
+  parser.add_argument('--interactive', '-i', {action: 'store_true'});
+  parser.add_argument('--rebaseline', '-r', {action: 'store_true'});
+  parser.add_argument('--no-depscheck', {action: 'store_true'});
+  parser.add_argument('--cross-origin-isolation', {action: 'store_true'});
+  parser.add_argument('--test-filter', '-f', {
+    help: 'filter Jest tests by regex, e.g. \'chrome_render\'',
+  });
+  parser.add_argument('--no-override-gn-args', {action: 'store_true'});
 
-  const args = parser.parseArgs();
+  const args = parser.parse_args();
   const clean = !args.no_build;
   cfg.outDir = path.resolve(ensureDir(args.out || cfg.outDir));
   cfg.outUiDir = ensureDir(pjoin(cfg.outDir, 'ui'), clean);
@@ -241,6 +241,12 @@
     genVersion();
     transpileTsProject('ui');
     transpileTsProject('ui/src/service_worker');
+
+    if (cfg.watch) {
+      transpileTsProject('ui', {watch: cfg.watch});
+      transpileTsProject('ui/src/service_worker', {watch: cfg.watch});
+    }
+
     bundleJs('rollup.config.js');
     genServiceWorkerManifestJson();
 
@@ -250,7 +256,6 @@
     scanDir(cfg.outDistRootDir);
   }
 
-
   // We should enter the loop only in watch mode, where tsc and rollup are
   // asynchronous because they run in watch mode.
   if (args.no_build && !isDistComplete()) {
@@ -344,6 +349,10 @@
 function compileProtos() {
   const dstJs = pjoin(cfg.outGenDir, 'protos.js');
   const dstTs = pjoin(cfg.outGenDir, 'protos.d.ts');
+  // We've ended up pulling in all the protos (via trace.proto,
+  // trace_packet.proto) below which means |dstJs| ends up being
+  // 23k lines/12mb. We should probably not do that.
+  // TODO(hjd): Figure out how to use lazy with pbjs/pbts.
   const inputs = [
     'protos/perfetto/common/trace_stats.proto',
     'protos/perfetto/common/tracing_service_capabilities.proto',
@@ -361,6 +370,8 @@
   const pbjsArgs = [
     '--no-beautify',
     '--force-number',
+    '--no-delimited',
+    '--no-verify',
     '-t',
     'static-module',
     '-w',
@@ -371,6 +382,11 @@
     dstJs,
   ].concat(inputs);
   addTask(execNode, ['pbjs', pbjsArgs]);
+
+  // Note: If you are looking into slowness of pbts it is not pbts
+  // itself that is slow. It invokes jsdoc to parse the comments out of
+  // the |dstJs| with https://github.com/hegemonic/catharsis which is
+  // pinning a CPU core the whole time.
   const pbtsArgs = ['--no-comments', '-p', ROOT_DIR, '-o', dstTs, dstJs];
   addTask(execNode, ['pbts', pbtsArgs]);
 }
@@ -450,9 +466,10 @@
 
 // This transpiles all the sources (frontend, controller, engine, extension) in
 // one go. The only project that has a dedicated invocation is service_worker.
-function transpileTsProject(project) {
+function transpileTsProject(project, options) {
   const args = ['--project', pjoin(ROOT_DIR, project)];
-  if (cfg.watch) {
+
+  if (options !== undefined && options.watch) {
     args.push('--watch', '--preserveWatchOutput');
     addTask(execNode, ['tsc', args, {async: true}]);
   } else {
@@ -466,9 +483,9 @@
   const args = ['-c', rcfg, '--no-indent'];
   args.push(...(cfg.verbose ? [] : ['--silent']));
   if (cfg.watch) {
-    // --waitForBundleInput is so that we can run tsc --watch and rollup --watch
-    // together, without having to wait that tsc completes the first build.
-    args.push('--watch', '--waitForBundleInput', '--no-watch.clearScreen');
+    // --waitForBundleInput is sadly quite busted so it is required ts
+    // has build at least once before invoking this.
+    args.push('--watch', '--no-watch.clearScreen');
     addTask(execNode, ['rollup', args, {async: true}]);
   } else {
     addTask(execNode, ['rollup', args]);
diff --git a/ui/config/rollup-serviceworker.config.js b/ui/config/rollup-serviceworker.config.js
deleted file mode 100644
index 023dbdd..0000000
--- a/ui/config/rollup-serviceworker.config.js
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (C) 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import commonjs from '@rollup/plugin-commonjs';
-import nodeResolve from '@rollup/plugin-node-resolve';
-import sourcemaps from 'rollup-plugin-sourcemaps';
-
-const path = require('path');
-const ROOT_DIR = path.dirname(path.dirname(__dirname));  // The repo root.
-const OUT_SYMLINK = path.join(ROOT_DIR, 'ui/out');
-
-export default [{
-  input: `${OUT_SYMLINK}/tsc/service_worker/service_worker.js`,
-  output: {
-    name: 'service_worker',
-    format: 'iife',
-    esModule: false,
-    file: `${OUT_SYMLINK}/dist/service_worker.js`,
-    sourcemap: true,
-  },
-  plugins: [
-    nodeResolve({
-      mainFields: ['browser'],
-      browser: true,
-      preferBuiltins: false,
-    }),
-    commonjs(),
-    sourcemaps(),
-  ],
-}];
diff --git a/ui/config/rollup.config.js b/ui/config/rollup.config.js
index 7372ccf..d83d2b9 100644
--- a/ui/config/rollup.config.js
+++ b/ui/config/rollup.config.js
@@ -37,16 +37,9 @@
         browser: true,
         preferBuiltins: false,
       }),
-      // emscripten conditionally executes require('fs') (likewise for
-      // others), when running under node. Rollup can't find those libraries
-      // so expects these to be present in the global scope, which then fails
-      // at runtime. To avoid this we ignore require('fs') and the like.
+
       commonjs({
-        ignore: [
-          'fs',
-          'path',
-          'crypto',
-        ],
+        strictRequires: true,
       }),
 
       replace({
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 361b7f1..7dc51bd 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -32,69 +32,87 @@
         "pako": "^1.0.11",
         "protobufjs": "^6.9.0",
         "util": "^0.12.3",
-        "uuid": "^8.3.2"
+        "uuid": "^9.0.0"
       },
       "devDependencies": {
-        "@rollup/plugin-commonjs": "^14.0.0",
-        "@rollup/plugin-node-resolve": "^8.4.0",
+        "@rollup/plugin-commonjs": "^24.0.1",
+        "@rollup/plugin-node-resolve": "^15.0.1",
         "@types/jest": "^26.0.23",
         "@types/pixelmatch": "^5.2.3",
-        "@types/puppeteer": "^5.4.6",
-        "@typescript-eslint/eslint-plugin": "^5.25.0",
+        "@typescript-eslint/eslint-plugin": "^5.56.0",
         "@typescript-eslint/parser": "^5.25.0",
         "dingusjs": "^0.0.3",
         "eslint": "^8.15.0",
         "eslint-config-google": "^0.14.0",
         "jest": "^26.6.3",
-        "node-sass": "^7.0.1",
+        "node-sass": "^8.0.0",
         "node-watch": "^0.7.1",
         "pixelmatch": "^5.2.1",
         "pngjs": "^6.0.0",
         "prettier": "^2.8.0",
-        "puppeteer": "^14.1.0",
+        "puppeteer": "^19.8.0",
         "rollup": "^2.38.5",
         "rollup-plugin-re": "^1.0.7",
         "rollup-plugin-sourcemaps": "^0.6.3",
-        "tslib": "^2.2.0",
-        "typescript": "^4.6.4"
+        "tslib": "^2.5.0",
+        "typescript": "^4.9.5"
+      }
+    },
+    "node_modules/@ampproject/remapping": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+      "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.1.0",
+        "@jridgewell/trace-mapping": "^0.3.9"
+      },
+      "engines": {
+        "node": ">=6.0.0"
       }
     },
     "node_modules/@babel/code-frame": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
-      "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
       "dev": true,
       "dependencies": {
-        "@babel/highlight": "^7.12.13"
+        "@babel/highlight": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/compat-data": {
-      "version": "7.14.4",
-      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.4.tgz",
-      "integrity": "sha512-i2wXrWQNkH6JplJQGn3Rd2I4Pij8GdHkXwHMxm+zV5YG/Jci+bCNrWZEWC4o+umiDkRrRs4dVzH3X4GP7vyjQQ==",
-      "dev": true
+      "version": "7.21.0",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz",
+      "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
     },
     "node_modules/@babel/core": {
-      "version": "7.14.3",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.3.tgz",
-      "integrity": "sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg==",
+      "version": "7.21.3",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.3.tgz",
+      "integrity": "sha512-qIJONzoa/qiHghnm0l1n4i/6IIziDpzqc36FBs4pzMhDUraHqponwJLiAKm1hGLP3OSB/TVNz6rMwVGpwxxySw==",
       "dev": true,
       "dependencies": {
-        "@babel/code-frame": "^7.12.13",
-        "@babel/generator": "^7.14.3",
-        "@babel/helper-compilation-targets": "^7.13.16",
-        "@babel/helper-module-transforms": "^7.14.2",
-        "@babel/helpers": "^7.14.0",
-        "@babel/parser": "^7.14.3",
-        "@babel/template": "^7.12.13",
-        "@babel/traverse": "^7.14.2",
-        "@babel/types": "^7.14.2",
+        "@ampproject/remapping": "^2.2.0",
+        "@babel/code-frame": "^7.18.6",
+        "@babel/generator": "^7.21.3",
+        "@babel/helper-compilation-targets": "^7.20.7",
+        "@babel/helper-module-transforms": "^7.21.2",
+        "@babel/helpers": "^7.21.0",
+        "@babel/parser": "^7.21.3",
+        "@babel/template": "^7.20.7",
+        "@babel/traverse": "^7.21.3",
+        "@babel/types": "^7.21.3",
         "convert-source-map": "^1.7.0",
         "debug": "^4.1.0",
         "gensync": "^1.0.0-beta.2",
-        "json5": "^2.1.2",
-        "semver": "^6.3.0",
-        "source-map": "^0.5.0"
+        "json5": "^2.2.2",
+        "semver": "^6.3.0"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -104,187 +122,223 @@
         "url": "https://opencollective.com/babel"
       }
     },
-    "node_modules/@babel/core/node_modules/source-map": {
-      "version": "0.5.7",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+    "node_modules/@babel/core/node_modules/semver": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
       "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
+      "bin": {
+        "semver": "bin/semver.js"
       }
     },
     "node_modules/@babel/generator": {
-      "version": "7.14.3",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz",
-      "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==",
+      "version": "7.21.3",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.3.tgz",
+      "integrity": "sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.14.2",
-        "jsesc": "^2.5.1",
-        "source-map": "^0.5.0"
+        "@babel/types": "^7.21.3",
+        "@jridgewell/gen-mapping": "^0.3.2",
+        "@jridgewell/trace-mapping": "^0.3.17",
+        "jsesc": "^2.5.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
-    "node_modules/@babel/generator/node_modules/source-map": {
-      "version": "0.5.7",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+    "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+      "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
       "dev": true,
+      "dependencies": {
+        "@jridgewell/set-array": "^1.0.1",
+        "@jridgewell/sourcemap-codec": "^1.4.10",
+        "@jridgewell/trace-mapping": "^0.3.9"
+      },
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=6.0.0"
       }
     },
     "node_modules/@babel/helper-compilation-targets": {
-      "version": "7.14.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.4.tgz",
-      "integrity": "sha512-JgdzOYZ/qGaKTVkn5qEDV/SXAh8KcyUVkCoSWGN8T3bwrgd6m+/dJa2kVGi6RJYJgEYPBdZ84BZp9dUjNWkBaA==",
+      "version": "7.20.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz",
+      "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==",
       "dev": true,
       "dependencies": {
-        "@babel/compat-data": "^7.14.4",
-        "@babel/helper-validator-option": "^7.12.17",
-        "browserslist": "^4.16.6",
+        "@babel/compat-data": "^7.20.5",
+        "@babel/helper-validator-option": "^7.18.6",
+        "browserslist": "^4.21.3",
+        "lru-cache": "^5.1.1",
         "semver": "^6.3.0"
       },
+      "engines": {
+        "node": ">=6.9.0"
+      },
       "peerDependencies": {
         "@babel/core": "^7.0.0"
       }
     },
+    "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/helper-environment-visitor": {
+      "version": "7.18.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
+      "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/@babel/helper-function-name": {
-      "version": "7.14.2",
-      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz",
-      "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==",
+      "version": "7.21.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz",
+      "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-get-function-arity": "^7.12.13",
-        "@babel/template": "^7.12.13",
-        "@babel/types": "^7.14.2"
+        "@babel/template": "^7.20.7",
+        "@babel/types": "^7.21.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
-    "node_modules/@babel/helper-get-function-arity": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
-      "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
+    "node_modules/@babel/helper-hoist-variables": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
+      "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.12.13"
-      }
-    },
-    "node_modules/@babel/helper-member-expression-to-functions": {
-      "version": "7.13.12",
-      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz",
-      "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==",
-      "dev": true,
-      "dependencies": {
-        "@babel/types": "^7.13.12"
+        "@babel/types": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-module-imports": {
-      "version": "7.13.12",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz",
-      "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz",
+      "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.13.12"
+        "@babel/types": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-module-transforms": {
-      "version": "7.14.2",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz",
-      "integrity": "sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA==",
+      "version": "7.21.2",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz",
+      "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-module-imports": "^7.13.12",
-        "@babel/helper-replace-supers": "^7.13.12",
-        "@babel/helper-simple-access": "^7.13.12",
-        "@babel/helper-split-export-declaration": "^7.12.13",
-        "@babel/helper-validator-identifier": "^7.14.0",
-        "@babel/template": "^7.12.13",
-        "@babel/traverse": "^7.14.2",
-        "@babel/types": "^7.14.2"
-      }
-    },
-    "node_modules/@babel/helper-module-transforms/node_modules/@babel/helper-validator-identifier": {
-      "version": "7.14.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
-      "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
-      "dev": true
-    },
-    "node_modules/@babel/helper-optimise-call-expression": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz",
-      "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==",
-      "dev": true,
-      "dependencies": {
-        "@babel/types": "^7.12.13"
+        "@babel/helper-environment-visitor": "^7.18.9",
+        "@babel/helper-module-imports": "^7.18.6",
+        "@babel/helper-simple-access": "^7.20.2",
+        "@babel/helper-split-export-declaration": "^7.18.6",
+        "@babel/helper-validator-identifier": "^7.19.1",
+        "@babel/template": "^7.20.7",
+        "@babel/traverse": "^7.21.2",
+        "@babel/types": "^7.21.2"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-plugin-utils": {
-      "version": "7.13.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz",
-      "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==",
-      "dev": true
-    },
-    "node_modules/@babel/helper-replace-supers": {
-      "version": "7.14.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.4.tgz",
-      "integrity": "sha512-zZ7uHCWlxfEAAOVDYQpEf/uyi1dmeC7fX4nCf2iz9drnCwi1zvwXL3HwWWNXUQEJ1k23yVn3VbddiI9iJEXaTQ==",
+      "version": "7.20.2",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
+      "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==",
       "dev": true,
-      "dependencies": {
-        "@babel/helper-member-expression-to-functions": "^7.13.12",
-        "@babel/helper-optimise-call-expression": "^7.12.13",
-        "@babel/traverse": "^7.14.2",
-        "@babel/types": "^7.14.4"
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-simple-access": {
-      "version": "7.13.12",
-      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz",
-      "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==",
+      "version": "7.20.2",
+      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
+      "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.13.12"
+        "@babel/types": "^7.20.2"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-split-export-declaration": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz",
-      "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
+      "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.12.13"
+        "@babel/types": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-string-parser": {
+      "version": "7.19.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
+      "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.12.11",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
-      "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==",
-      "dev": true
+      "version": "7.19.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+      "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
     },
     "node_modules/@babel/helper-validator-option": {
-      "version": "7.12.17",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz",
-      "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==",
-      "dev": true
+      "version": "7.21.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz",
+      "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
     },
     "node_modules/@babel/helpers": {
-      "version": "7.14.0",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz",
-      "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==",
+      "version": "7.21.0",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz",
+      "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==",
       "dev": true,
       "dependencies": {
-        "@babel/template": "^7.12.13",
-        "@babel/traverse": "^7.14.0",
-        "@babel/types": "^7.14.0"
+        "@babel/template": "^7.20.7",
+        "@babel/traverse": "^7.21.0",
+        "@babel/types": "^7.21.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/highlight": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz",
-      "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-validator-identifier": "^7.12.11",
+        "@babel/helper-validator-identifier": "^7.18.6",
         "chalk": "^2.0.0",
         "js-tokens": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/highlight/node_modules/ansi-styles": {
@@ -325,13 +379,22 @@
     "node_modules/@babel/highlight/node_modules/color-name": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
       "dev": true
     },
+    "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
     "node_modules/@babel/highlight/node_modules/has-flag": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
       "dev": true,
       "engines": {
         "node": ">=4"
@@ -350,9 +413,9 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.14.4",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz",
-      "integrity": "sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==",
+      "version": "7.21.3",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.3.tgz",
+      "integrity": "sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==",
       "dev": true,
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -494,60 +557,78 @@
       }
     },
     "node_modules/@babel/plugin-syntax-top-level-await": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz",
-      "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==",
+      "version": "7.14.5",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+      "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.12.13"
+        "@babel/helper-plugin-utils": "^7.14.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       },
       "peerDependencies": {
         "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/template": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
-      "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
+      "version": "7.20.7",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz",
+      "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==",
       "dev": true,
       "dependencies": {
-        "@babel/code-frame": "^7.12.13",
-        "@babel/parser": "^7.12.13",
-        "@babel/types": "^7.12.13"
+        "@babel/code-frame": "^7.18.6",
+        "@babel/parser": "^7.20.7",
+        "@babel/types": "^7.20.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.14.2",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz",
-      "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==",
+      "version": "7.21.3",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.3.tgz",
+      "integrity": "sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==",
       "dev": true,
       "dependencies": {
-        "@babel/code-frame": "^7.12.13",
-        "@babel/generator": "^7.14.2",
-        "@babel/helper-function-name": "^7.14.2",
-        "@babel/helper-split-export-declaration": "^7.12.13",
-        "@babel/parser": "^7.14.2",
-        "@babel/types": "^7.14.2",
+        "@babel/code-frame": "^7.18.6",
+        "@babel/generator": "^7.21.3",
+        "@babel/helper-environment-visitor": "^7.18.9",
+        "@babel/helper-function-name": "^7.21.0",
+        "@babel/helper-hoist-variables": "^7.18.6",
+        "@babel/helper-split-export-declaration": "^7.18.6",
+        "@babel/parser": "^7.21.3",
+        "@babel/types": "^7.21.3",
         "debug": "^4.1.0",
         "globals": "^11.1.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse/node_modules/globals": {
+      "version": "11.12.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
       }
     },
     "node_modules/@babel/types": {
-      "version": "7.14.4",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
-      "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+      "version": "7.21.3",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.3.tgz",
+      "integrity": "sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-validator-identifier": "^7.14.0",
+        "@babel/helper-string-parser": "^7.19.4",
+        "@babel/helper-validator-identifier": "^7.19.1",
         "to-fast-properties": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
-    "node_modules/@babel/types/node_modules/@babel/helper-validator-identifier": {
-      "version": "7.14.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
-      "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
-      "dev": true
-    },
     "node_modules/@bcoe/v8-coverage": {
       "version": "0.2.3",
       "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
@@ -571,9 +652,9 @@
       }
     },
     "node_modules/@esbuild/android-arm": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.12.tgz",
-      "integrity": "sha512-IC7TqIqiyE0MmvAhWkl/8AEzpOtbhRNDo7aph47We1NbE5w2bt/Q+giAhe0YYeVpYnIhGMcuZY92qDK6dQauvA==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.18.tgz",
+      "integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==",
       "cpu": [
         "arm"
       ],
@@ -586,9 +667,9 @@
       }
     },
     "node_modules/@esbuild/linux-loong64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.12.tgz",
-      "integrity": "sha512-tZEowDjvU7O7I04GYvWQOS4yyP9E/7YlsB0jjw1Ycukgr2ycEzKyIk5tms5WnLBymaewc6VmRKnn5IJWgK4eFw==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz",
+      "integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==",
       "cpu": [
         "loong64"
       ],
@@ -600,16 +681,40 @@
         "node": ">=12"
       }
     },
+    "node_modules/@eslint-community/eslint-utils": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+      "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+      "dev": true,
+      "dependencies": {
+        "eslint-visitor-keys": "^3.3.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+      }
+    },
+    "node_modules/@eslint-community/regexpp": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.1.tgz",
+      "integrity": "sha512-BISJ6ZE4xQsuL/FmsyRaiffpq977bMlsKfGHTQrOGFErfByxIe6iZTxPf/00Zon9b9a7iUykfQwejN3s2ZW/Bw==",
+      "dev": true,
+      "engines": {
+        "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+      }
+    },
     "node_modules/@eslint/eslintrc": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz",
-      "integrity": "sha512-uGo44hIwoLGNyduRpjdEpovcbMdd+Nv7amtmJxnKmI8xj6yd5LncmSwDa5NgX/41lIFJtkjD6YdVfgEzPfJ5UA==",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz",
+      "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==",
       "dev": true,
       "dependencies": {
         "ajv": "^6.12.4",
         "debug": "^4.3.2",
-        "espree": "^9.3.2",
-        "globals": "^13.9.0",
+        "espree": "^9.5.0",
+        "globals": "^13.19.0",
         "ignore": "^5.2.0",
         "import-fresh": "^3.2.1",
         "js-yaml": "^4.1.0",
@@ -618,63 +723,18 @@
       },
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      }
-    },
-    "node_modules/@eslint/eslintrc/node_modules/argparse": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
-      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
-      "dev": true
-    },
-    "node_modules/@eslint/eslintrc/node_modules/globals": {
-      "version": "13.15.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz",
-      "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==",
-      "dev": true,
-      "dependencies": {
-        "type-fest": "^0.20.2"
-      },
-      "engines": {
-        "node": ">=8"
       },
       "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "url": "https://opencollective.com/eslint"
       }
     },
-    "node_modules/@eslint/eslintrc/node_modules/js-yaml": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
-      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
-      "dev": true,
-      "dependencies": {
-        "argparse": "^2.0.1"
-      },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
-      }
-    },
-    "node_modules/@eslint/eslintrc/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/@eslint/eslintrc/node_modules/type-fest": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
-      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+    "node_modules/@eslint/js": {
+      "version": "8.36.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz",
+      "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==",
       "dev": true,
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
       }
     },
     "node_modules/@gar/promisify": {
@@ -684,19 +744,32 @@
       "dev": true
     },
     "node_modules/@humanwhocodes/config-array": {
-      "version": "0.9.5",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
-      "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
+      "version": "0.11.8",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
+      "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==",
       "dev": true,
       "dependencies": {
         "@humanwhocodes/object-schema": "^1.2.1",
         "debug": "^4.1.1",
-        "minimatch": "^3.0.4"
+        "minimatch": "^3.0.5"
       },
       "engines": {
         "node": ">=10.10.0"
       }
     },
+    "node_modules/@humanwhocodes/module-importer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+      "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+      "dev": true,
+      "engines": {
+        "node": ">=12.22"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/nzakas"
+      }
+    },
     "node_modules/@humanwhocodes/object-schema": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
@@ -719,6 +792,89 @@
         "node": ">=8"
       }
     },
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+      "dev": true,
+      "dependencies": {
+        "sprintf-js": "~1.0.2"
+      }
+    },
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
+      "version": "3.14.1",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+      "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+      "dev": true,
+      "dependencies": {
+        "argparse": "^1.0.7",
+        "esprima": "^4.0.0"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
+      }
+    },
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/@istanbuljs/schema": {
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
@@ -784,6 +940,43 @@
         "node": ">= 10.14.2"
       }
     },
+    "node_modules/@jest/core/node_modules/jest-config": {
+      "version": "26.6.3",
+      "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz",
+      "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/core": "^7.1.0",
+        "@jest/test-sequencer": "^26.6.3",
+        "@jest/types": "^26.6.2",
+        "babel-jest": "^26.6.3",
+        "chalk": "^4.0.0",
+        "deepmerge": "^4.2.2",
+        "glob": "^7.1.1",
+        "graceful-fs": "^4.2.4",
+        "jest-environment-jsdom": "^26.6.2",
+        "jest-environment-node": "^26.6.2",
+        "jest-get-type": "^26.3.0",
+        "jest-jasmine2": "^26.6.3",
+        "jest-regex-util": "^26.0.0",
+        "jest-resolve": "^26.6.2",
+        "jest-util": "^26.6.2",
+        "jest-validate": "^26.6.2",
+        "micromatch": "^4.0.2",
+        "pretty-format": "^26.6.2"
+      },
+      "engines": {
+        "node": ">= 10.14.2"
+      },
+      "peerDependencies": {
+        "ts-node": ">=9.0.0"
+      },
+      "peerDependenciesMeta": {
+        "ts-node": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@jest/environment": {
       "version": "26.6.2",
       "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz",
@@ -955,6 +1148,53 @@
         "node": ">= 10.14.2"
       }
     },
+    "node_modules/@jridgewell/gen-mapping": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+      "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/set-array": "^1.0.0",
+        "@jridgewell/sourcemap-codec": "^1.4.10"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/resolve-uri": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+      "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/set-array": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+      "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/sourcemap-codec": {
+      "version": "1.4.14",
+      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+      "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+      "dev": true
+    },
+    "node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.17",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+      "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/resolve-uri": "3.1.0",
+        "@jridgewell/sourcemap-codec": "1.4.14"
+      }
+    },
     "node_modules/@nodelib/fs.scandir": {
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -1000,25 +1240,11 @@
         "semver": "^7.3.5"
       }
     },
-    "node_modules/@npmcli/fs/node_modules/semver": {
-      "version": "7.3.7",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
-      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
-      "dev": true,
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/@npmcli/move-file": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
       "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
+      "deprecated": "This functionality has been moved to @npmcli/fs",
       "dev": true,
       "dependencies": {
         "mkdirp": "^1.0.4",
@@ -1028,22 +1254,10 @@
         "node": ">=10"
       }
     },
-    "node_modules/@npmcli/move-file/node_modules/mkdirp": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
-      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
-      "dev": true,
-      "bin": {
-        "mkdirp": "bin/cmd.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/@popperjs/core": {
-      "version": "2.11.6",
-      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
-      "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
+      "version": "2.11.7",
+      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz",
+      "integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==",
       "funding": {
         "type": "opencollective",
         "url": "https://opencollective.com/popperjs"
@@ -1052,7 +1266,7 @@
     "node_modules/@protobufjs/aspromise": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
-      "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78="
+      "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
     },
     "node_modules/@protobufjs/base64": {
       "version": "1.1.2",
@@ -1067,12 +1281,12 @@
     "node_modules/@protobufjs/eventemitter": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
-      "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A="
+      "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
     },
     "node_modules/@protobufjs/fetch": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
-      "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=",
+      "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
       "dependencies": {
         "@protobufjs/aspromise": "^1.1.1",
         "@protobufjs/inquire": "^1.1.0"
@@ -1081,70 +1295,186 @@
     "node_modules/@protobufjs/float": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
-      "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E="
+      "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
     },
     "node_modules/@protobufjs/inquire": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
-      "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik="
+      "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
     },
     "node_modules/@protobufjs/path": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
-      "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0="
+      "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
     },
     "node_modules/@protobufjs/pool": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
-      "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q="
+      "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
     },
     "node_modules/@protobufjs/utf8": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
-      "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
+      "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
     },
     "node_modules/@rollup/plugin-commonjs": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-14.0.0.tgz",
-      "integrity": "sha512-+PSmD9ePwTAeU106i9FRdc+Zb3XUWyW26mo5Atr2mk82hor8+nPwkztEjFo8/B1fJKfaQDg9aM2bzQkjhi7zOw==",
+      "version": "24.0.1",
+      "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.1.tgz",
+      "integrity": "sha512-15LsiWRZk4eOGqvrJyu3z3DaBu5BhXIMeWnijSRvd8irrrg9SHpQ1pH+BUK4H6Z9wL9yOxZJMTLU+Au86XHxow==",
       "dev": true,
       "dependencies": {
-        "@rollup/pluginutils": "^3.0.8",
+        "@rollup/pluginutils": "^5.0.1",
         "commondir": "^1.0.1",
-        "estree-walker": "^1.0.1",
-        "glob": "^7.1.2",
-        "is-reference": "^1.1.2",
-        "magic-string": "^0.25.2",
-        "resolve": "^1.11.0"
+        "estree-walker": "^2.0.2",
+        "glob": "^8.0.3",
+        "is-reference": "1.2.1",
+        "magic-string": "^0.27.0"
       },
       "engines": {
-        "node": ">= 8.0.0"
+        "node": ">=14.0.0"
       },
       "peerDependencies": {
-        "rollup": "^2.3.4"
+        "rollup": "^2.68.0||^3.0.0"
+      },
+      "peerDependenciesMeta": {
+        "rollup": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@rollup/plugin-commonjs/node_modules/@rollup/pluginutils": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
+      "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
+      "dev": true,
+      "dependencies": {
+        "@types/estree": "^1.0.0",
+        "estree-walker": "^2.0.2",
+        "picomatch": "^2.3.1"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      },
+      "peerDependencies": {
+        "rollup": "^1.20.0||^2.0.0||^3.0.0"
+      },
+      "peerDependenciesMeta": {
+        "rollup": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@rollup/plugin-commonjs/node_modules/@types/estree": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
+      "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==",
+      "dev": true
+    },
+    "node_modules/@rollup/plugin-commonjs/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/@rollup/plugin-commonjs/node_modules/estree-walker": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+      "dev": true
+    },
+    "node_modules/@rollup/plugin-commonjs/node_modules/glob": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+      "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^5.0.1",
+        "once": "^1.3.0"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@rollup/plugin-commonjs/node_modules/minimatch": {
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+      "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
     "node_modules/@rollup/plugin-node-resolve": {
-      "version": "8.4.0",
-      "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-8.4.0.tgz",
-      "integrity": "sha512-LFqKdRLn0ShtQyf6SBYO69bGE1upV6wUhBX0vFOUnLAyzx5cwp8svA0eHUnu8+YU57XOkrMtfG63QOpQx25pHQ==",
+      "version": "15.0.1",
+      "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz",
+      "integrity": "sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg==",
       "dev": true,
       "dependencies": {
-        "@rollup/pluginutils": "^3.1.0",
-        "@types/resolve": "1.17.1",
-        "builtin-modules": "^3.1.0",
-        "deep-freeze": "^0.0.1",
+        "@rollup/pluginutils": "^5.0.1",
+        "@types/resolve": "1.20.2",
         "deepmerge": "^4.2.2",
+        "is-builtin-module": "^3.2.0",
         "is-module": "^1.0.0",
-        "resolve": "^1.17.0"
+        "resolve": "^1.22.1"
       },
       "engines": {
-        "node": ">= 8.0.0"
+        "node": ">=14.0.0"
       },
       "peerDependencies": {
-        "rollup": "^1.20.0||^2.0.0"
+        "rollup": "^2.78.0||^3.0.0"
+      },
+      "peerDependenciesMeta": {
+        "rollup": {
+          "optional": true
+        }
       }
     },
+    "node_modules/@rollup/plugin-node-resolve/node_modules/@rollup/pluginutils": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
+      "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
+      "dev": true,
+      "dependencies": {
+        "@types/estree": "^1.0.0",
+        "estree-walker": "^2.0.2",
+        "picomatch": "^2.3.1"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      },
+      "peerDependencies": {
+        "rollup": "^1.20.0||^2.0.0||^3.0.0"
+      },
+      "peerDependenciesMeta": {
+        "rollup": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@rollup/plugin-node-resolve/node_modules/@types/estree": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
+      "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==",
+      "dev": true
+    },
+    "node_modules/@rollup/plugin-node-resolve/node_modules/estree-walker": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+      "dev": true
+    },
     "node_modules/@rollup/pluginutils": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
@@ -1163,9 +1493,9 @@
       }
     },
     "node_modules/@sinonjs/commons": {
-      "version": "1.8.3",
-      "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
-      "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==",
+      "version": "1.8.6",
+      "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
+      "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==",
       "dev": true,
       "dependencies": {
         "type-detect": "4.0.8"
@@ -1190,31 +1520,31 @@
       }
     },
     "node_modules/@types/babel__core": {
-      "version": "7.1.14",
-      "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz",
-      "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==",
+      "version": "7.20.0",
+      "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz",
+      "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==",
       "dev": true,
       "dependencies": {
-        "@babel/parser": "^7.1.0",
-        "@babel/types": "^7.0.0",
+        "@babel/parser": "^7.20.7",
+        "@babel/types": "^7.20.7",
         "@types/babel__generator": "*",
         "@types/babel__template": "*",
         "@types/babel__traverse": "*"
       }
     },
     "node_modules/@types/babel__generator": {
-      "version": "7.6.2",
-      "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz",
-      "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==",
+      "version": "7.6.4",
+      "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz",
+      "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==",
       "dev": true,
       "dependencies": {
         "@babel/types": "^7.0.0"
       }
     },
     "node_modules/@types/babel__template": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz",
-      "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==",
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
+      "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==",
       "dev": true,
       "dependencies": {
         "@babel/parser": "^7.1.0",
@@ -1222,9 +1552,9 @@
       }
     },
     "node_modules/@types/babel__traverse": {
-      "version": "7.11.1",
-      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.1.tgz",
-      "integrity": "sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==",
+      "version": "7.18.3",
+      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz",
+      "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==",
       "dev": true,
       "dependencies": {
         "@babel/types": "^7.3.0"
@@ -1267,28 +1597,28 @@
       }
     },
     "node_modules/@types/filewriter": {
-      "version": "0.0.28",
-      "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.28.tgz",
-      "integrity": "sha1-wFTor02d11205jq8dviFFocU1LM="
+      "version": "0.0.29",
+      "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.29.tgz",
+      "integrity": "sha512-BsPXH/irW0ht0Ji6iw/jJaK8Lj3FJemon2gvEqHKpCdDCeemHa+rI3WBGq5z7cDMZgoLjY40oninGxqk+8NzNQ=="
     },
     "node_modules/@types/graceful-fs": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
-      "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==",
+      "version": "4.1.6",
+      "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz",
+      "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==",
       "dev": true,
       "dependencies": {
         "@types/node": "*"
       }
     },
     "node_modules/@types/har-format": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.8.tgz",
-      "integrity": "sha512-OP6L9VuZNdskgNN3zFQQ54ceYD8OLq5IbqO4VK91ORLfOm7WdT/CiT/pHEBSQEqCInJ2y3O6iCm/zGtPElpgJQ=="
+      "version": "1.2.10",
+      "resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.10.tgz",
+      "integrity": "sha512-o0J30wqycjF5miWDKYKKzzOU1ZTLuA42HZ4HE7/zqTOc/jTLdQ5NhYWvsRQo45Nfi1KHoRdNhteSI4BAxTF1Pg=="
     },
     "node_modules/@types/istanbul-lib-coverage": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
-      "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==",
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
+      "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
       "dev": true
     },
     "node_modules/@types/istanbul-lib-report": {
@@ -1310,9 +1640,9 @@
       }
     },
     "node_modules/@types/jest": {
-      "version": "26.0.23",
-      "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz",
-      "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==",
+      "version": "26.0.24",
+      "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.24.tgz",
+      "integrity": "sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==",
       "dev": true,
       "dependencies": {
         "jest-diff": "^26.0.0",
@@ -1326,9 +1656,9 @@
       "dev": true
     },
     "node_modules/@types/long": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
-      "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
+      "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="
     },
     "node_modules/@types/minimist": {
       "version": "1.2.2",
@@ -1337,30 +1667,30 @@
       "dev": true
     },
     "node_modules/@types/mithril": {
-      "version": "2.0.11",
-      "resolved": "https://registry.npmjs.org/@types/mithril/-/mithril-2.0.11.tgz",
-      "integrity": "sha512-2tYTImXc7RzWkPpgcbnSKpV46DQI4Bm8CfgmkrIbst8MJlX6d8hdgy2yQCEf5NZYLGNyK4xbzb4rr8VPmk0iXQ=="
+      "version": "2.0.12",
+      "resolved": "https://registry.npmjs.org/@types/mithril/-/mithril-2.0.12.tgz",
+      "integrity": "sha512-vedzt04n3EB7rcnfSLCv3+w3qJLkGWdsNRBKvelTqhSJSfg73Roq9b+rcnn9zeqGYtQAMqNcO6vNBR/w0OzipQ=="
     },
     "node_modules/@types/node": {
-      "version": "14.14.25",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.25.tgz",
-      "integrity": "sha512-EPpXLOVqDvisVxtlbvzfyqSsFeQxltFbluZNRndIb8tr9KiBnYNLzrc1N3pyKUCww2RNrfHDViqDWWE1LCJQtQ=="
+      "version": "14.18.41",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.41.tgz",
+      "integrity": "sha512-2cfHr8AsUjKx6u4Q+d2eqK51z8+HueoumCQGCKVt95y/yGG4uajOuCANSnE20mbLw94h3tMcddIJ8nYkTu2mFw=="
     },
     "node_modules/@types/normalize-package-data": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
-      "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
+      "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
       "dev": true
     },
     "node_modules/@types/pako": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.1.tgz",
-      "integrity": "sha512-GdZbRSJ3Cv5fiwT6I0SQ3ckeN2PWNqxd26W9Z2fCK1tGrrasGy4puvNFtnddqH9UJFMQYXxEuuB7B8UK+LLwSg=="
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.4.tgz",
+      "integrity": "sha512-Z+5bJSm28EXBSUJEgx29ioWeEEHUh6TiMkZHDhLwjc9wVFH+ressbkmX6waUZc5R3Gobn4Qu5llGxaoflZ+yhA=="
     },
     "node_modules/@types/pixelmatch": {
-      "version": "5.2.3",
-      "resolved": "https://registry.npmjs.org/@types/pixelmatch/-/pixelmatch-5.2.3.tgz",
-      "integrity": "sha512-p+nAQVYK/DUx7+s1Xyu9dqAg0gobf7VmJ+iDA4lljg1o4XRgQHr7R2h1NwFt3gdNOZiftxWB11+0TuZqXYf19w==",
+      "version": "5.2.4",
+      "resolved": "https://registry.npmjs.org/@types/pixelmatch/-/pixelmatch-5.2.4.tgz",
+      "integrity": "sha512-HDaSHIAv9kwpMN7zlmwfTv6gax0PiporJOipcrGsVNF3Ba+kryOZc0Pio5pn6NhisgWr7TaajlPEKTbTAypIBQ==",
       "dev": true,
       "dependencies": {
         "@types/node": "*"
@@ -1375,33 +1705,27 @@
       }
     },
     "node_modules/@types/prettier": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz",
-      "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==",
+      "version": "2.7.2",
+      "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz",
+      "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==",
       "dev": true
     },
-    "node_modules/@types/puppeteer": {
-      "version": "5.4.6",
-      "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.6.tgz",
-      "integrity": "sha512-98Kghehs7+/GD9b56qryhqdqVCXUTbetTv3PlvDnmFRTHQH0j9DIp1f7rkAW3BAj4U3yoeSEQnKgdW8bDq0Y0Q==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
     "node_modules/@types/resolve": {
-      "version": "1.17.1",
-      "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
-      "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
+      "version": "1.20.2",
+      "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
+      "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
+      "dev": true
+    },
+    "node_modules/@types/semver": {
+      "version": "7.3.13",
+      "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
+      "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
+      "dev": true
     },
     "node_modules/@types/stack-utils": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz",
-      "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
+      "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
       "dev": true
     },
     "node_modules/@types/uuid": {
@@ -1410,29 +1734,29 @@
       "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw=="
     },
     "node_modules/@types/w3c-web-usb": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.4.tgz",
-      "integrity": "sha512-aaOB3EL5WCWBBOYX7W1MKuzspOM9ZJI9s3iziRVypr1N+QyvIgXzCM4lm1iiOQ1VFzZioUPX9bsa23myCbKK4A=="
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.6.tgz",
+      "integrity": "sha512-cSjhgrr8g4KbPnnijAr/KJDNKa/bBa+ixYkywFRvrhvi9n1WEl7yYbtRyzE6jqNQiSxxJxoAW3STaOQwJHndaw=="
     },
     "node_modules/@types/yargs": {
-      "version": "15.0.13",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz",
-      "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==",
+      "version": "15.0.15",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.15.tgz",
+      "integrity": "sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg==",
       "dev": true,
       "dependencies": {
         "@types/yargs-parser": "*"
       }
     },
     "node_modules/@types/yargs-parser": {
-      "version": "20.2.0",
-      "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz",
-      "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==",
+      "version": "21.0.0",
+      "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
+      "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
       "dev": true
     },
     "node_modules/@types/yauzl": {
-      "version": "2.9.1",
-      "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz",
-      "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==",
+      "version": "2.10.0",
+      "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz",
+      "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==",
       "dev": true,
       "optional": true,
       "dependencies": {
@@ -1440,18 +1764,19 @@
       }
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.25.0.tgz",
-      "integrity": "sha512-icYrFnUzvm+LhW0QeJNKkezBu6tJs9p/53dpPLFH8zoM9w1tfaKzVurkPotEpAqQ8Vf8uaFyL5jHd0Vs6Z0ZQg==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.56.0.tgz",
+      "integrity": "sha512-ZNW37Ccl3oMZkzxrYDUX4o7cnuPgU+YrcaYXzsRtLB16I1FR5SHMqga3zGsaSliZADCWo2v8qHWqAYIj8nWCCg==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "5.25.0",
-        "@typescript-eslint/type-utils": "5.25.0",
-        "@typescript-eslint/utils": "5.25.0",
+        "@eslint-community/regexpp": "^4.4.0",
+        "@typescript-eslint/scope-manager": "5.56.0",
+        "@typescript-eslint/type-utils": "5.56.0",
+        "@typescript-eslint/utils": "5.56.0",
         "debug": "^4.3.4",
-        "functional-red-black-tree": "^1.0.1",
+        "grapheme-splitter": "^1.0.4",
         "ignore": "^5.2.0",
-        "regexpp": "^3.2.0",
+        "natural-compare-lite": "^1.4.0",
         "semver": "^7.3.7",
         "tsutils": "^3.21.0"
       },
@@ -1472,21 +1797,6 @@
         }
       }
     },
-    "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": {
-      "version": "7.3.7",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
-      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
-      "dev": true,
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/@typescript-eslint/eslint-plugin/node_modules/tslib": {
       "version": "1.14.1",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@@ -1509,14 +1819,14 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.25.0.tgz",
-      "integrity": "sha512-r3hwrOWYbNKP1nTcIw/aZoH+8bBnh/Lh1iDHoFpyG4DnCpvEdctrSl6LOo19fZbzypjQMHdajolxs6VpYoChgA==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.56.0.tgz",
+      "integrity": "sha512-sn1OZmBxUsgxMmR8a8U5QM/Wl+tyqlH//jTqCg8daTAmhAk26L2PFhcqPLlYBhYUJMZJK276qLXlHN3a83o2cg==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "5.25.0",
-        "@typescript-eslint/types": "5.25.0",
-        "@typescript-eslint/typescript-estree": "5.25.0",
+        "@typescript-eslint/scope-manager": "5.56.0",
+        "@typescript-eslint/types": "5.56.0",
+        "@typescript-eslint/typescript-estree": "5.56.0",
         "debug": "^4.3.4"
       },
       "engines": {
@@ -1536,13 +1846,13 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.25.0.tgz",
-      "integrity": "sha512-p4SKTFWj+2VpreUZ5xMQsBMDdQ9XdRvODKXN4EksyBjFp2YvQdLkyHqOffakYZPuWJUDNu3jVXtHALDyTv3cww==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.56.0.tgz",
+      "integrity": "sha512-jGYKyt+iBakD0SA5Ww8vFqGpoV2asSjwt60Gl6YcO8ksQ8s2HlUEyHBMSa38bdLopYqGf7EYQMUIGdT/Luw+sw==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "5.25.0",
-        "@typescript-eslint/visitor-keys": "5.25.0"
+        "@typescript-eslint/types": "5.56.0",
+        "@typescript-eslint/visitor-keys": "5.56.0"
       },
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1553,12 +1863,13 @@
       }
     },
     "node_modules/@typescript-eslint/type-utils": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.25.0.tgz",
-      "integrity": "sha512-B6nb3GK3Gv1Rsb2pqalebe/RyQoyG/WDy9yhj8EE0Ikds4Xa8RR28nHz+wlt4tMZk5bnAr0f3oC8TuDAd5CPrw==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.56.0.tgz",
+      "integrity": "sha512-8WxgOgJjWRy6m4xg9KoSHPzBNZeQbGlQOH7l2QEhQID/+YseaFxg5J/DLwWSsi9Axj4e/cCiKx7PVzOq38tY4A==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/utils": "5.25.0",
+        "@typescript-eslint/typescript-estree": "5.56.0",
+        "@typescript-eslint/utils": "5.56.0",
         "debug": "^4.3.4",
         "tsutils": "^3.21.0"
       },
@@ -1600,9 +1911,9 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.25.0.tgz",
-      "integrity": "sha512-7fWqfxr0KNHj75PFqlGX24gWjdV/FDBABXL5dyvBOWHpACGyveok8Uj4ipPX/1fGU63fBkzSIycEje4XsOxUFA==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.56.0.tgz",
+      "integrity": "sha512-JyAzbTJcIyhuUhogmiu+t79AkdnqgPUEsxMTMc/dCZczGMJQh1MK2wgrju++yMN6AWroVAy2jxyPcPr3SWCq5w==",
       "dev": true,
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1613,13 +1924,13 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.25.0.tgz",
-      "integrity": "sha512-MrPODKDych/oWs/71LCnuO7NyR681HuBly2uLnX3r5i4ME7q/yBqC4hW33kmxtuauLTM0OuBOhhkFaxCCOjEEw==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.56.0.tgz",
+      "integrity": "sha512-41CH/GncsLXOJi0jb74SnC7jVPWeVJ0pxQj8bOjH1h2O26jXN3YHKDT1ejkVz5YeTEQPeLCCRY0U2r68tfNOcg==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "5.25.0",
-        "@typescript-eslint/visitor-keys": "5.25.0",
+        "@typescript-eslint/types": "5.56.0",
+        "@typescript-eslint/visitor-keys": "5.56.0",
         "debug": "^4.3.4",
         "globby": "^11.1.0",
         "is-glob": "^4.0.3",
@@ -1639,21 +1950,6 @@
         }
       }
     },
-    "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
-      "version": "7.3.7",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
-      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
-      "dev": true,
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/@typescript-eslint/typescript-estree/node_modules/tslib": {
       "version": "1.14.1",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@@ -1676,17 +1972,19 @@
       }
     },
     "node_modules/@typescript-eslint/utils": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.25.0.tgz",
-      "integrity": "sha512-qNC9bhnz/n9Kba3yI6HQgQdBLuxDoMgdjzdhSInZh6NaDnFpTUlwNGxplUFWfY260Ya0TRPvkg9dd57qxrJI9g==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.56.0.tgz",
+      "integrity": "sha512-XhZDVdLnUJNtbzaJeDSCIYaM+Tgr59gZGbFuELgF7m0IY03PlciidS7UQNKLE0+WpUTn1GlycEr6Ivb/afjbhA==",
       "dev": true,
       "dependencies": {
+        "@eslint-community/eslint-utils": "^4.2.0",
         "@types/json-schema": "^7.0.9",
-        "@typescript-eslint/scope-manager": "5.25.0",
-        "@typescript-eslint/types": "5.25.0",
-        "@typescript-eslint/typescript-estree": "5.25.0",
+        "@types/semver": "^7.3.12",
+        "@typescript-eslint/scope-manager": "5.56.0",
+        "@typescript-eslint/types": "5.56.0",
+        "@typescript-eslint/typescript-estree": "5.56.0",
         "eslint-scope": "^5.1.1",
-        "eslint-utils": "^3.0.0"
+        "semver": "^7.3.7"
       },
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1699,35 +1997,13 @@
         "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
       }
     },
-    "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
-      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
-      "dev": true,
-      "dependencies": {
-        "esrecurse": "^4.3.0",
-        "estraverse": "^4.1.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/utils/node_modules/estraverse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
-      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
-      "dev": true,
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.25.0.tgz",
-      "integrity": "sha512-yd26vFgMsC4h2dgX4+LR+GeicSKIfUvZREFLf3DDjZPtqgLx5AJZr6TetMNwFP9hcKreTTeztQYBTNbNoOycwA==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.56.0.tgz",
+      "integrity": "sha512-1mFdED7u5bZpX6Xxf5N9U2c18sb+8EvU3tyOIj6LQZ5OOvnmj8BVeNNP603OFPm5KkS1a7IvCIcwrdHXaEMG/Q==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "5.25.0",
+        "@typescript-eslint/types": "5.56.0",
         "eslint-visitor-keys": "^3.3.0"
       },
       "engines": {
@@ -1739,9 +2015,9 @@
       }
     },
     "node_modules/abab": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
-      "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==",
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
+      "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==",
       "dev": true
     },
     "node_modules/abbrev": {
@@ -1751,9 +2027,9 @@
       "dev": true
     },
     "node_modules/acorn": {
-      "version": "8.7.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
-      "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+      "version": "8.8.2",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
+      "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
       "dev": true,
       "bin": {
         "acorn": "bin/acorn"
@@ -1815,13 +2091,13 @@
       }
     },
     "node_modules/agentkeepalive": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz",
-      "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==",
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz",
+      "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==",
       "dev": true,
       "dependencies": {
         "debug": "^4.1.0",
-        "depd": "^1.1.2",
+        "depd": "^2.0.0",
         "humanize-ms": "^1.2.1"
       },
       "engines": {
@@ -1909,9 +2185,9 @@
       }
     },
     "node_modules/anymatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
-      "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
       "dev": true,
       "dependencies": {
         "normalize-path": "^3.0.0",
@@ -1927,46 +2203,16 @@
       "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
       "dev": true
     },
-    "node_modules/are-we-there-yet": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
-      "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
-      "dev": true,
-      "dependencies": {
-        "delegates": "^1.0.0",
-        "readable-stream": "^3.6.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/are-we-there-yet/node_modules/readable-stream": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
     "node_modules/argparse": {
-      "version": "1.0.10",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
-      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
-      "dev": true,
-      "dependencies": {
-        "sprintf-js": "~1.0.2"
-      }
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+      "dev": true
     },
     "node_modules/arr-diff": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
-      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -1984,17 +2230,12 @@
     "node_modules/arr-union": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
-      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
-    "node_modules/array-filter": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz",
-      "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM="
-    },
     "node_modules/array-union": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@@ -2007,7 +2248,7 @@
     "node_modules/array-unique": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
-      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+      "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -2016,34 +2257,16 @@
     "node_modules/arrify": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
-      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
-    "node_modules/asn1": {
-      "version": "0.2.6",
-      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
-      "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
-      "dev": true,
-      "dependencies": {
-        "safer-buffer": "~2.1.0"
-      }
-    },
-    "node_modules/assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
     "node_modules/assign-symbols": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
-      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -2052,7 +2275,7 @@
     "node_modules/async-foreach": {
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
-      "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
+      "integrity": "sha512-VUeSMD8nEGBWaZK4lizI1sf3yEC7pnAQ/mrI7pC2fBz2s/tq5jWWEngTwaf0Gruu/OoXRGLGg1XFqpYBiGTYJA==",
       "dev": true,
       "engines": {
         "node": "*"
@@ -2061,7 +2284,7 @@
     "node_modules/asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
       "dev": true
     },
     "node_modules/atob": {
@@ -2077,12 +2300,9 @@
       }
     },
     "node_modules/available-typed-arrays": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz",
-      "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==",
-      "dependencies": {
-        "array-filter": "^1.0.0"
-      },
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+      "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
       "engines": {
         "node": ">= 0.4"
       },
@@ -2090,21 +2310,6 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/aws-sign2": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
-      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/aws4": {
-      "version": "1.11.0",
-      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
-      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
-      "dev": true
-    },
     "node_modules/babel-jest": {
       "version": "26.6.3",
       "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz",
@@ -2128,21 +2333,46 @@
       }
     },
     "node_modules/babel-plugin-istanbul": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz",
-      "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==",
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
+      "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0",
         "@istanbuljs/load-nyc-config": "^1.0.0",
         "@istanbuljs/schema": "^0.1.2",
-        "istanbul-lib-instrument": "^4.0.0",
+        "istanbul-lib-instrument": "^5.0.4",
         "test-exclude": "^6.0.0"
       },
       "engines": {
         "node": ">=8"
       }
     },
+    "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
+      "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/core": "^7.12.3",
+        "@babel/parser": "^7.14.7",
+        "@istanbuljs/schema": "^0.1.2",
+        "istanbul-lib-coverage": "^3.2.0",
+        "semver": "^6.3.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/babel-plugin-istanbul/node_modules/semver": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
     "node_modules/babel-plugin-jest-hoist": {
       "version": "26.6.2",
       "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz",
@@ -2198,9 +2428,9 @@
       }
     },
     "node_modules/balanced-match": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
     },
     "node_modules/base": {
       "version": "0.11.2",
@@ -2223,7 +2453,7 @@
     "node_modules/base/node_modules/define-property": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+      "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
       "dev": true,
       "dependencies": {
         "is-descriptor": "^1.0.0"
@@ -2232,44 +2462,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/base/node_modules/is-accessor-descriptor": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
-      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/base/node_modules/is-data-descriptor": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
-      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/base/node_modules/is-descriptor": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
-      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
-      "dev": true,
-      "dependencies": {
-        "is-accessor-descriptor": "^1.0.0",
-        "is-data-descriptor": "^1.0.0",
-        "kind-of": "^6.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/base64-js": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -2290,15 +2482,6 @@
         }
       ]
     },
-    "node_modules/bcrypt-pbkdf": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
-      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
-      "dev": true,
-      "dependencies": {
-        "tweetnacl": "^0.14.3"
-      }
-    },
     "node_modules/bl": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
@@ -2310,20 +2493,6 @@
         "readable-stream": "^3.4.0"
       }
     },
-    "node_modules/bl/node_modules/readable-stream": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
     "node_modules/brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -2352,26 +2521,31 @@
       "dev": true
     },
     "node_modules/browserslist": {
-      "version": "4.16.6",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
-      "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
+      "version": "4.21.5",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
+      "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==",
       "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        }
+      ],
       "dependencies": {
-        "caniuse-lite": "^1.0.30001219",
-        "colorette": "^1.2.2",
-        "electron-to-chromium": "^1.3.723",
-        "escalade": "^3.1.1",
-        "node-releases": "^1.1.71"
+        "caniuse-lite": "^1.0.30001449",
+        "electron-to-chromium": "^1.4.284",
+        "node-releases": "^2.0.8",
+        "update-browserslist-db": "^1.0.10"
       },
       "bin": {
         "browserslist": "cli.js"
       },
       "engines": {
         "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/browserslist"
       }
     },
     "node_modules/bser": {
@@ -2410,22 +2584,22 @@
     "node_modules/buffer-crc32": {
       "version": "0.2.13",
       "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
-      "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+      "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
       "dev": true,
       "engines": {
         "node": "*"
       }
     },
     "node_modules/buffer-from": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
-      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
       "dev": true
     },
     "node_modules/builtin-modules": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz",
-      "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==",
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
+      "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
       "dev": true,
       "engines": {
         "node": ">=6"
@@ -2463,27 +2637,24 @@
         "node": ">= 10"
       }
     },
-    "node_modules/cacache/node_modules/chownr": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
-      "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+    "node_modules/cacache/node_modules/lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
       "dev": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/cacache/node_modules/mkdirp": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
-      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
-      "dev": true,
-      "bin": {
-        "mkdirp": "bin/cmd.js"
+      "dependencies": {
+        "yallist": "^4.0.0"
       },
       "engines": {
         "node": ">=10"
       }
     },
+    "node_modules/cacache/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true
+    },
     "node_modules/cache-base": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
@@ -2552,14 +2723,20 @@
       }
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30001233",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001233.tgz",
-      "integrity": "sha512-BmkbxLfStqiPA7IEzQpIk0UFZFf3A4E6fzjPJ6OR+bFC2L8ES9J8zGA/asoi47p8XDVkev+WJo2I2Nc8c/34Yg==",
+      "version": "1.0.30001470",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001470.tgz",
+      "integrity": "sha512-065uNwY6QtHCBOExzbV6m236DDhYCCtPmQUCoQtwkVqzud8v5QPidoMr6CoMkC2nfp6nksjttqWQRRh75LqUmA==",
       "dev": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/browserslist"
-      }
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+        }
+      ]
     },
     "node_modules/capture-exit": {
       "version": "2.0.0",
@@ -2573,12 +2750,6 @@
         "node": "6.* || 8.* || >= 10.*"
       }
     },
-    "node_modules/caseless": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
-      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
-      "dev": true
-    },
     "node_modules/chalk": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -2605,10 +2776,13 @@
       }
     },
     "node_modules/chownr": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
-      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
-      "dev": true
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+      "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
     },
     "node_modules/ci-info": {
       "version": "2.0.0",
@@ -2640,7 +2814,7 @@
     "node_modules/class-utils/node_modules/define-property": {
       "version": "0.2.5",
       "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
       "dev": true,
       "dependencies": {
         "is-descriptor": "^0.1.0"
@@ -2649,6 +2823,77 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/class-utils/node_modules/is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/class-utils/node_modules/is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/class-utils/node_modules/is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/class-utils/node_modules/kind-of": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+      "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/clean-stack": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
@@ -2672,7 +2917,7 @@
     "node_modules/co": {
       "version": "4.6.0",
       "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
-      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+      "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
       "dev": true,
       "engines": {
         "iojs": ">= 1.0.0",
@@ -2688,7 +2933,7 @@
     "node_modules/collection-visit": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
-      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==",
       "dev": true,
       "dependencies": {
         "map-visit": "^1.0.0",
@@ -2723,12 +2968,6 @@
         "color-support": "bin.js"
       }
     },
-    "node_modules/colorette": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
-      "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
-      "dev": true
-    },
     "node_modules/combined-stream": {
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -2744,7 +2983,7 @@
     "node_modules/commondir": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
-      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
       "dev": true
     },
     "node_modules/component-emitter": {
@@ -2756,33 +2995,24 @@
     "node_modules/concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
     },
     "node_modules/console-control-strings": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
-      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+      "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
       "dev": true
     },
     "node_modules/convert-source-map": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
-      "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "~5.1.1"
-      }
-    },
-    "node_modules/convert-source-map/node_modules/safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+      "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
       "dev": true
     },
     "node_modules/copy-descriptor": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
-      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -2791,9 +3021,27 @@
     "node_modules/core-util-is": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
-      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
       "dev": true
     },
+    "node_modules/cosmiconfig": {
+      "version": "8.1.3",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz",
+      "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==",
+      "dev": true,
+      "dependencies": {
+        "import-fresh": "^3.2.1",
+        "js-yaml": "^4.1.0",
+        "parse-json": "^5.0.0",
+        "path-type": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/d-fischer"
+      }
+    },
     "node_modules/cross-fetch": {
       "version": "3.1.5",
       "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
@@ -2804,28 +3052,17 @@
       }
     },
     "node_modules/cross-spawn": {
-      "version": "6.0.5",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
-      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
       "dev": true,
       "dependencies": {
-        "nice-try": "^1.0.4",
-        "path-key": "^2.0.1",
-        "semver": "^5.5.0",
-        "shebang-command": "^1.2.0",
-        "which": "^1.2.9"
+        "path-key": "^3.1.0",
+        "shebang-command": "^2.0.0",
+        "which": "^2.0.1"
       },
       "engines": {
-        "node": ">=4.8"
-      }
-    },
-    "node_modules/cross-spawn/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
+        "node": ">= 8"
       }
     },
     "node_modules/cssom": {
@@ -2856,18 +3093,6 @@
       "resolved": "src/base/utils",
       "link": true
     },
-    "node_modules/dashdash": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
-      "dev": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
     "node_modules/data-urls": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz",
@@ -2882,6 +3107,41 @@
         "node": ">=10"
       }
     },
+    "node_modules/data-urls/node_modules/tr46": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
+      "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
+      "dev": true,
+      "dependencies": {
+        "punycode": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/data-urls/node_modules/webidl-conversions": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
+      "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
+      "dev": true,
+      "engines": {
+        "node": ">=10.4"
+      }
+    },
+    "node_modules/data-urls/node_modules/whatwg-url": {
+      "version": "8.7.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz",
+      "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==",
+      "dev": true,
+      "dependencies": {
+        "lodash": "^4.7.0",
+        "tr46": "^2.1.0",
+        "webidl-conversions": "^6.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/debug": {
       "version": "4.3.4",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -2902,16 +3162,16 @@
     "node_modules/decamelize": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
-      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
     "node_modules/decamelize-keys": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz",
-      "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=",
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
+      "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
       "dev": true,
       "dependencies": {
         "decamelize": "^1.1.0",
@@ -2919,64 +3179,50 @@
       },
       "engines": {
         "node": ">=0.10.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/decamelize-keys/node_modules/map-obj": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
-      "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+      "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
     "node_modules/decimal.js": {
-      "version": "10.2.1",
-      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz",
-      "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==",
+      "version": "10.4.3",
+      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
+      "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==",
       "dev": true
     },
     "node_modules/decode-uri-component": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
-      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
+      "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
       "dev": true,
       "engines": {
         "node": ">=0.10"
       }
     },
-    "node_modules/deep-freeze": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/deep-freeze/-/deep-freeze-0.0.1.tgz",
-      "integrity": "sha1-OgsABd4YZygZ39OM0x+RF5yJPoQ=",
-      "dev": true
-    },
     "node_modules/deep-is": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
-      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
       "dev": true
     },
     "node_modules/deepmerge": {
-      "version": "4.2.2",
-      "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
-      "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+      "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
-    "node_modules/define-properties": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
-      "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
-      "dependencies": {
-        "object-keys": "^1.0.12"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
     "node_modules/define-property": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
@@ -2990,48 +3236,10 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/define-property/node_modules/is-accessor-descriptor": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
-      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/define-property/node_modules/is-data-descriptor": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
-      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/define-property/node_modules/is-descriptor": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
-      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
-      "dev": true,
-      "dependencies": {
-        "is-accessor-descriptor": "^1.0.0",
-        "is-data-descriptor": "^1.0.0",
-        "kind-of": "^6.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/delayed-stream": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
       "dev": true,
       "engines": {
         "node": ">=0.4.0"
@@ -3040,16 +3248,16 @@
     "node_modules/delegates": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
-      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+      "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
       "dev": true
     },
     "node_modules/depd": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
-      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
       "dev": true,
       "engines": {
-        "node": ">= 0.6"
+        "node": ">= 0.8"
       }
     },
     "node_modules/detect-newline": {
@@ -3126,20 +3334,10 @@
         "node": ">=8"
       }
     },
-    "node_modules/ecc-jsbn": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
-      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
-      "dev": true,
-      "dependencies": {
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.1.0"
-      }
-    },
     "node_modules/electron-to-chromium": {
-      "version": "1.3.747",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.747.tgz",
-      "integrity": "sha512-+K1vnBc08GNYxCWwdRe9o3Ml30DhsNyK/qIl/NE1Dic+qCy9ZREcqGNiV4jiLiAdALK1DUG3pakJHGkJUd9QQw==",
+      "version": "1.4.340",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.340.tgz",
+      "integrity": "sha512-zx8hqumOqltKsv/MF50yvdAlPF9S/4PXbyfzJS6ZGhbddGkRegdwImmfSVqCkEziYzrIGZ/TlrzBND4FysfkDg==",
       "dev": true
     },
     "node_modules/emittery": {
@@ -3170,19 +3368,6 @@
         "iconv-lite": "^0.6.2"
       }
     },
-    "node_modules/encoding/node_modules/iconv-lite": {
-      "version": "0.6.3",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
-      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "safer-buffer": ">= 2.1.2 < 3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/end-of-stream": {
       "version": "1.4.4",
       "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -3216,53 +3401,10 @@
         "is-arrayish": "^0.2.1"
       }
     },
-    "node_modules/es-abstract": {
-      "version": "1.18.0-next.2",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz",
-      "integrity": "sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==",
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "es-to-primitive": "^1.2.1",
-        "function-bind": "^1.1.1",
-        "get-intrinsic": "^1.0.2",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.1",
-        "is-callable": "^1.2.2",
-        "is-negative-zero": "^2.0.1",
-        "is-regex": "^1.1.1",
-        "object-inspect": "^1.9.0",
-        "object-keys": "^1.1.1",
-        "object.assign": "^4.1.2",
-        "string.prototype.trimend": "^1.0.3",
-        "string.prototype.trimstart": "^1.0.3"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/es-to-primitive": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
-      "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
-      "dependencies": {
-        "is-callable": "^1.1.4",
-        "is-date-object": "^1.0.1",
-        "is-symbol": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/esbuild": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.12.tgz",
-      "integrity": "sha512-PcT+/wyDqJQsRVhaE9uX/Oq4XLrFh0ce/bs2TJh4CSaw9xuvI+xFrH2nAYOADbhQjUgAhNWC5LKoUsakm4dxng==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.18.tgz",
+      "integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==",
       "hasInstallScript": true,
       "bin": {
         "esbuild": "bin/esbuild"
@@ -3271,34 +3413,34 @@
         "node": ">=12"
       },
       "optionalDependencies": {
-        "@esbuild/android-arm": "0.15.12",
-        "@esbuild/linux-loong64": "0.15.12",
-        "esbuild-android-64": "0.15.12",
-        "esbuild-android-arm64": "0.15.12",
-        "esbuild-darwin-64": "0.15.12",
-        "esbuild-darwin-arm64": "0.15.12",
-        "esbuild-freebsd-64": "0.15.12",
-        "esbuild-freebsd-arm64": "0.15.12",
-        "esbuild-linux-32": "0.15.12",
-        "esbuild-linux-64": "0.15.12",
-        "esbuild-linux-arm": "0.15.12",
-        "esbuild-linux-arm64": "0.15.12",
-        "esbuild-linux-mips64le": "0.15.12",
-        "esbuild-linux-ppc64le": "0.15.12",
-        "esbuild-linux-riscv64": "0.15.12",
-        "esbuild-linux-s390x": "0.15.12",
-        "esbuild-netbsd-64": "0.15.12",
-        "esbuild-openbsd-64": "0.15.12",
-        "esbuild-sunos-64": "0.15.12",
-        "esbuild-windows-32": "0.15.12",
-        "esbuild-windows-64": "0.15.12",
-        "esbuild-windows-arm64": "0.15.12"
+        "@esbuild/android-arm": "0.15.18",
+        "@esbuild/linux-loong64": "0.15.18",
+        "esbuild-android-64": "0.15.18",
+        "esbuild-android-arm64": "0.15.18",
+        "esbuild-darwin-64": "0.15.18",
+        "esbuild-darwin-arm64": "0.15.18",
+        "esbuild-freebsd-64": "0.15.18",
+        "esbuild-freebsd-arm64": "0.15.18",
+        "esbuild-linux-32": "0.15.18",
+        "esbuild-linux-64": "0.15.18",
+        "esbuild-linux-arm": "0.15.18",
+        "esbuild-linux-arm64": "0.15.18",
+        "esbuild-linux-mips64le": "0.15.18",
+        "esbuild-linux-ppc64le": "0.15.18",
+        "esbuild-linux-riscv64": "0.15.18",
+        "esbuild-linux-s390x": "0.15.18",
+        "esbuild-netbsd-64": "0.15.18",
+        "esbuild-openbsd-64": "0.15.18",
+        "esbuild-sunos-64": "0.15.18",
+        "esbuild-windows-32": "0.15.18",
+        "esbuild-windows-64": "0.15.18",
+        "esbuild-windows-arm64": "0.15.18"
       }
     },
     "node_modules/esbuild-android-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.12.tgz",
-      "integrity": "sha512-MJKXwvPY9g0rGps0+U65HlTsM1wUs9lbjt5CU19RESqycGFDRijMDQsh68MtbzkqWSRdEtiKS1mtPzKneaAI0Q==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz",
+      "integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==",
       "cpu": [
         "x64"
       ],
@@ -3311,9 +3453,9 @@
       }
     },
     "node_modules/esbuild-android-arm64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.12.tgz",
-      "integrity": "sha512-Hc9SEcZbIMhhLcvhr1DH+lrrec9SFTiRzfJ7EGSBZiiw994gfkVV6vG0sLWqQQ6DD7V4+OggB+Hn0IRUdDUqvA==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz",
+      "integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==",
       "cpu": [
         "arm64"
       ],
@@ -3326,9 +3468,9 @@
       }
     },
     "node_modules/esbuild-darwin-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.12.tgz",
-      "integrity": "sha512-qkmqrTVYPFiePt5qFjP8w/S+GIUMbt6k8qmiPraECUWfPptaPJUGkCKrWEfYFRWB7bY23FV95rhvPyh/KARP8Q==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz",
+      "integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==",
       "cpu": [
         "x64"
       ],
@@ -3341,9 +3483,9 @@
       }
     },
     "node_modules/esbuild-darwin-arm64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.12.tgz",
-      "integrity": "sha512-z4zPX02tQ41kcXMyN3c/GfZpIjKoI/BzHrdKUwhC/Ki5BAhWv59A9M8H+iqaRbwpzYrYidTybBwiZAIWCLJAkw==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz",
+      "integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==",
       "cpu": [
         "arm64"
       ],
@@ -3356,9 +3498,9 @@
       }
     },
     "node_modules/esbuild-freebsd-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.12.tgz",
-      "integrity": "sha512-XFL7gKMCKXLDiAiBjhLG0XECliXaRLTZh6hsyzqUqPUf/PY4C6EJDTKIeqqPKXaVJ8+fzNek88285krSz1QECw==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz",
+      "integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==",
       "cpu": [
         "x64"
       ],
@@ -3371,9 +3513,9 @@
       }
     },
     "node_modules/esbuild-freebsd-arm64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.12.tgz",
-      "integrity": "sha512-jwEIu5UCUk6TjiG1X+KQnCGISI+ILnXzIzt9yDVrhjug2fkYzlLbl0K43q96Q3KB66v6N1UFF0r5Ks4Xo7i72g==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz",
+      "integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==",
       "cpu": [
         "arm64"
       ],
@@ -3386,9 +3528,9 @@
       }
     },
     "node_modules/esbuild-linux-32": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.12.tgz",
-      "integrity": "sha512-uSQuSEyF1kVzGzuIr4XM+v7TPKxHjBnLcwv2yPyCz8riV8VUCnO/C4BF3w5dHiVpCd5Z1cebBtZJNlC4anWpwA==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz",
+      "integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==",
       "cpu": [
         "ia32"
       ],
@@ -3401,9 +3543,9 @@
       }
     },
     "node_modules/esbuild-linux-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.12.tgz",
-      "integrity": "sha512-QcgCKb7zfJxqT9o5z9ZUeGH1k8N6iX1Y7VNsEi5F9+HzN1OIx7ESxtQXDN9jbeUSPiRH1n9cw6gFT3H4qbdvcA==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz",
+      "integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==",
       "cpu": [
         "x64"
       ],
@@ -3416,9 +3558,9 @@
       }
     },
     "node_modules/esbuild-linux-arm": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.12.tgz",
-      "integrity": "sha512-Wf7T0aNylGcLu7hBnzMvsTfEXdEdJY/hY3u36Vla21aY66xR0MS5I1Hw8nVquXjTN0A6fk/vnr32tkC/C2lb0A==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz",
+      "integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==",
       "cpu": [
         "arm"
       ],
@@ -3431,9 +3573,9 @@
       }
     },
     "node_modules/esbuild-linux-arm64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.12.tgz",
-      "integrity": "sha512-HtNq5xm8fUpZKwWKS2/YGwSfTF+339L4aIA8yphNKYJckd5hVdhfdl6GM2P3HwLSCORS++++7++//ApEwXEuAQ==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz",
+      "integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==",
       "cpu": [
         "arm64"
       ],
@@ -3446,9 +3588,9 @@
       }
     },
     "node_modules/esbuild-linux-mips64le": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.12.tgz",
-      "integrity": "sha512-Qol3+AvivngUZkTVFgLpb0H6DT+N5/zM3V1YgTkryPYFeUvuT5JFNDR3ZiS6LxhyF8EE+fiNtzwlPqMDqVcc6A==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz",
+      "integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==",
       "cpu": [
         "mips64el"
       ],
@@ -3461,9 +3603,9 @@
       }
     },
     "node_modules/esbuild-linux-ppc64le": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.12.tgz",
-      "integrity": "sha512-4D8qUCo+CFKaR0cGXtGyVsOI7w7k93Qxb3KFXWr75An0DHamYzq8lt7TNZKoOq/Gh8c40/aKaxvcZnTgQ0TJNg==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz",
+      "integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==",
       "cpu": [
         "ppc64"
       ],
@@ -3476,9 +3618,9 @@
       }
     },
     "node_modules/esbuild-linux-riscv64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.12.tgz",
-      "integrity": "sha512-G9w6NcuuCI6TUUxe6ka0enjZHDnSVK8bO+1qDhMOCtl7Tr78CcZilJj8SGLN00zO5iIlwNRZKHjdMpfFgNn1VA==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz",
+      "integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==",
       "cpu": [
         "riscv64"
       ],
@@ -3491,9 +3633,9 @@
       }
     },
     "node_modules/esbuild-linux-s390x": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.12.tgz",
-      "integrity": "sha512-Lt6BDnuXbXeqSlVuuUM5z18GkJAZf3ERskGZbAWjrQoi9xbEIsj/hEzVnSAFLtkfLuy2DE4RwTcX02tZFunXww==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz",
+      "integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==",
       "cpu": [
         "s390x"
       ],
@@ -3506,9 +3648,9 @@
       }
     },
     "node_modules/esbuild-netbsd-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.12.tgz",
-      "integrity": "sha512-jlUxCiHO1dsqoURZDQts+HK100o0hXfi4t54MNRMCAqKGAV33JCVvMplLAa2FwviSojT/5ZG5HUfG3gstwAG8w==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz",
+      "integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==",
       "cpu": [
         "x64"
       ],
@@ -3521,9 +3663,9 @@
       }
     },
     "node_modules/esbuild-openbsd-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.12.tgz",
-      "integrity": "sha512-1o1uAfRTMIWNOmpf8v7iudND0L6zRBYSH45sofCZywrcf7NcZA+c7aFsS1YryU+yN7aRppTqdUK1PgbZVaB1Dw==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz",
+      "integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==",
       "cpu": [
         "x64"
       ],
@@ -3536,9 +3678,9 @@
       }
     },
     "node_modules/esbuild-sunos-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.12.tgz",
-      "integrity": "sha512-nkl251DpoWoBO9Eq9aFdoIt2yYmp4I3kvQjba3jFKlMXuqQ9A4q+JaqdkCouG3DHgAGnzshzaGu6xofGcXyPXg==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz",
+      "integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==",
       "cpu": [
         "x64"
       ],
@@ -3551,9 +3693,9 @@
       }
     },
     "node_modules/esbuild-windows-32": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.12.tgz",
-      "integrity": "sha512-WlGeBZHgPC00O08luIp5B2SP4cNCp/PcS+3Pcg31kdcJPopHxLkdCXtadLU9J82LCfw4TVls21A6lilQ9mzHrw==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz",
+      "integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==",
       "cpu": [
         "ia32"
       ],
@@ -3566,9 +3708,9 @@
       }
     },
     "node_modules/esbuild-windows-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.12.tgz",
-      "integrity": "sha512-VActO3WnWZSN//xjSfbiGOSyC+wkZtI8I4KlgrTo5oHJM6z3MZZBCuFaZHd8hzf/W9KPhF0lY8OqlmWC9HO5AA==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz",
+      "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==",
       "cpu": [
         "x64"
       ],
@@ -3581,9 +3723,9 @@
       }
     },
     "node_modules/esbuild-windows-arm64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.12.tgz",
-      "integrity": "sha512-Of3MIacva1OK/m4zCNIvBfz8VVROBmQT+gRX6pFTLPngFYcj6TFH/12VveAqq1k9VB2l28EoVMNMUCcmsfwyuA==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz",
+      "integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==",
       "cpu": [
         "arm64"
       ],
@@ -3605,12 +3747,15 @@
       }
     },
     "node_modules/escape-string-regexp": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
       "dev": true,
       "engines": {
-        "node": ">=0.8.0"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/escodegen": {
@@ -3635,14 +3780,79 @@
         "source-map": "~0.6.1"
       }
     },
-    "node_modules/eslint": {
-      "version": "8.15.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz",
-      "integrity": "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==",
+    "node_modules/escodegen/node_modules/estraverse": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/escodegen/node_modules/levn": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+      "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==",
       "dev": true,
       "dependencies": {
-        "@eslint/eslintrc": "^1.2.3",
-        "@humanwhocodes/config-array": "^0.9.2",
+        "prelude-ls": "~1.1.2",
+        "type-check": "~0.3.2"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/escodegen/node_modules/optionator": {
+      "version": "0.8.3",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+      "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+      "dev": true,
+      "dependencies": {
+        "deep-is": "~0.1.3",
+        "fast-levenshtein": "~2.0.6",
+        "levn": "~0.3.0",
+        "prelude-ls": "~1.1.2",
+        "type-check": "~0.3.2",
+        "word-wrap": "~1.2.3"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/escodegen/node_modules/prelude-ls": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+      "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/escodegen/node_modules/type-check": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+      "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
+      "dev": true,
+      "dependencies": {
+        "prelude-ls": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/eslint": {
+      "version": "8.36.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz",
+      "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==",
+      "dev": true,
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.2.0",
+        "@eslint-community/regexpp": "^4.4.0",
+        "@eslint/eslintrc": "^2.0.1",
+        "@eslint/js": "8.36.0",
+        "@humanwhocodes/config-array": "^0.11.8",
+        "@humanwhocodes/module-importer": "^1.0.1",
+        "@nodelib/fs.walk": "^1.2.8",
         "ajv": "^6.10.0",
         "chalk": "^4.0.0",
         "cross-spawn": "^7.0.2",
@@ -3650,20 +3860,22 @@
         "doctrine": "^3.0.0",
         "escape-string-regexp": "^4.0.0",
         "eslint-scope": "^7.1.1",
-        "eslint-utils": "^3.0.0",
         "eslint-visitor-keys": "^3.3.0",
-        "espree": "^9.3.2",
-        "esquery": "^1.4.0",
+        "espree": "^9.5.0",
+        "esquery": "^1.4.2",
         "esutils": "^2.0.2",
         "fast-deep-equal": "^3.1.3",
         "file-entry-cache": "^6.0.1",
-        "functional-red-black-tree": "^1.0.1",
-        "glob-parent": "^6.0.1",
-        "globals": "^13.6.0",
+        "find-up": "^5.0.0",
+        "glob-parent": "^6.0.2",
+        "globals": "^13.19.0",
+        "grapheme-splitter": "^1.0.4",
         "ignore": "^5.2.0",
         "import-fresh": "^3.0.0",
         "imurmurhash": "^0.1.4",
         "is-glob": "^4.0.0",
+        "is-path-inside": "^3.0.3",
+        "js-sdsl": "^4.1.4",
         "js-yaml": "^4.1.0",
         "json-stable-stringify-without-jsonify": "^1.0.1",
         "levn": "^0.4.1",
@@ -3671,11 +3883,9 @@
         "minimatch": "^3.1.2",
         "natural-compare": "^1.4.0",
         "optionator": "^0.9.1",
-        "regexpp": "^3.2.0",
         "strip-ansi": "^6.0.1",
         "strip-json-comments": "^3.1.0",
-        "text-table": "^0.2.0",
-        "v8-compile-cache": "^2.0.3"
+        "text-table": "^0.2.0"
       },
       "bin": {
         "eslint": "bin/eslint.js"
@@ -3700,6 +3910,28 @@
       }
     },
     "node_modules/eslint-scope": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+      "dev": true,
+      "dependencies": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^4.1.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/eslint-visitor-keys": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
+      "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      }
+    },
+    "node_modules/eslint/node_modules/eslint-scope": {
       "version": "7.1.1",
       "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
       "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
@@ -3712,233 +3944,30 @@
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
       }
     },
-    "node_modules/eslint-utils": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
-      "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
-      "dev": true,
-      "dependencies": {
-        "eslint-visitor-keys": "^2.0.0"
-      },
-      "engines": {
-        "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/mysticatea"
-      },
-      "peerDependencies": {
-        "eslint": ">=5"
-      }
-    },
-    "node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-      "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+    "node_modules/eslint/node_modules/estraverse": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
       "dev": true,
       "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/eslint-visitor-keys": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
-      "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
-      "dev": true,
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      }
-    },
-    "node_modules/eslint/node_modules/argparse": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
-      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
-      "dev": true
-    },
-    "node_modules/eslint/node_modules/cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
-      "dev": true,
-      "dependencies": {
-        "path-key": "^3.1.0",
-        "shebang-command": "^2.0.0",
-        "which": "^2.0.1"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/eslint/node_modules/escape-string-regexp": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/eslint/node_modules/globals": {
-      "version": "13.15.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz",
-      "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==",
-      "dev": true,
-      "dependencies": {
-        "type-fest": "^0.20.2"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/eslint/node_modules/js-yaml": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
-      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
-      "dev": true,
-      "dependencies": {
-        "argparse": "^2.0.1"
-      },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
-      }
-    },
-    "node_modules/eslint/node_modules/levn": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
-      "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
-      "dev": true,
-      "dependencies": {
-        "prelude-ls": "^1.2.1",
-        "type-check": "~0.4.0"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/eslint/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/eslint/node_modules/optionator": {
-      "version": "0.9.1",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
-      "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
-      "dev": true,
-      "dependencies": {
-        "deep-is": "^0.1.3",
-        "fast-levenshtein": "^2.0.6",
-        "levn": "^0.4.1",
-        "prelude-ls": "^1.2.1",
-        "type-check": "^0.4.0",
-        "word-wrap": "^1.2.3"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/eslint/node_modules/path-key": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/eslint/node_modules/prelude-ls": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
-      "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/eslint/node_modules/shebang-command": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
-      "dev": true,
-      "dependencies": {
-        "shebang-regex": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/eslint/node_modules/shebang-regex": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/eslint/node_modules/type-check": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
-      "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
-      "dev": true,
-      "dependencies": {
-        "prelude-ls": "^1.2.1"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/eslint/node_modules/type-fest": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
-      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/eslint/node_modules/which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-      "dev": true,
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "node-which": "bin/node-which"
-      },
-      "engines": {
-        "node": ">= 8"
+        "node": ">=4.0"
       }
     },
     "node_modules/espree": {
-      "version": "9.3.2",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
-      "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==",
+      "version": "9.5.0",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz",
+      "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==",
       "dev": true,
       "dependencies": {
-        "acorn": "^8.7.1",
+        "acorn": "^8.8.0",
         "acorn-jsx": "^5.3.2",
         "eslint-visitor-keys": "^3.3.0"
       },
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
     "node_modules/esprima": {
@@ -3955,9 +3984,9 @@
       }
     },
     "node_modules/esquery": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
-      "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+      "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
       "dev": true,
       "dependencies": {
         "estraverse": "^5.1.0"
@@ -3966,6 +3995,15 @@
         "node": ">=0.10"
       }
     },
+    "node_modules/esquery/node_modules/estraverse": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
     "node_modules/esrecurse": {
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
@@ -3978,10 +4016,19 @@
         "node": ">=4.0"
       }
     },
+    "node_modules/esrecurse/node_modules/estraverse": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
     "node_modules/estraverse": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
-      "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
       "dev": true,
       "engines": {
         "node": ">=4.0"
@@ -4003,9 +4050,9 @@
       }
     },
     "node_modules/events": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz",
-      "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==",
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+      "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
       "engines": {
         "node": ">=0.8.x"
       }
@@ -4017,27 +4064,32 @@
       "dev": true
     },
     "node_modules/execa": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
-      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
+      "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
       "dev": true,
       "dependencies": {
-        "cross-spawn": "^6.0.0",
-        "get-stream": "^4.0.0",
-        "is-stream": "^1.1.0",
-        "npm-run-path": "^2.0.0",
-        "p-finally": "^1.0.0",
-        "signal-exit": "^3.0.0",
-        "strip-eof": "^1.0.0"
+        "cross-spawn": "^7.0.0",
+        "get-stream": "^5.0.0",
+        "human-signals": "^1.1.1",
+        "is-stream": "^2.0.0",
+        "merge-stream": "^2.0.0",
+        "npm-run-path": "^4.0.0",
+        "onetime": "^5.1.0",
+        "signal-exit": "^3.0.2",
+        "strip-final-newline": "^2.0.0"
       },
       "engines": {
-        "node": ">=6"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sindresorhus/execa?sponsor=1"
       }
     },
     "node_modules/exit": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
-      "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+      "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
       "dev": true,
       "engines": {
         "node": ">= 0.8.0"
@@ -4046,7 +4098,7 @@
     "node_modules/expand-brackets": {
       "version": "2.1.4",
       "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
-      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==",
       "dev": true,
       "dependencies": {
         "debug": "^2.3.3",
@@ -4073,7 +4125,7 @@
     "node_modules/expand-brackets/node_modules/define-property": {
       "version": "0.2.5",
       "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
       "dev": true,
       "dependencies": {
         "is-descriptor": "^0.1.0"
@@ -4085,7 +4137,7 @@
     "node_modules/expand-brackets/node_modules/extend-shallow": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
       "dev": true,
       "dependencies": {
         "is-extendable": "^0.1.0"
@@ -4094,10 +4146,90 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/expand-brackets/node_modules/is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/expand-brackets/node_modules/is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/expand-brackets/node_modules/is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/expand-brackets/node_modules/is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/expand-brackets/node_modules/kind-of": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+      "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/expand-brackets/node_modules/ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
       "dev": true
     },
     "node_modules/expect": {
@@ -4117,16 +4249,10 @@
         "node": ">= 10.14.2"
       }
     },
-    "node_modules/extend": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
-      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
-      "dev": true
-    },
     "node_modules/extend-shallow": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
-      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
       "dev": true,
       "dependencies": {
         "assign-symbols": "^1.0.0",
@@ -4136,18 +4262,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/extend-shallow/node_modules/is-extendable": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
-      "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
-      "dev": true,
-      "dependencies": {
-        "is-plain-object": "^2.0.4"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/extglob": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
@@ -4170,7 +4284,7 @@
     "node_modules/extglob/node_modules/define-property": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+      "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
       "dev": true,
       "dependencies": {
         "is-descriptor": "^1.0.0"
@@ -4182,7 +4296,7 @@
     "node_modules/extglob/node_modules/extend-shallow": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
       "dev": true,
       "dependencies": {
         "is-extendable": "^0.1.0"
@@ -4191,40 +4305,11 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/extglob/node_modules/is-accessor-descriptor": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
-      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+    "node_modules/extglob/node_modules/is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
       "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/extglob/node_modules/is-data-descriptor": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
-      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/extglob/node_modules/is-descriptor": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
-      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
-      "dev": true,
-      "dependencies": {
-        "is-accessor-descriptor": "^1.0.0",
-        "is-data-descriptor": "^1.0.0",
-        "kind-of": "^6.0.2"
-      },
       "engines": {
         "node": ">=0.10.0"
       }
@@ -4249,30 +4334,6 @@
         "@types/yauzl": "^2.9.1"
       }
     },
-    "node_modules/extract-zip/node_modules/get-stream": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
-      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
-      "dev": true,
-      "dependencies": {
-        "pump": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/extsprintf": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
-      "dev": true,
-      "engines": [
-        "node >=0.6.0"
-      ]
-    },
     "node_modules/fast-deep-equal": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -4280,9 +4341,9 @@
       "dev": true
     },
     "node_modules/fast-glob": {
-      "version": "3.2.11",
-      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
-      "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
+      "version": "3.2.12",
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
+      "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
       "dev": true,
       "dependencies": {
         "@nodelib/fs.stat": "^2.0.2",
@@ -4316,22 +4377,22 @@
     "node_modules/fast-levenshtein": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
-      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+      "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
       "dev": true
     },
     "node_modules/fastq": {
-      "version": "1.13.0",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
-      "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+      "version": "1.15.0",
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
+      "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
       "dev": true,
       "dependencies": {
         "reusify": "^1.0.4"
       }
     },
     "node_modules/fb-watchman": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
-      "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
+      "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
       "dev": true,
       "dependencies": {
         "bser": "2.1.1"
@@ -4340,7 +4401,7 @@
     "node_modules/fd-slicer": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
-      "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+      "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
       "dev": true,
       "dependencies": {
         "pend": "~1.2.0"
@@ -4371,16 +4432,19 @@
       }
     },
     "node_modules/find-up": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
-      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+      "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
       "dev": true,
       "dependencies": {
-        "locate-path": "^5.0.0",
+        "locate-path": "^6.0.0",
         "path-exists": "^4.0.0"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/flat-cache": {
@@ -4397,52 +4461,32 @@
       }
     },
     "node_modules/flatted": {
-      "version": "3.2.5",
-      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz",
-      "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==",
+      "version": "3.2.7",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
+      "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
       "dev": true
     },
+    "node_modules/for-each": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+      "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+      "dependencies": {
+        "is-callable": "^1.1.3"
+      }
+    },
     "node_modules/for-in": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
-      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
-    "node_modules/foreach": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
-      "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
-    },
-    "node_modules/forever-agent": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/form-data": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
-      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
-      "dev": true,
-      "dependencies": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.6",
-        "mime-types": "^2.1.12"
-      },
-      "engines": {
-        "node": ">= 0.12"
-      }
-    },
     "node_modules/fragment-cache": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
-      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==",
       "dev": true,
       "dependencies": {
         "map-cache": "^0.2.2"
@@ -4472,7 +4516,7 @@
     "node_modules/fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
     },
     "node_modules/fsevents": {
       "version": "2.3.2",
@@ -4493,32 +4537,6 @@
       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
       "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
     },
-    "node_modules/functional-red-black-tree": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
-      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
-      "dev": true
-    },
-    "node_modules/gauge": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
-      "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
-      "dev": true,
-      "dependencies": {
-        "aproba": "^1.0.3 || ^2.0.0",
-        "color-support": "^1.1.2",
-        "console-control-strings": "^1.0.0",
-        "has-unicode": "^2.0.1",
-        "object-assign": "^4.1.1",
-        "signal-exit": "^3.0.0",
-        "string-width": "^4.2.3",
-        "strip-ansi": "^6.0.1",
-        "wide-align": "^1.1.2"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/gaze": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
@@ -4550,13 +4568,13 @@
       }
     },
     "node_modules/get-intrinsic": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
-      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
+      "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==",
       "dependencies": {
         "function-bind": "^1.1.1",
         "has": "^1.0.3",
-        "has-symbols": "^1.0.1"
+        "has-symbols": "^1.0.3"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -4574,51 +4592,45 @@
     "node_modules/get-stdin": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
-      "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+      "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
     "node_modules/get-stream": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
-      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
       "dev": true,
       "dependencies": {
         "pump": "^3.0.0"
       },
       "engines": {
-        "node": ">=6"
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/get-value": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
-      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
-    "node_modules/getpass": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
-      "dev": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0"
-      }
-    },
     "node_modules/glob": {
-      "version": "7.1.6",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
-      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
       "dependencies": {
         "fs.realpath": "^1.0.0",
         "inflight": "^1.0.4",
         "inherits": "2",
-        "minimatch": "^3.0.4",
+        "minimatch": "^3.1.1",
         "once": "^1.3.0",
         "path-is-absolute": "^1.0.0"
       },
@@ -4642,12 +4654,18 @@
       }
     },
     "node_modules/globals": {
-      "version": "11.12.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
-      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+      "version": "13.20.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
+      "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
       "dev": true,
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/globby": {
@@ -4671,55 +4689,81 @@
       }
     },
     "node_modules/globule": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz",
-      "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==",
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz",
+      "integrity": "sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==",
       "dev": true,
       "dependencies": {
         "glob": "~7.1.1",
-        "lodash": "~4.17.10",
+        "lodash": "^4.17.21",
         "minimatch": "~3.0.2"
       },
       "engines": {
         "node": ">= 0.10"
       }
     },
+    "node_modules/globule/node_modules/glob": {
+      "version": "7.1.7",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+      "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/globule/node_modules/minimatch": {
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
+      "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/gopd": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+      "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+      "dependencies": {
+        "get-intrinsic": "^1.1.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/graceful-fs": {
-      "version": "4.2.10",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
-      "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+      "version": "4.2.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+      "dev": true
+    },
+    "node_modules/grapheme-splitter": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+      "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
       "dev": true
     },
     "node_modules/growly": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
-      "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
+      "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==",
       "dev": true,
       "optional": true
     },
-    "node_modules/har-schema": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
-      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/har-validator": {
-      "version": "5.1.5",
-      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
-      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
-      "deprecated": "this library is no longer supported",
-      "dev": true,
-      "dependencies": {
-        "ajv": "^6.12.3",
-        "har-schema": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
     "node_modules/hard-rejection": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
@@ -4750,9 +4794,23 @@
       }
     },
     "node_modules/has-symbols": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
-      "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-tostringtag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+      "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+      "dependencies": {
+        "has-symbols": "^1.0.2"
+      },
       "engines": {
         "node": ">= 0.4"
       },
@@ -4763,13 +4821,13 @@
     "node_modules/has-unicode": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
-      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
+      "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
       "dev": true
     },
     "node_modules/has-value": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
-      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==",
       "dev": true,
       "dependencies": {
         "get-value": "^2.0.6",
@@ -4783,7 +4841,7 @@
     "node_modules/has-values": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
-      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+      "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==",
       "dev": true,
       "dependencies": {
         "is-number": "^3.0.0",
@@ -4796,7 +4854,7 @@
     "node_modules/has-values/node_modules/is-number": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
-      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
       "dev": true,
       "dependencies": {
         "kind-of": "^3.0.2"
@@ -4808,7 +4866,7 @@
     "node_modules/has-values/node_modules/is-number/node_modules/kind-of": {
       "version": "3.2.2",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
       "dev": true,
       "dependencies": {
         "is-buffer": "^1.1.5"
@@ -4820,7 +4878,7 @@
     "node_modules/has-values/node_modules/kind-of": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
-      "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+      "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==",
       "dev": true,
       "dependencies": {
         "is-buffer": "^1.1.5"
@@ -4830,9 +4888,33 @@
       }
     },
     "node_modules/hosted-git-info": {
-      "version": "2.8.9",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
-      "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+      "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
+      "dev": true,
+      "dependencies": {
+        "lru-cache": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/hosted-git-info/node_modules/lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "dev": true,
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/hosted-git-info/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
       "dev": true
     },
     "node_modules/hsluv": {
@@ -4859,9 +4941,9 @@
       "dev": true
     },
     "node_modules/http-cache-semantics": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
-      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
+      "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
       "dev": true
     },
     "node_modules/http-proxy-agent": {
@@ -4878,21 +4960,6 @@
         "node": ">= 6"
       }
     },
-    "node_modules/http-signature": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
-      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
-      "dev": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0",
-        "jsprim": "^1.2.2",
-        "sshpk": "^1.7.0"
-      },
-      "engines": {
-        "node": ">=0.8",
-        "npm": ">=1.3.7"
-      }
-    },
     "node_modules/https-proxy-agent": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
@@ -4918,19 +4985,20 @@
     "node_modules/humanize-ms": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
-      "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=",
+      "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
       "dev": true,
       "dependencies": {
         "ms": "^2.0.0"
       }
     },
     "node_modules/iconv-lite": {
-      "version": "0.4.24",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
-      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
       "dev": true,
+      "optional": true,
       "dependencies": {
-        "safer-buffer": ">= 2.1.2 < 3"
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
       },
       "engines": {
         "node": ">=0.10.0"
@@ -4957,18 +5025,18 @@
       ]
     },
     "node_modules/ignore": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
-      "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+      "version": "5.2.4",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+      "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
       "dev": true,
       "engines": {
         "node": ">= 4"
       }
     },
     "node_modules/immer": {
-      "version": "9.0.14",
-      "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.14.tgz",
-      "integrity": "sha512-ubBeqQutOSLIFCUBN03jGeOS6a3DoYlSYwYJTa+gSKEZKU5redJIqkIdZ3JVv/4RZpfcXdAWH5zCNLWPRv2WDw==",
+      "version": "9.0.21",
+      "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
+      "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==",
       "funding": {
         "type": "opencollective",
         "url": "https://opencollective.com/immer"
@@ -4990,19 +5058,10 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/import-fresh/node_modules/resolve-from": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
-      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/import-local": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz",
-      "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+      "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
       "dev": true,
       "dependencies": {
         "pkg-dir": "^4.2.0",
@@ -5013,12 +5072,15 @@
       },
       "engines": {
         "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/imurmurhash": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
-      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
       "dev": true,
       "engines": {
         "node": ">=0.8.19"
@@ -5042,7 +5104,7 @@
     "node_modules/inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
       "dependencies": {
         "once": "^1.3.0",
         "wrappy": "1"
@@ -5054,41 +5116,30 @@
       "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
     },
     "node_modules/ip": {
-      "version": "1.1.8",
-      "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
-      "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
+      "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==",
       "dev": true
     },
     "node_modules/is-accessor-descriptor": {
-      "version": "0.1.6",
-      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
-      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
       "dev": true,
       "dependencies": {
-        "kind-of": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-accessor-descriptor/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
+        "kind-of": "^6.0.0"
       },
       "engines": {
         "node": ">=0.10.0"
       }
     },
     "node_modules/is-arguments": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz",
-      "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==",
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
+      "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
       "dependencies": {
-        "call-bind": "^1.0.0"
+        "call-bind": "^1.0.2",
+        "has-tostringtag": "^1.0.0"
       },
       "engines": {
         "node": ">= 0.4"
@@ -5100,7 +5151,7 @@
     "node_modules/is-arrayish": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
       "dev": true
     },
     "node_modules/is-buffer": {
@@ -5109,10 +5160,25 @@
       "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
       "dev": true
     },
+    "node_modules/is-builtin-module": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz",
+      "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==",
+      "dev": true,
+      "dependencies": {
+        "builtin-modules": "^3.3.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/is-callable": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz",
-      "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==",
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+      "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
       "engines": {
         "node": ">= 0.4"
       },
@@ -5133,9 +5199,9 @@
       }
     },
     "node_modules/is-core-module": {
-      "version": "2.9.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
-      "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
+      "version": "2.11.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+      "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
       "dev": true,
       "dependencies": {
         "has": "^1.0.3"
@@ -5145,63 +5211,31 @@
       }
     },
     "node_modules/is-data-descriptor": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
-      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
       "dev": true,
       "dependencies": {
-        "kind-of": "^3.0.2"
+        "kind-of": "^6.0.0"
       },
       "engines": {
         "node": ">=0.10.0"
       }
     },
-    "node_modules/is-data-descriptor/node_modules/kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "dependencies": {
-        "is-buffer": "^1.1.5"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-date-object": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
-      "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-descriptor": {
-      "version": "0.1.6",
-      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
-      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
       "dev": true,
       "dependencies": {
-        "is-accessor-descriptor": "^0.1.6",
-        "is-data-descriptor": "^0.1.4",
-        "kind-of": "^5.0.0"
+        "is-accessor-descriptor": "^1.0.0",
+        "is-data-descriptor": "^1.0.0",
+        "kind-of": "^6.0.2"
       },
       "engines": {
         "node": ">=0.10.0"
       }
     },
-    "node_modules/is-descriptor/node_modules/kind-of": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
-      "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/is-docker": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
@@ -5219,10 +5253,13 @@
       }
     },
     "node_modules/is-extendable": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
-      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+      "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
       "dev": true,
+      "dependencies": {
+        "is-plain-object": "^2.0.4"
+      },
       "engines": {
         "node": ">=0.10.0"
       }
@@ -5230,7 +5267,7 @@
     "node_modules/is-extglob": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -5255,9 +5292,12 @@
       }
     },
     "node_modules/is-generator-function": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz",
-      "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==",
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
+      "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
+      "dependencies": {
+        "has-tostringtag": "^1.0.0"
+      },
       "engines": {
         "node": ">= 0.4"
       },
@@ -5280,26 +5320,15 @@
     "node_modules/is-lambda": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
-      "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=",
+      "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
       "dev": true
     },
     "node_modules/is-module": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
-      "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
+      "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
       "dev": true
     },
-    "node_modules/is-negative-zero": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
-      "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-number": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -5309,10 +5338,19 @@
         "node": ">=0.12.0"
       }
     },
+    "node_modules/is-path-inside": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+      "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/is-plain-obj": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
-      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+      "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -5345,54 +5383,28 @@
         "@types/estree": "*"
       }
     },
-    "node_modules/is-regex": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz",
-      "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==",
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "has-symbols": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-stream": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
       "dev": true,
       "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-symbol": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
-      "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
-      "dependencies": {
-        "has-symbols": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
+        "node": ">=8"
       },
       "funding": {
-        "url": "https://github.com/sponsors/ljharb"
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/is-typed-array": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.4.tgz",
-      "integrity": "sha512-ILaRgn4zaSrVNXNGtON6iFNotXW3hAPF3+0fB1usg2jFlWqo5fEDdmJkz0zBfoi7Dgskr8Khi2xZ8cXqZEfXNA==",
+      "version": "1.1.10",
+      "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
+      "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
       "dependencies": {
-        "available-typed-arrays": "^1.0.2",
-        "call-bind": "^1.0.0",
-        "es-abstract": "^1.18.0-next.1",
-        "foreach": "^2.0.5",
-        "has-symbols": "^1.0.1"
+        "available-typed-arrays": "^1.0.5",
+        "call-bind": "^1.0.2",
+        "for-each": "^0.3.3",
+        "gopd": "^1.0.1",
+        "has-tostringtag": "^1.0.0"
       },
       "engines": {
         "node": ">= 0.4"
@@ -5404,7 +5416,7 @@
     "node_modules/is-typedarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
-      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
       "dev": true
     },
     "node_modules/is-windows": {
@@ -5432,34 +5444,28 @@
     "node_modules/isarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
       "dev": true
     },
     "node_modules/isexe": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
       "dev": true
     },
     "node_modules/isobject": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
-    "node_modules/isstream": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
-      "dev": true
-    },
     "node_modules/istanbul-lib-coverage": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
-      "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
+      "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
       "dev": true,
       "engines": {
         "node": ">=8"
@@ -5480,6 +5486,15 @@
         "node": ">=8"
       }
     },
+    "node_modules/istanbul-lib-instrument/node_modules/semver": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
     "node_modules/istanbul-lib-report": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
@@ -5495,9 +5510,9 @@
       }
     },
     "node_modules/istanbul-lib-source-maps": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz",
-      "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+      "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
       "dev": true,
       "dependencies": {
         "debug": "^4.1.1",
@@ -5505,13 +5520,13 @@
         "source-map": "^0.6.1"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=10"
       }
     },
     "node_modules/istanbul-reports": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz",
-      "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==",
+      "version": "3.1.5",
+      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
+      "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
       "dev": true,
       "dependencies": {
         "html-escaper": "^2.0.0",
@@ -5552,125 +5567,34 @@
         "node": ">= 10.14.2"
       }
     },
-    "node_modules/jest-changed-files/node_modules/cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+    "node_modules/jest-cli": {
+      "version": "26.6.3",
+      "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz",
+      "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==",
       "dev": true,
       "dependencies": {
-        "path-key": "^3.1.0",
-        "shebang-command": "^2.0.0",
-        "which": "^2.0.1"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/jest-changed-files/node_modules/execa": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
-      "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
-      "dev": true,
-      "dependencies": {
-        "cross-spawn": "^7.0.0",
-        "get-stream": "^5.0.0",
-        "human-signals": "^1.1.1",
-        "is-stream": "^2.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^4.0.0",
-        "onetime": "^5.1.0",
-        "signal-exit": "^3.0.2",
-        "strip-final-newline": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
-      }
-    },
-    "node_modules/jest-changed-files/node_modules/get-stream": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
-      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
-      "dev": true,
-      "dependencies": {
-        "pump": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/jest-changed-files/node_modules/is-stream": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
-      "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/jest-changed-files/node_modules/npm-run-path": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
-      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
-      "dev": true,
-      "dependencies": {
-        "path-key": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/jest-changed-files/node_modules/path-key": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/jest-changed-files/node_modules/shebang-command": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
-      "dev": true,
-      "dependencies": {
-        "shebang-regex": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/jest-changed-files/node_modules/shebang-regex": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/jest-changed-files/node_modules/which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-      "dev": true,
-      "dependencies": {
-        "isexe": "^2.0.0"
+        "@jest/core": "^26.6.3",
+        "@jest/test-result": "^26.6.2",
+        "@jest/types": "^26.6.2",
+        "chalk": "^4.0.0",
+        "exit": "^0.1.2",
+        "graceful-fs": "^4.2.4",
+        "import-local": "^3.0.2",
+        "is-ci": "^2.0.0",
+        "jest-config": "^26.6.3",
+        "jest-util": "^26.6.2",
+        "jest-validate": "^26.6.2",
+        "prompts": "^2.0.1",
+        "yargs": "^15.4.1"
       },
       "bin": {
-        "node-which": "bin/node-which"
+        "jest": "bin/jest.js"
       },
       "engines": {
-        "node": ">= 8"
+        "node": ">= 10.14.2"
       }
     },
-    "node_modules/jest-config": {
+    "node_modules/jest-cli/node_modules/jest-config": {
       "version": "26.6.3",
       "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz",
       "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==",
@@ -5912,9 +5836,9 @@
       }
     },
     "node_modules/jest-pnp-resolver": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz",
-      "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==",
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
+      "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
       "dev": true,
       "engines": {
         "node": ">=6"
@@ -6001,6 +5925,43 @@
         "node": ">= 10.14.2"
       }
     },
+    "node_modules/jest-runner/node_modules/jest-config": {
+      "version": "26.6.3",
+      "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz",
+      "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/core": "^7.1.0",
+        "@jest/test-sequencer": "^26.6.3",
+        "@jest/types": "^26.6.2",
+        "babel-jest": "^26.6.3",
+        "chalk": "^4.0.0",
+        "deepmerge": "^4.2.2",
+        "glob": "^7.1.1",
+        "graceful-fs": "^4.2.4",
+        "jest-environment-jsdom": "^26.6.2",
+        "jest-environment-node": "^26.6.2",
+        "jest-get-type": "^26.3.0",
+        "jest-jasmine2": "^26.6.3",
+        "jest-regex-util": "^26.0.0",
+        "jest-resolve": "^26.6.2",
+        "jest-util": "^26.6.2",
+        "jest-validate": "^26.6.2",
+        "micromatch": "^4.0.2",
+        "pretty-format": "^26.6.2"
+      },
+      "engines": {
+        "node": ">= 10.14.2"
+      },
+      "peerDependencies": {
+        "ts-node": ">=9.0.0"
+      },
+      "peerDependenciesMeta": {
+        "ts-node": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/jest-runtime": {
       "version": "26.6.3",
       "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz",
@@ -6042,6 +6003,43 @@
         "node": ">= 10.14.2"
       }
     },
+    "node_modules/jest-runtime/node_modules/jest-config": {
+      "version": "26.6.3",
+      "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz",
+      "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/core": "^7.1.0",
+        "@jest/test-sequencer": "^26.6.3",
+        "@jest/types": "^26.6.2",
+        "babel-jest": "^26.6.3",
+        "chalk": "^4.0.0",
+        "deepmerge": "^4.2.2",
+        "glob": "^7.1.1",
+        "graceful-fs": "^4.2.4",
+        "jest-environment-jsdom": "^26.6.2",
+        "jest-environment-node": "^26.6.2",
+        "jest-get-type": "^26.3.0",
+        "jest-jasmine2": "^26.6.3",
+        "jest-regex-util": "^26.0.0",
+        "jest-resolve": "^26.6.2",
+        "jest-util": "^26.6.2",
+        "jest-validate": "^26.6.2",
+        "micromatch": "^4.0.2",
+        "pretty-format": "^26.6.2"
+      },
+      "engines": {
+        "node": ">= 10.14.2"
+      },
+      "peerDependencies": {
+        "ts-node": ">=9.0.0"
+      },
+      "peerDependenciesMeta": {
+        "ts-node": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/jest-serializer": {
       "version": "26.6.2",
       "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz",
@@ -6082,21 +6080,6 @@
         "node": ">= 10.14.2"
       }
     },
-    "node_modules/jest-snapshot/node_modules/semver": {
-      "version": "7.3.5",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
-      "dev": true,
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/jest-util": {
       "version": "26.6.2",
       "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz",
@@ -6132,9 +6115,9 @@
       }
     },
     "node_modules/jest-validate/node_modules/camelcase": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
-      "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+      "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
       "dev": true,
       "engines": {
         "node": ">=10"
@@ -6175,39 +6158,22 @@
         "node": ">= 10.13.0"
       }
     },
-    "node_modules/jest/node_modules/jest-cli": {
-      "version": "26.6.3",
-      "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz",
-      "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==",
-      "dev": true,
-      "dependencies": {
-        "@jest/core": "^26.6.3",
-        "@jest/test-result": "^26.6.2",
-        "@jest/types": "^26.6.2",
-        "chalk": "^4.0.0",
-        "exit": "^0.1.2",
-        "graceful-fs": "^4.2.4",
-        "import-local": "^3.0.2",
-        "is-ci": "^2.0.0",
-        "jest-config": "^26.6.3",
-        "jest-util": "^26.6.2",
-        "jest-validate": "^26.6.2",
-        "prompts": "^2.0.1",
-        "yargs": "^15.4.1"
-      },
-      "bin": {
-        "jest": "bin/jest.js"
-      },
-      "engines": {
-        "node": ">= 10.14.2"
-      }
-    },
     "node_modules/js-base64": {
       "version": "2.6.4",
       "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
       "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==",
       "dev": true
     },
+    "node_modules/js-sdsl": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz",
+      "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==",
+      "dev": true,
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/js-sdsl"
+      }
+    },
     "node_modules/js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -6215,33 +6181,26 @@
       "dev": true
     },
     "node_modules/js-yaml": {
-      "version": "3.14.1",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
-      "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
       "dev": true,
       "dependencies": {
-        "argparse": "^1.0.7",
-        "esprima": "^4.0.0"
+        "argparse": "^2.0.1"
       },
       "bin": {
         "js-yaml": "bin/js-yaml.js"
       }
     },
-    "node_modules/jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
-      "dev": true
-    },
     "node_modules/jsbn-rsa": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/jsbn-rsa/-/jsbn-rsa-1.0.4.tgz",
       "integrity": "sha512-unHyEPFGjr6WCzrcMiwdNhYMlq4gXt6Hg5JuKOyE7OXJ7GbVMpottnqsUkPeZCAYqByAkn4N8gJwCpnacduOew=="
     },
     "node_modules/jsdom": {
-      "version": "16.6.0",
-      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz",
-      "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==",
+      "version": "16.7.0",
+      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz",
+      "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==",
       "dev": true,
       "dependencies": {
         "abab": "^2.0.5",
@@ -6269,7 +6228,7 @@
         "whatwg-encoding": "^1.0.5",
         "whatwg-mimetype": "^2.3.0",
         "whatwg-url": "^8.5.0",
-        "ws": "^7.4.5",
+        "ws": "^7.4.6",
         "xml-name-validator": "^3.0.0"
       },
       "engines": {
@@ -6298,6 +6257,77 @@
         "node": ">= 6"
       }
     },
+    "node_modules/jsdom/node_modules/tough-cookie": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz",
+      "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==",
+      "dev": true,
+      "dependencies": {
+        "psl": "^1.1.33",
+        "punycode": "^2.1.1",
+        "universalify": "^0.2.0",
+        "url-parse": "^1.5.3"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/jsdom/node_modules/tr46": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
+      "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
+      "dev": true,
+      "dependencies": {
+        "punycode": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/jsdom/node_modules/webidl-conversions": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
+      "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
+      "dev": true,
+      "engines": {
+        "node": ">=10.4"
+      }
+    },
+    "node_modules/jsdom/node_modules/whatwg-url": {
+      "version": "8.7.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz",
+      "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==",
+      "dev": true,
+      "dependencies": {
+        "lodash": "^4.7.0",
+        "tr46": "^2.1.0",
+        "webidl-conversions": "^6.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/jsdom/node_modules/ws": {
+      "version": "7.5.9",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
+      "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=8.3.0"
+      },
+      "peerDependencies": {
+        "bufferutil": "^4.0.1",
+        "utf-8-validate": "^5.0.2"
+      },
+      "peerDependenciesMeta": {
+        "bufferutil": {
+          "optional": true
+        },
+        "utf-8-validate": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/jsesc": {
       "version": "2.5.2",
       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@@ -6316,12 +6346,6 @@
       "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
       "dev": true
     },
-    "node_modules/json-schema": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
-      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
-      "dev": true
-    },
     "node_modules/json-schema-traverse": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -6331,23 +6355,14 @@
     "node_modules/json-stable-stringify-without-jsonify": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
-      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
-      "dev": true
-    },
-    "node_modules/json-stringify-safe": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+      "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
       "dev": true
     },
     "node_modules/json5": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
-      "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
       "dev": true,
-      "dependencies": {
-        "minimist": "^1.2.5"
-      },
       "bin": {
         "json5": "lib/cli.js"
       },
@@ -6355,21 +6370,6 @@
         "node": ">=6"
       }
     },
-    "node_modules/jsprim": {
-      "version": "1.4.2",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
-      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
-      "dev": true,
-      "dependencies": {
-        "assert-plus": "1.0.0",
-        "extsprintf": "1.3.0",
-        "json-schema": "0.4.0",
-        "verror": "1.10.0"
-      },
-      "engines": {
-        "node": ">=0.6.0"
-      }
-    },
     "node_modules/kind-of": {
       "version": "6.0.3",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@@ -6398,34 +6398,37 @@
       }
     },
     "node_modules/levn": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
-      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+      "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
       "dev": true,
       "dependencies": {
-        "prelude-ls": "~1.1.2",
-        "type-check": "~0.3.2"
+        "prelude-ls": "^1.2.1",
+        "type-check": "~0.4.0"
       },
       "engines": {
         "node": ">= 0.8.0"
       }
     },
     "node_modules/lines-and-columns": {
-      "version": "1.1.6",
-      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
-      "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
       "dev": true
     },
     "node_modules/locate-path": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
-      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+      "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
       "dev": true,
       "dependencies": {
-        "p-locate": "^4.1.0"
+        "p-locate": "^5.0.0"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/lodash": {
@@ -6446,24 +6449,24 @@
       "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
     },
     "node_modules/lru-cache": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
-      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
       "dev": true,
       "dependencies": {
-        "yallist": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=10"
+        "yallist": "^3.0.2"
       }
     },
     "node_modules/magic-string": {
-      "version": "0.25.7",
-      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
-      "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
+      "version": "0.27.0",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz",
+      "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==",
       "dev": true,
       "dependencies": {
-        "sourcemap-codec": "^1.4.4"
+        "@jridgewell/sourcemap-codec": "^1.4.13"
+      },
+      "engines": {
+        "node": ">=12"
       }
     },
     "node_modules/make-dir": {
@@ -6481,6 +6484,15 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/make-dir/node_modules/semver": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
     "node_modules/make-fetch-happen": {
       "version": "9.1.0",
       "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
@@ -6508,19 +6520,37 @@
         "node": ">= 10"
       }
     },
-    "node_modules/makeerror": {
-      "version": "1.0.11",
-      "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz",
-      "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=",
+    "node_modules/make-fetch-happen/node_modules/lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
       "dev": true,
       "dependencies": {
-        "tmpl": "1.0.x"
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/make-fetch-happen/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true
+    },
+    "node_modules/makeerror": {
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+      "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
+      "dev": true,
+      "dependencies": {
+        "tmpl": "1.0.5"
       }
     },
     "node_modules/map-cache": {
       "version": "0.2.2",
       "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
-      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -6541,7 +6571,7 @@
     "node_modules/map-visit": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
-      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+      "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==",
       "dev": true,
       "dependencies": {
         "object-visit": "^1.0.0"
@@ -6576,48 +6606,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/meow/node_modules/hosted-git-info": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
-      "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
-      "dev": true,
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/meow/node_modules/normalize-package-data": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
-      "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
-      "dev": true,
-      "dependencies": {
-        "hosted-git-info": "^4.0.1",
-        "is-core-module": "^2.5.0",
-        "semver": "^7.3.4",
-        "validate-npm-package-license": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/meow/node_modules/semver": {
-      "version": "7.3.7",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
-      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
-      "dev": true,
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/meow/node_modules/type-fest": {
       "version": "0.18.1",
       "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
@@ -6630,15 +6618,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/meow/node_modules/yargs-parser": {
-      "version": "20.2.9",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
-      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/merge-stream": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -6655,46 +6634,34 @@
       }
     },
     "node_modules/micromatch": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
-      "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
       "dev": true,
       "dependencies": {
-        "braces": "^3.0.1",
-        "picomatch": "^2.2.3"
+        "braces": "^3.0.2",
+        "picomatch": "^2.3.1"
       },
       "engines": {
         "node": ">=8.6"
       }
     },
-    "node_modules/micromatch/node_modules/picomatch": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
-      "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
     "node_modules/mime-db": {
-      "version": "1.45.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
-      "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==",
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
       "dev": true,
       "engines": {
         "node": ">= 0.6"
       }
     },
     "node_modules/mime-types": {
-      "version": "2.1.28",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz",
-      "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==",
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
       "dev": true,
       "dependencies": {
-        "mime-db": "1.45.0"
+        "mime-db": "1.52.0"
       },
       "engines": {
         "node": ">= 0.6"
@@ -6719,9 +6686,9 @@
       }
     },
     "node_modules/minimatch": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
       "dependencies": {
         "brace-expansion": "^1.1.7"
       },
@@ -6730,10 +6697,13 @@
       }
     },
     "node_modules/minimist": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
-      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
-      "dev": true
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
     },
     "node_modules/minimist-options": {
       "version": "4.1.0",
@@ -6750,9 +6720,9 @@
       }
     },
     "node_modules/minipass": {
-      "version": "3.1.6",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz",
-      "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==",
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
       "dev": true,
       "dependencies": {
         "yallist": "^4.0.0"
@@ -6826,6 +6796,12 @@
         "node": ">=8"
       }
     },
+    "node_modules/minipass/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true
+    },
     "node_modules/minizlib": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
@@ -6839,10 +6815,16 @@
         "node": ">= 8"
       }
     },
+    "node_modules/minizlib/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true
+    },
     "node_modules/mithril": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/mithril/-/mithril-2.2.0.tgz",
-      "integrity": "sha512-Dqdp2As819R5Wgtjbe+L2mww+K5/sVAqb4K/d4wmNg9Qp5IzzQbanbiU2l8GCWu/k44gClqDQBwNytEMLagVJQ==",
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/mithril/-/mithril-2.2.2.tgz",
+      "integrity": "sha512-YRm6eLv2UUaWaWHdH8L+desW9+DN7+oM34CxJv6tT2e1lNVue8bxQlknQeDRn9aKlO8sIujm2wqUHwM+Hb1wGQ==",
       "dependencies": {
         "ospec": "4.0.0"
       },
@@ -6850,6 +6832,12 @@
         "ospec": "ospec/bin/ospec"
       }
     },
+    "node_modules/mitt": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz",
+      "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==",
+      "dev": true
+    },
     "node_modules/mixin-deep": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
@@ -6863,16 +6851,16 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/mixin-deep/node_modules/is-extendable": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
-      "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+    "node_modules/mkdirp": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
       "dev": true,
-      "dependencies": {
-        "is-plain-object": "^2.0.4"
+      "bin": {
+        "mkdirp": "bin/cmd.js"
       },
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=10"
       }
     },
     "node_modules/mkdirp-classic": {
@@ -6888,9 +6876,9 @@
       "dev": true
     },
     "node_modules/nan": {
-      "version": "2.14.2",
-      "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
-      "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
+      "version": "2.17.0",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
+      "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==",
       "dev": true
     },
     "node_modules/nanomatch": {
@@ -6918,7 +6906,13 @@
     "node_modules/natural-compare": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
-      "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+      "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+      "dev": true
+    },
+    "node_modules/natural-compare-lite": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
+      "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
       "dev": true
     },
     "node_modules/negotiator": {
@@ -6956,28 +6950,6 @@
         }
       }
     },
-    "node_modules/node-fetch/node_modules/tr46": {
-      "version": "0.0.3",
-      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-      "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
-      "dev": true
-    },
-    "node_modules/node-fetch/node_modules/webidl-conversions": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
-      "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
-      "dev": true
-    },
-    "node_modules/node-fetch/node_modules/whatwg-url": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
-      "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
-      "dev": true,
-      "dependencies": {
-        "tr46": "~0.0.3",
-        "webidl-conversions": "^3.0.0"
-      }
-    },
     "node_modules/node-gyp": {
       "version": "8.4.1",
       "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz",
@@ -7003,16 +6975,16 @@
       }
     },
     "node_modules/node-gyp/node_modules/are-we-there-yet": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz",
-      "integrity": "sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
+      "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
       "dev": true,
       "dependencies": {
         "delegates": "^1.0.0",
         "readable-stream": "^3.6.0"
       },
       "engines": {
-        "node": "^12.13.0 || ^14.15.0 || >=16"
+        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
       }
     },
     "node_modules/node-gyp/node_modules/gauge": {
@@ -7049,65 +7021,12 @@
         "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
       }
     },
-    "node_modules/node-gyp/node_modules/readable-stream": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/node-gyp/node_modules/semver": {
-      "version": "7.3.7",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
-      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
-      "dev": true,
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/node-gyp/node_modules/which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-      "dev": true,
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "node-which": "bin/node-which"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
     "node_modules/node-int64": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
-      "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=",
+      "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
       "dev": true
     },
-    "node_modules/node-modules-regexp": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
-      "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/node-notifier": {
       "version": "8.0.2",
       "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz",
@@ -7123,48 +7042,26 @@
         "which": "^2.0.2"
       }
     },
-    "node_modules/node-notifier/node_modules/semver": {
-      "version": "7.3.5",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+    "node_modules/node-notifier/node_modules/uuid": {
+      "version": "8.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
       "dev": true,
       "optional": true,
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
       "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/node-notifier/node_modules/which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "node-which": "bin/node-which"
-      },
-      "engines": {
-        "node": ">= 8"
+        "uuid": "dist/bin/uuid"
       }
     },
     "node_modules/node-releases": {
-      "version": "1.1.72",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz",
-      "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==",
+      "version": "2.0.10",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz",
+      "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==",
       "dev": true
     },
     "node_modules/node-sass": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-7.0.1.tgz",
-      "integrity": "sha512-uMy+Xt29NlqKCFdFRZyXKOTqGt+QaKHexv9STj2WeLottnlqZEEWx6Bj0MXNthmFRRdM/YwyNo/8Tr46TOM0jQ==",
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-8.0.0.tgz",
+      "integrity": "sha512-jPzqCF2/e6JXw6r3VxfIqYc8tKQdkj5Z/BDATYyG6FL6b/LuYBNFGFVhus0mthcWifHm/JzBpKAd+3eXsWeK/A==",
       "dev": true,
       "hasInstallScript": true,
       "dependencies": {
@@ -7175,85 +7072,247 @@
         "get-stdin": "^4.0.1",
         "glob": "^7.0.3",
         "lodash": "^4.17.15",
+        "make-fetch-happen": "^10.0.4",
         "meow": "^9.0.0",
-        "nan": "^2.13.2",
+        "nan": "^2.17.0",
         "node-gyp": "^8.4.1",
-        "npmlog": "^5.0.0",
-        "request": "^2.88.0",
-        "sass-graph": "4.0.0",
+        "sass-graph": "^4.0.1",
         "stdout-stream": "^1.4.0",
-        "true-case-path": "^1.0.2"
+        "true-case-path": "^2.2.1"
       },
       "bin": {
         "node-sass": "bin/node-sass"
       },
       "engines": {
+        "node": ">=14"
+      }
+    },
+    "node_modules/node-sass/node_modules/@npmcli/fs": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz",
+      "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==",
+      "dev": true,
+      "dependencies": {
+        "@gar/promisify": "^1.1.3",
+        "semver": "^7.3.5"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+      }
+    },
+    "node_modules/node-sass/node_modules/@npmcli/move-file": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz",
+      "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==",
+      "deprecated": "This functionality has been moved to @npmcli/fs",
+      "dev": true,
+      "dependencies": {
+        "mkdirp": "^1.0.4",
+        "rimraf": "^3.0.2"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+      }
+    },
+    "node_modules/node-sass/node_modules/@tootallnate/once": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
+      "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/node-sass/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/node-sass/node_modules/cacache": {
+      "version": "16.1.3",
+      "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz",
+      "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==",
+      "dev": true,
+      "dependencies": {
+        "@npmcli/fs": "^2.1.0",
+        "@npmcli/move-file": "^2.0.0",
+        "chownr": "^2.0.0",
+        "fs-minipass": "^2.1.0",
+        "glob": "^8.0.1",
+        "infer-owner": "^1.0.4",
+        "lru-cache": "^7.7.1",
+        "minipass": "^3.1.6",
+        "minipass-collect": "^1.0.2",
+        "minipass-flush": "^1.0.5",
+        "minipass-pipeline": "^1.2.4",
+        "mkdirp": "^1.0.4",
+        "p-map": "^4.0.0",
+        "promise-inflight": "^1.0.1",
+        "rimraf": "^3.0.2",
+        "ssri": "^9.0.0",
+        "tar": "^6.1.11",
+        "unique-filename": "^2.0.0"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+      }
+    },
+    "node_modules/node-sass/node_modules/cacache/node_modules/glob": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+      "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^5.0.1",
+        "once": "^1.3.0"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/node-sass/node_modules/http-proxy-agent": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
+      "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
+      "dev": true,
+      "dependencies": {
+        "@tootallnate/once": "2",
+        "agent-base": "6",
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/node-sass/node_modules/lru-cache": {
+      "version": "7.18.3",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+      "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+      "dev": true,
+      "engines": {
         "node": ">=12"
       }
     },
-    "node_modules/node-sass/node_modules/cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+    "node_modules/node-sass/node_modules/make-fetch-happen": {
+      "version": "10.2.1",
+      "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz",
+      "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==",
       "dev": true,
       "dependencies": {
-        "path-key": "^3.1.0",
-        "shebang-command": "^2.0.0",
-        "which": "^2.0.1"
+        "agentkeepalive": "^4.2.1",
+        "cacache": "^16.1.0",
+        "http-cache-semantics": "^4.1.0",
+        "http-proxy-agent": "^5.0.0",
+        "https-proxy-agent": "^5.0.0",
+        "is-lambda": "^1.0.1",
+        "lru-cache": "^7.7.1",
+        "minipass": "^3.1.6",
+        "minipass-collect": "^1.0.2",
+        "minipass-fetch": "^2.0.3",
+        "minipass-flush": "^1.0.5",
+        "minipass-pipeline": "^1.2.4",
+        "negotiator": "^0.6.3",
+        "promise-retry": "^2.0.1",
+        "socks-proxy-agent": "^7.0.0",
+        "ssri": "^9.0.0"
       },
       "engines": {
-        "node": ">= 8"
+        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
       }
     },
-    "node_modules/node-sass/node_modules/path-key": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/node-sass/node_modules/shebang-command": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+    "node_modules/node-sass/node_modules/minimatch": {
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+      "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
       "dev": true,
       "dependencies": {
-        "shebang-regex": "^3.0.0"
+        "brace-expansion": "^2.0.1"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=10"
       }
     },
-    "node_modules/node-sass/node_modules/shebang-regex": {
+    "node_modules/node-sass/node_modules/minipass-fetch": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz",
+      "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==",
+      "dev": true,
+      "dependencies": {
+        "minipass": "^3.1.6",
+        "minipass-sized": "^1.0.3",
+        "minizlib": "^2.1.2"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+      },
+      "optionalDependencies": {
+        "encoding": "^0.1.13"
+      }
+    },
+    "node_modules/node-sass/node_modules/socks-proxy-agent": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz",
+      "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==",
+      "dev": true,
+      "dependencies": {
+        "agent-base": "^6.0.2",
+        "debug": "^4.3.3",
+        "socks": "^2.6.2"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/node-sass/node_modules/ssri": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz",
+      "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==",
+      "dev": true,
+      "dependencies": {
+        "minipass": "^3.1.1"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+      }
+    },
+    "node_modules/node-sass/node_modules/unique-filename": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz",
+      "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==",
+      "dev": true,
+      "dependencies": {
+        "unique-slug": "^3.0.0"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+      }
+    },
+    "node_modules/node-sass/node_modules/unique-slug": {
       "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/node-sass/node_modules/which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz",
+      "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==",
       "dev": true,
       "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "node-which": "bin/node-which"
+        "imurmurhash": "^0.1.4"
       },
       "engines": {
-        "node": ">= 8"
+        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
       }
     },
     "node_modules/node-watch": {
-      "version": "0.7.1",
-      "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.1.tgz",
-      "integrity": "sha512-UWblPYuZYrkCQCW5PxAwYSxaELNBLUckrTBBk8xr1/bUgyOkYYTsUcV4e3ytcazFEOyiRyiUrsG37pu6I0I05g==",
+      "version": "0.7.3",
+      "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.3.tgz",
+      "integrity": "sha512-3l4E8uMPY1HdMMryPRUAl+oIHtXtyiTlIiESNSVSNxcPfzAFzeTbXFQkZfAwBbo0B1qMSG8nUABx+Gd+YrbKrQ==",
       "dev": true,
       "engines": {
         "node": ">=6"
@@ -7280,24 +7339,18 @@
       }
     },
     "node_modules/normalize-package-data": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
-      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
+      "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
       "dev": true,
       "dependencies": {
-        "hosted-git-info": "^2.1.4",
-        "resolve": "^1.10.0",
-        "semver": "2 || 3 || 4 || 5",
+        "hosted-git-info": "^4.0.1",
+        "is-core-module": "^2.5.0",
+        "semver": "^7.3.4",
         "validate-npm-package-license": "^3.0.1"
-      }
-    },
-    "node_modules/normalize-package-data/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
     "node_modules/normalize-path": {
@@ -7310,57 +7363,27 @@
       }
     },
     "node_modules/npm-run-path": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
-      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
       "dev": true,
       "dependencies": {
-        "path-key": "^2.0.0"
+        "path-key": "^3.0.0"
       },
       "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/npmlog": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
-      "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
-      "dev": true,
-      "dependencies": {
-        "are-we-there-yet": "^2.0.0",
-        "console-control-strings": "^1.1.0",
-        "gauge": "^3.0.0",
-        "set-blocking": "^2.0.0"
+        "node": ">=8"
       }
     },
     "node_modules/nwsapi": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
-      "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz",
+      "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==",
       "dev": true
     },
-    "node_modules/oauth-sign": {
-      "version": "0.9.0",
-      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
-      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/object-assign": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/object-copy": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
-      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==",
       "dev": true,
       "dependencies": {
         "copy-descriptor": "^0.1.0",
@@ -7374,7 +7397,7 @@
     "node_modules/object-copy/node_modules/define-property": {
       "version": "0.2.5",
       "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
       "dev": true,
       "dependencies": {
         "is-descriptor": "^0.1.0"
@@ -7383,10 +7406,57 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/object-copy/node_modules/is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-copy/node_modules/is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-copy/node_modules/is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+      "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/object-copy/node_modules/kind-of": {
       "version": "3.2.2",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
       "dev": true,
       "dependencies": {
         "is-buffer": "^1.1.5"
@@ -7395,26 +7465,10 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/object-inspect": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-      "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/object-keys": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
-      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
     "node_modules/object-visit": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
-      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==",
       "dev": true,
       "dependencies": {
         "isobject": "^3.0.0"
@@ -7423,27 +7477,10 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/object.assign": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-      "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
-      "dependencies": {
-        "call-bind": "^1.0.0",
-        "define-properties": "^1.1.3",
-        "has-symbols": "^1.0.1",
-        "object-keys": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/object.pick": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
-      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+      "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==",
       "dev": true,
       "dependencies": {
         "isobject": "^3.0.1"
@@ -7455,7 +7492,7 @@
     "node_modules/once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
       "dependencies": {
         "wrappy": "1"
       }
@@ -7476,17 +7513,17 @@
       }
     },
     "node_modules/optionator": {
-      "version": "0.8.3",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
-      "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+      "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
       "dev": true,
       "dependencies": {
-        "deep-is": "~0.1.3",
-        "fast-levenshtein": "~2.0.6",
-        "levn": "~0.3.0",
-        "prelude-ls": "~1.1.2",
-        "type-check": "~0.3.2",
-        "word-wrap": "~1.2.3"
+        "deep-is": "^0.1.3",
+        "fast-levenshtein": "^2.0.6",
+        "levn": "^0.4.1",
+        "prelude-ls": "^1.2.1",
+        "type-check": "^0.4.0",
+        "word-wrap": "^1.2.3"
       },
       "engines": {
         "node": ">= 0.8.0"
@@ -7518,37 +7555,40 @@
     "node_modules/p-finally": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
-      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+      "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
       "dev": true,
       "engines": {
         "node": ">=4"
       }
     },
     "node_modules/p-limit": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
       "dev": true,
       "dependencies": {
-        "p-try": "^2.0.0"
+        "yocto-queue": "^0.1.0"
       },
       "engines": {
-        "node": ">=6"
+        "node": ">=10"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/p-locate": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
-      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+      "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
       "dev": true,
       "dependencies": {
-        "p-limit": "^2.2.0"
+        "p-limit": "^3.0.2"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/p-map": {
@@ -7619,7 +7659,7 @@
     "node_modules/pascalcase": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
-      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -7637,18 +7677,18 @@
     "node_modules/path-is-absolute": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
       "engines": {
         "node": ">=0.10.0"
       }
     },
     "node_modules/path-key": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
-      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
       "dev": true,
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/path-parse": {
@@ -7669,19 +7709,19 @@
     "node_modules/pend": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
-      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+      "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
       "dev": true
     },
-    "node_modules/performance-now": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
-      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+    "node_modules/picocolors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
       "dev": true
     },
     "node_modules/picomatch": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
-      "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
       "dev": true,
       "engines": {
         "node": ">=8.6"
@@ -7691,38 +7731,26 @@
       }
     },
     "node_modules/pirates": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz",
-      "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==",
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
+      "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
       "dev": true,
-      "dependencies": {
-        "node-modules-regexp": "^1.0.0"
-      },
       "engines": {
         "node": ">= 6"
       }
     },
     "node_modules/pixelmatch": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.2.1.tgz",
-      "integrity": "sha512-WjcAdYSnKrrdDdqTcVEY7aB7UhhwjYQKYhHiBXdJef0MOaQeYpUdQ+iVyBLa5YBKS8MPVPPMX7rpOByISLpeEQ==",
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.3.0.tgz",
+      "integrity": "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==",
       "dev": true,
       "dependencies": {
-        "pngjs": "^4.0.1"
+        "pngjs": "^6.0.0"
       },
       "bin": {
         "pixelmatch": "bin/pixelmatch"
       }
     },
-    "node_modules/pixelmatch/node_modules/pngjs": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-4.0.1.tgz",
-      "integrity": "sha512-rf5+2/ioHeQxR6IxuYNYGFytUyG3lma/WW1nsmjeHlWwtb2aByla6dkVc8pmJ9nplzkTA0q2xx7mMWrOTqT4Gg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
     "node_modules/pkg-dir": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
@@ -7735,6 +7763,58 @@
         "node": ">=8"
       }
     },
+    "node_modules/pkg-dir/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/pngjs": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz",
@@ -7747,25 +7827,25 @@
     "node_modules/posix-character-classes": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
-      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+      "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
     "node_modules/prelude-ls": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
-      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+      "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
       "dev": true,
       "engines": {
         "node": ">= 0.8.0"
       }
     },
     "node_modules/prettier": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.0.tgz",
-      "integrity": "sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==",
+      "version": "2.8.7",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz",
+      "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==",
       "dev": true,
       "bin": {
         "prettier": "bin-prettier.js"
@@ -7810,7 +7890,7 @@
     "node_modules/promise-inflight": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
-      "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
+      "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
       "dev": true
     },
     "node_modules/promise-retry": {
@@ -7827,9 +7907,9 @@
       }
     },
     "node_modules/prompts": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz",
-      "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==",
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
+      "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
       "dev": true,
       "dependencies": {
         "kleur": "^3.0.3",
@@ -7840,9 +7920,9 @@
       }
     },
     "node_modules/protobufjs": {
-      "version": "6.10.2",
-      "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz",
-      "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==",
+      "version": "6.11.3",
+      "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz",
+      "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==",
       "hasInstallScript": true,
       "dependencies": {
         "@protobufjs/aspromise": "^1.1.2",
@@ -7856,7 +7936,7 @@
         "@protobufjs/pool": "^1.1.0",
         "@protobufjs/utf8": "^1.1.0",
         "@types/long": "^4.0.1",
-        "@types/node": "^13.7.0",
+        "@types/node": ">=13.7.0",
         "long": "^4.0.0"
       },
       "bin": {
@@ -7864,11 +7944,6 @@
         "pbts": "bin/pbts"
       }
     },
-    "node_modules/protobufjs/node_modules/@types/node": {
-      "version": "13.13.41",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.41.tgz",
-      "integrity": "sha512-qLT9IvHiXJfdrje9VmsLzun7cQ65obsBTmtU3EOnCSLFOoSHx1hpiRHoBnpdbyFqnzqdUUIv81JcEJQCB8un9g=="
-    },
     "node_modules/proxy-from-env": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
@@ -7876,9 +7951,9 @@
       "dev": true
     },
     "node_modules/psl": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
-      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
+      "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
       "dev": true
     },
     "node_modules/pump": {
@@ -7892,73 +7967,80 @@
       }
     },
     "node_modules/punycode": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+      "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
       "dev": true,
       "engines": {
         "node": ">=6"
       }
     },
     "node_modules/puppeteer": {
-      "version": "14.1.0",
-      "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-14.1.0.tgz",
-      "integrity": "sha512-T3eB4f6k9HVttYvyy8drGIKb04M+vxhepqM7qqcVCBTNT3T6M9cUaJT4k7P+a6wSonObJSJUP98JkPDQG+3fJw==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-19.8.0.tgz",
+      "integrity": "sha512-MpQClmttCUxv4bVokX/YSXLCU12CUApuRf0rIJyGknYcIrDQNkLUx1N7hNt88Ya4lq9VDsdiDEJ3bcPijqJYPQ==",
       "dev": true,
       "hasInstallScript": true,
       "dependencies": {
-        "cross-fetch": "3.1.5",
-        "debug": "4.3.4",
-        "devtools-protocol": "0.0.982423",
-        "extract-zip": "2.0.1",
+        "cosmiconfig": "8.1.3",
         "https-proxy-agent": "5.0.1",
-        "pkg-dir": "4.2.0",
         "progress": "2.0.3",
         "proxy-from-env": "1.1.0",
-        "rimraf": "3.0.2",
-        "tar-fs": "2.1.1",
-        "unbzip2-stream": "1.4.3",
-        "ws": "8.6.0"
+        "puppeteer-core": "19.8.0"
+      }
+    },
+    "node_modules/puppeteer/node_modules/chromium-bidi": {
+      "version": "0.4.5",
+      "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.5.tgz",
+      "integrity": "sha512-rkav9YzRfAshSTG3wNXF7P7yNiI29QAo1xBXElPoCoSQR5n20q3cOyVhDv6S7+GlF/CJ/emUxlQiR0xOPurkGg==",
+      "dev": true,
+      "dependencies": {
+        "mitt": "3.0.0"
       },
-      "engines": {
-        "node": ">=14.1.0"
+      "peerDependencies": {
+        "devtools-protocol": "*"
       }
     },
     "node_modules/puppeteer/node_modules/devtools-protocol": {
-      "version": "0.0.982423",
-      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.982423.tgz",
-      "integrity": "sha512-FnVW2nDbjGNw1uD/JRC+9U5768W7e1TfUwqbDTcSsAu1jXFjITSX8w3rkW5FEpHRMPPGpvNSmO1pOpqByiWscA==",
+      "version": "0.0.1107588",
+      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1107588.tgz",
+      "integrity": "sha512-yIR+pG9x65Xko7bErCUSQaDLrO/P1p3JUzEk7JCU4DowPcGHkTGUGQapcfcLc4qj0UaALwZ+cr0riFgiqpixcg==",
       "dev": true
     },
-    "node_modules/puppeteer/node_modules/ws": {
-      "version": "8.6.0",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz",
-      "integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==",
+    "node_modules/puppeteer/node_modules/puppeteer-core": {
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-19.8.0.tgz",
+      "integrity": "sha512-5gBkLR9nae7chWDhI3mpj5QA+hPmjEOW29qw5ap5g51Uo5Lxe5Yip1uyQwZSjg5Wn/eyE9grh2Lyx3m8rPK90A==",
       "dev": true,
+      "dependencies": {
+        "chromium-bidi": "0.4.5",
+        "cross-fetch": "3.1.5",
+        "debug": "4.3.4",
+        "devtools-protocol": "0.0.1107588",
+        "extract-zip": "2.0.1",
+        "https-proxy-agent": "5.0.1",
+        "proxy-from-env": "1.1.0",
+        "tar-fs": "2.1.1",
+        "unbzip2-stream": "1.4.3",
+        "ws": "8.13.0"
+      },
       "engines": {
-        "node": ">=10.0.0"
+        "node": ">=14.14.0"
       },
       "peerDependencies": {
-        "bufferutil": "^4.0.1",
-        "utf-8-validate": "^5.0.2"
+        "typescript": ">= 4.7.4"
       },
       "peerDependenciesMeta": {
-        "bufferutil": {
-          "optional": true
-        },
-        "utf-8-validate": {
+        "typescript": {
           "optional": true
         }
       }
     },
-    "node_modules/qs": {
-      "version": "6.5.3",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
-      "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.6"
-      }
+    "node_modules/querystringify": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
+      "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
+      "dev": true
     },
     "node_modules/queue-microtask": {
       "version": "1.2.3",
@@ -8027,6 +8109,94 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/read-pkg-up/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/type-fest": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg/node_modules/hosted-git-info": {
+      "version": "2.8.9",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+      "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+      "dev": true
+    },
+    "node_modules/read-pkg/node_modules/normalize-package-data": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+      "dev": true,
+      "dependencies": {
+        "hosted-git-info": "^2.1.4",
+        "resolve": "^1.10.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "node_modules/read-pkg/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
     "node_modules/read-pkg/node_modules/type-fest": {
       "version": "0.6.0",
       "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
@@ -8037,26 +8207,19 @@
       }
     },
     "node_modules/readable-stream": {
-      "version": "2.3.7",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
-      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+      "version": "3.6.2",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
       "dev": true,
       "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.3",
-        "isarray": "~1.0.0",
-        "process-nextick-args": "~2.0.0",
-        "safe-buffer": "~5.1.1",
-        "string_decoder": "~1.1.1",
-        "util-deprecate": "~1.0.1"
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
       }
     },
-    "node_modules/readable-stream/node_modules/safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-      "dev": true
-    },
     "node_modules/redent": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
@@ -8083,22 +8246,10 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/regexpp": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
-      "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/mysticatea"
-      }
-    },
     "node_modules/remove-trailing-separator": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
-      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+      "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
       "dev": true
     },
     "node_modules/repeat-element": {
@@ -8113,71 +8264,16 @@
     "node_modules/repeat-string": {
       "version": "1.6.1",
       "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
-      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+      "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
       "dev": true,
       "engines": {
         "node": ">=0.10"
       }
     },
-    "node_modules/request": {
-      "version": "2.88.2",
-      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
-      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
-      "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
-      "dev": true,
-      "dependencies": {
-        "aws-sign2": "~0.7.0",
-        "aws4": "^1.8.0",
-        "caseless": "~0.12.0",
-        "combined-stream": "~1.0.6",
-        "extend": "~3.0.2",
-        "forever-agent": "~0.6.1",
-        "form-data": "~2.3.2",
-        "har-validator": "~5.1.3",
-        "http-signature": "~1.2.0",
-        "is-typedarray": "~1.0.0",
-        "isstream": "~0.1.2",
-        "json-stringify-safe": "~5.0.1",
-        "mime-types": "~2.1.19",
-        "oauth-sign": "~0.9.0",
-        "performance-now": "^2.1.0",
-        "qs": "~6.5.2",
-        "safe-buffer": "^5.1.2",
-        "tough-cookie": "~2.5.0",
-        "tunnel-agent": "^0.6.0",
-        "uuid": "^3.3.2"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/request/node_modules/tough-cookie": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
-      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
-      "dev": true,
-      "dependencies": {
-        "psl": "^1.1.28",
-        "punycode": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
-    "node_modules/request/node_modules/uuid": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
-      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
-      "deprecated": "Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.",
-      "dev": true,
-      "bin": {
-        "uuid": "bin/uuid"
-      }
-    },
     "node_modules/require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -8189,14 +8285,24 @@
       "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
       "dev": true
     },
+    "node_modules/requires-port": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+      "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+      "dev": true
+    },
     "node_modules/resolve": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
-      "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
+      "version": "1.22.1",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+      "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
       "dev": true,
       "dependencies": {
-        "is-core-module": "^2.1.0",
-        "path-parse": "^1.0.6"
+        "is-core-module": "^2.9.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -8214,7 +8320,7 @@
         "node": ">=8"
       }
     },
-    "node_modules/resolve-from": {
+    "node_modules/resolve-cwd/node_modules/resolve-from": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
       "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
@@ -8223,10 +8329,19 @@
         "node": ">=8"
       }
     },
+    "node_modules/resolve-from": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/resolve-url": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
-      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==",
       "deprecated": "https://github.com/lydell/resolve-url#deprecated",
       "dev": true
     },
@@ -8242,7 +8357,7 @@
     "node_modules/retry": {
       "version": "0.12.0",
       "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
-      "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
+      "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
       "dev": true,
       "engines": {
         "node": ">= 4"
@@ -8274,9 +8389,9 @@
       }
     },
     "node_modules/rollup": {
-      "version": "2.38.5",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.38.5.tgz",
-      "integrity": "sha512-VoWt8DysFGDVRGWuHTqZzT02J0ASgjVq/hPs9QcBOGMd7B+jfTr/iqMVEyOi901rE3xq+Deq66GzIT1yt7sGwQ==",
+      "version": "2.79.1",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
+      "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
       "dev": true,
       "bin": {
         "rollup": "dist/bin/rollup"
@@ -8285,13 +8400,13 @@
         "node": ">=10.0.0"
       },
       "optionalDependencies": {
-        "fsevents": "~2.3.1"
+        "fsevents": "~2.3.2"
       }
     },
     "node_modules/rollup-plugin-re": {
       "version": "1.0.7",
       "resolved": "https://registry.npmjs.org/rollup-plugin-re/-/rollup-plugin-re-1.0.7.tgz",
-      "integrity": "sha1-/hdHBO1ZzahMrwK9ATtYLm/apPY=",
+      "integrity": "sha512-TyFf3QaV/eJ/50k4wp5BM0SodGy0Idq0uOgvA1q3gHRwgXLPVX5y3CRKkBuHzKTZPC9CTZX7igKw5UvgjDls8w==",
       "dev": true,
       "dependencies": {
         "magic-string": "^0.16.0",
@@ -8301,7 +8416,7 @@
     "node_modules/rollup-plugin-re/node_modules/magic-string": {
       "version": "0.16.0",
       "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.16.0.tgz",
-      "integrity": "sha1-lw67DacZMwEoX7GqZQ85vdgetFo=",
+      "integrity": "sha512-c4BEos3y6G2qO0B9X7K0FVLOPT9uGrjYwYRLFmDqyl5YMboUviyecnXWp94fJTSMwPw2/sf+CEYt5AGpmklkkQ==",
       "dev": true,
       "dependencies": {
         "vlq": "^0.2.1"
@@ -8329,17 +8444,6 @@
         }
       }
     },
-    "node_modules/rollup-plugin-sourcemaps/node_modules/source-map-resolve": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz",
-      "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==",
-      "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated",
-      "dev": true,
-      "dependencies": {
-        "atob": "^2.1.2",
-        "decode-uri-component": "^0.2.0"
-      }
-    },
     "node_modules/rollup-pluginutils": {
       "version": "2.8.2",
       "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
@@ -8391,6 +8495,7 @@
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
       "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+      "dev": true,
       "funding": [
         {
           "type": "github",
@@ -8409,7 +8514,7 @@
     "node_modules/safe-regex": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
-      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==",
       "dev": true,
       "dependencies": {
         "ret": "~0.1.10"
@@ -8479,7 +8584,7 @@
     "node_modules/sane/node_modules/braces/node_modules/extend-shallow": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
       "dev": true,
       "dependencies": {
         "is-extendable": "^0.1.0"
@@ -8488,10 +8593,44 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/sane/node_modules/cross-spawn": {
+      "version": "6.0.5",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+      "dev": true,
+      "dependencies": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      },
+      "engines": {
+        "node": ">=4.8"
+      }
+    },
+    "node_modules/sane/node_modules/execa": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^6.0.0",
+        "get-stream": "^4.0.0",
+        "is-stream": "^1.1.0",
+        "npm-run-path": "^2.0.0",
+        "p-finally": "^1.0.0",
+        "signal-exit": "^3.0.0",
+        "strip-eof": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/sane/node_modules/fill-range": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
-      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+      "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==",
       "dev": true,
       "dependencies": {
         "extend-shallow": "^2.0.1",
@@ -8506,7 +8645,7 @@
     "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
       "dev": true,
       "dependencies": {
         "is-extendable": "^0.1.0"
@@ -8515,10 +8654,31 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/sane/node_modules/get-stream": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "dev": true,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/sane/node_modules/is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/sane/node_modules/is-number": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
-      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
       "dev": true,
       "dependencies": {
         "kind-of": "^3.0.2"
@@ -8530,7 +8690,7 @@
     "node_modules/sane/node_modules/is-number/node_modules/kind-of": {
       "version": "3.2.2",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
       "dev": true,
       "dependencies": {
         "is-buffer": "^1.1.5"
@@ -8539,6 +8699,15 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/sane/node_modules/is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/sane/node_modules/micromatch": {
       "version": "3.1.10",
       "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
@@ -8566,7 +8735,7 @@
     "node_modules/sane/node_modules/normalize-path": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
-      "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+      "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==",
       "dev": true,
       "dependencies": {
         "remove-trailing-separator": "^1.0.1"
@@ -8575,10 +8744,61 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/sane/node_modules/npm-run-path": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+      "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
+      "dev": true,
+      "dependencies": {
+        "path-key": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/sane/node_modules/path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/sane/node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/sane/node_modules/shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+      "dev": true,
+      "dependencies": {
+        "shebang-regex": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sane/node_modules/shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/sane/node_modules/to-regex-range": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
-      "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+      "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==",
       "dev": true,
       "dependencies": {
         "is-number": "^3.0.0",
@@ -8588,15 +8808,27 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/sane/node_modules/which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "which": "bin/which"
+      }
+    },
     "node_modules/sass-graph": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-4.0.0.tgz",
-      "integrity": "sha512-WSO/MfXqKH7/TS8RdkCX3lVkPFQzCgbqdGsmSKq6tlPU+GpGEsa/5aW18JqItnqh+lPtcjifqdZ/VmiILkKckQ==",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-4.0.1.tgz",
+      "integrity": "sha512-5YCfmGBmxoIRYHnKK2AKzrAkCoQ8ozO+iumT8K4tXJXRVCPf+7s1/9KxTSW3Rbvf+7Y7b4FR3mWyLnQr3PHocA==",
       "dev": true,
       "dependencies": {
         "glob": "^7.0.0",
         "lodash": "^4.17.11",
-        "scss-tokenizer": "^0.3.0",
+        "scss-tokenizer": "^0.4.3",
         "yargs": "^17.2.1"
       },
       "bin": {
@@ -8607,14 +8839,17 @@
       }
     },
     "node_modules/sass-graph/node_modules/cliui": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
       "dev": true,
       "dependencies": {
         "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
+        "strip-ansi": "^6.0.1",
         "wrap-ansi": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=12"
       }
     },
     "node_modules/sass-graph/node_modules/wrap-ansi": {
@@ -8644,27 +8879,27 @@
       }
     },
     "node_modules/sass-graph/node_modules/yargs": {
-      "version": "17.5.0",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.0.tgz",
-      "integrity": "sha512-3sLxVhbAB5OC8qvVRebCLWuouhwh/rswsiDYx3WGxajUk/l4G20SKfrKKFeNIHboUFt2JFgv2yfn+5cgOr/t5A==",
+      "version": "17.7.1",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz",
+      "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
       "dev": true,
       "dependencies": {
-        "cliui": "^7.0.2",
+        "cliui": "^8.0.1",
         "escalade": "^3.1.1",
         "get-caller-file": "^2.0.5",
         "require-directory": "^2.1.1",
         "string-width": "^4.2.3",
         "y18n": "^5.0.5",
-        "yargs-parser": "^21.0.0"
+        "yargs-parser": "^21.1.1"
       },
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/sass-graph/node_modules/yargs-parser": {
-      "version": "21.0.1",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
-      "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==",
+      "version": "21.1.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
       "dev": true,
       "engines": {
         "node": ">=12"
@@ -8683,37 +8918,61 @@
       }
     },
     "node_modules/scss-tokenizer": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.3.0.tgz",
-      "integrity": "sha512-14Zl9GcbBvOT9057ZKjpz5yPOyUWG2ojd9D5io28wHRYsOrs7U95Q+KNL87+32p8rc+LvDpbu/i9ZYjM9Q+FsQ==",
+      "version": "0.4.3",
+      "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.4.3.tgz",
+      "integrity": "sha512-raKLgf1LI5QMQnG+RxHz6oK0sL3x3I4FN2UDLqgLOGO8hodECNnNh5BXn7fAyBxrA8zVzdQizQ6XjNJQ+uBwMw==",
       "dev": true,
       "dependencies": {
-        "js-base64": "^2.4.3",
-        "source-map": "^0.7.1"
+        "js-base64": "^2.4.9",
+        "source-map": "^0.7.3"
       }
     },
     "node_modules/scss-tokenizer/node_modules/source-map": {
-      "version": "0.7.3",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
-      "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+      "version": "0.7.4",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+      "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
       "dev": true,
       "engines": {
         "node": ">= 8"
       }
     },
     "node_modules/semver": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+      "version": "7.3.8",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+      "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
       "dev": true,
+      "dependencies": {
+        "lru-cache": "^6.0.0"
+      },
       "bin": {
         "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
+    "node_modules/semver/node_modules/lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "dev": true,
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/semver/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true
+    },
     "node_modules/set-blocking": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+      "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
       "dev": true
     },
     "node_modules/set-value": {
@@ -8734,7 +8993,7 @@
     "node_modules/set-value/node_modules/extend-shallow": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
       "dev": true,
       "dependencies": {
         "is-extendable": "^0.1.0"
@@ -8743,25 +9002,34 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/shebang-command": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
-      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+    "node_modules/set-value/node_modules/is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
       "dev": true,
-      "dependencies": {
-        "shebang-regex": "^1.0.0"
-      },
       "engines": {
         "node": ">=0.10.0"
       }
     },
+    "node_modules/shebang-command": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+      "dev": true,
+      "dependencies": {
+        "shebang-regex": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/shebang-regex": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
-      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
       "dev": true,
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=8"
       }
     },
     "node_modules/shellwords": {
@@ -8838,7 +9106,7 @@
     "node_modules/snapdragon-node/node_modules/define-property": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+      "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
       "dev": true,
       "dependencies": {
         "is-descriptor": "^1.0.0"
@@ -8847,44 +9115,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
-      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/snapdragon-node/node_modules/is-data-descriptor": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
-      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
-      "dev": true,
-      "dependencies": {
-        "kind-of": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/snapdragon-node/node_modules/is-descriptor": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
-      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
-      "dev": true,
-      "dependencies": {
-        "is-accessor-descriptor": "^1.0.0",
-        "is-data-descriptor": "^1.0.0",
-        "kind-of": "^6.0.2"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/snapdragon-util": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
@@ -8900,7 +9130,7 @@
     "node_modules/snapdragon-util/node_modules/kind-of": {
       "version": "3.2.2",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
       "dev": true,
       "dependencies": {
         "is-buffer": "^1.1.5"
@@ -8921,7 +9151,7 @@
     "node_modules/snapdragon/node_modules/define-property": {
       "version": "0.2.5",
       "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
       "dev": true,
       "dependencies": {
         "is-descriptor": "^0.1.0"
@@ -8933,7 +9163,7 @@
     "node_modules/snapdragon/node_modules/extend-shallow": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+      "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
       "dev": true,
       "dependencies": {
         "is-extendable": "^0.1.0"
@@ -8942,28 +9172,122 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/snapdragon/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
+    "node_modules/snapdragon/node_modules/is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "node_modules/snapdragon/node_modules/source-map": {
-      "version": "0.5.7",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+    "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon/node_modules/is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon/node_modules/is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon/node_modules/is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
-    "node_modules/socks": {
-      "version": "2.6.2",
-      "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz",
-      "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==",
+    "node_modules/snapdragon/node_modules/kind-of": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+      "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true
+    },
+    "node_modules/snapdragon/node_modules/source-map": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+      "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/snapdragon/node_modules/source-map-resolve": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+      "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+      "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated",
       "dev": true,
       "dependencies": {
-        "ip": "^1.1.5",
+        "atob": "^2.1.2",
+        "decode-uri-component": "^0.2.0",
+        "resolve-url": "^0.2.1",
+        "source-map-url": "^0.4.0",
+        "urix": "^0.1.0"
+      }
+    },
+    "node_modules/socks": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
+      "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
+      "dev": true,
+      "dependencies": {
+        "ip": "^2.0.0",
         "smart-buffer": "^4.2.0"
       },
       "engines": {
@@ -8972,9 +9296,9 @@
       }
     },
     "node_modules/socks-proxy-agent": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz",
-      "integrity": "sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ==",
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
+      "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
       "dev": true,
       "dependencies": {
         "agent-base": "^6.0.2",
@@ -8995,23 +9319,20 @@
       }
     },
     "node_modules/source-map-resolve": {
-      "version": "0.5.3",
-      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
-      "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz",
+      "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==",
       "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated",
       "dev": true,
       "dependencies": {
         "atob": "^2.1.2",
-        "decode-uri-component": "^0.2.0",
-        "resolve-url": "^0.2.1",
-        "source-map-url": "^0.4.0",
-        "urix": "^0.1.0"
+        "decode-uri-component": "^0.2.0"
       }
     },
     "node_modules/source-map-support": {
-      "version": "0.5.19",
-      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
-      "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+      "version": "0.5.21",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
       "dev": true,
       "dependencies": {
         "buffer-from": "^1.0.0",
@@ -9025,16 +9346,10 @@
       "deprecated": "See https://github.com/lydell/source-map-url#deprecated",
       "dev": true
     },
-    "node_modules/sourcemap-codec": {
-      "version": "1.4.8",
-      "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
-      "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
-      "dev": true
-    },
     "node_modules/spdx-correct": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
-      "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
+      "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
       "dev": true,
       "dependencies": {
         "spdx-expression-parse": "^3.0.0",
@@ -9058,9 +9373,9 @@
       }
     },
     "node_modules/spdx-license-ids": {
-      "version": "3.0.7",
-      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz",
-      "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==",
+      "version": "3.0.13",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz",
+      "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==",
       "dev": true
     },
     "node_modules/split-string": {
@@ -9078,34 +9393,9 @@
     "node_modules/sprintf-js": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
       "dev": true
     },
-    "node_modules/sshpk": {
-      "version": "1.17.0",
-      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
-      "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
-      "dev": true,
-      "dependencies": {
-        "asn1": "~0.2.3",
-        "assert-plus": "^1.0.0",
-        "bcrypt-pbkdf": "^1.0.0",
-        "dashdash": "^1.12.0",
-        "ecc-jsbn": "~0.1.1",
-        "getpass": "^0.1.1",
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.0.2",
-        "tweetnacl": "~0.14.0"
-      },
-      "bin": {
-        "sshpk-conv": "bin/sshpk-conv",
-        "sshpk-sign": "bin/sshpk-sign",
-        "sshpk-verify": "bin/sshpk-verify"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/ssri": {
       "version": "8.0.1",
       "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
@@ -9119,9 +9409,9 @@
       }
     },
     "node_modules/stack-utils": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz",
-      "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==",
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+      "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
       "dev": true,
       "dependencies": {
         "escape-string-regexp": "^2.0.0"
@@ -9142,7 +9432,7 @@
     "node_modules/static-extend": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
-      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+      "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==",
       "dev": true,
       "dependencies": {
         "define-property": "^0.2.5",
@@ -9155,7 +9445,7 @@
     "node_modules/static-extend/node_modules/define-property": {
       "version": "0.2.5",
       "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+      "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
       "dev": true,
       "dependencies": {
         "is-descriptor": "^0.1.0"
@@ -9164,6 +9454,77 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/static-extend/node_modules/is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/static-extend/node_modules/is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+      "dev": true,
+      "dependencies": {
+        "is-buffer": "^1.1.5"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/static-extend/node_modules/is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "dependencies": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/static-extend/node_modules/kind-of": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+      "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/stdout-stream": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
@@ -9173,7 +9534,28 @@
         "readable-stream": "^2.0.1"
       }
     },
-    "node_modules/string_decoder": {
+    "node_modules/stdout-stream/node_modules/readable-stream": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+      "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      }
+    },
+    "node_modules/stdout-stream/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+      "dev": true
+    },
+    "node_modules/stdout-stream/node_modules/string_decoder": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
       "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
@@ -9182,11 +9564,14 @@
         "safe-buffer": "~5.1.0"
       }
     },
-    "node_modules/string_decoder/node_modules/safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-      "dev": true
+    "node_modules/string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "~5.2.0"
+      }
     },
     "node_modules/string-length": {
       "version": "4.0.2",
@@ -9215,30 +9600,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/string.prototype.trimend": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz",
-      "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==",
-      "dependencies": {
-        "call-bind": "^1.0.0",
-        "define-properties": "^1.1.3"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/string.prototype.trimstart": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz",
-      "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==",
-      "dependencies": {
-        "call-bind": "^1.0.0",
-        "define-properties": "^1.1.3"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/strip-ansi": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -9263,7 +9624,7 @@
     "node_modules/strip-eof": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
-      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+      "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -9315,9 +9676,9 @@
       }
     },
     "node_modules/supports-hyperlinks": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz",
-      "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz",
+      "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==",
       "dev": true,
       "dependencies": {
         "has-flag": "^4.0.0",
@@ -9327,6 +9688,18 @@
         "node": ">=8"
       }
     },
+    "node_modules/supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/symbol-tree": {
       "version": "3.2.4",
       "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
@@ -9334,20 +9707,20 @@
       "dev": true
     },
     "node_modules/tar": {
-      "version": "6.1.11",
-      "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
-      "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
+      "version": "6.1.13",
+      "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz",
+      "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==",
       "dev": true,
       "dependencies": {
         "chownr": "^2.0.0",
         "fs-minipass": "^2.0.0",
-        "minipass": "^3.0.0",
+        "minipass": "^4.0.0",
         "minizlib": "^2.1.1",
         "mkdirp": "^1.0.3",
         "yallist": "^4.0.0"
       },
       "engines": {
-        "node": ">= 10"
+        "node": ">=10"
       }
     },
     "node_modules/tar-fs": {
@@ -9362,6 +9735,12 @@
         "tar-stream": "^2.1.4"
       }
     },
+    "node_modules/tar-fs/node_modules/chownr": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+      "dev": true
+    },
     "node_modules/tar-stream": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
@@ -9378,40 +9757,20 @@
         "node": ">=6"
       }
     },
-    "node_modules/tar-stream/node_modules/readable-stream": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+    "node_modules/tar/node_modules/minipass": {
+      "version": "4.2.5",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz",
+      "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==",
       "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
-      },
       "engines": {
-        "node": ">= 6"
+        "node": ">=8"
       }
     },
-    "node_modules/tar/node_modules/chownr": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
-      "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/tar/node_modules/mkdirp": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
-      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
-      "dev": true,
-      "bin": {
-        "mkdirp": "bin/cmd.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
+    "node_modules/tar/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true
     },
     "node_modules/terminal-link": {
       "version": "2.1.1",
@@ -9446,7 +9805,7 @@
     "node_modules/text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
-      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+      "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
       "dev": true
     },
     "node_modules/throat": {
@@ -9458,7 +9817,7 @@
     "node_modules/through": {
       "version": "2.3.8",
       "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
       "dev": true
     },
     "node_modules/tmpl": {
@@ -9470,7 +9829,7 @@
     "node_modules/to-fast-properties": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
-      "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+      "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
       "dev": true,
       "engines": {
         "node": ">=4"
@@ -9479,7 +9838,7 @@
     "node_modules/to-object-path": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
-      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+      "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==",
       "dev": true,
       "dependencies": {
         "kind-of": "^3.0.2"
@@ -9491,7 +9850,7 @@
     "node_modules/to-object-path/node_modules/kind-of": {
       "version": "3.2.2",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
       "dev": true,
       "dependencies": {
         "is-buffer": "^1.1.5"
@@ -9527,31 +9886,11 @@
         "node": ">=8.0"
       }
     },
-    "node_modules/tough-cookie": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
-      "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
-      "dev": true,
-      "dependencies": {
-        "psl": "^1.1.33",
-        "punycode": "^2.1.1",
-        "universalify": "^0.1.2"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
     "node_modules/tr46": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
-      "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
-      "dev": true,
-      "dependencies": {
-        "punycode": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+      "dev": true
     },
     "node_modules/trim-newlines": {
       "version": "3.0.1",
@@ -9563,45 +9902,24 @@
       }
     },
     "node_modules/true-case-path": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
-      "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
-      "dev": true,
-      "dependencies": {
-        "glob": "^7.1.2"
-      }
-    },
-    "node_modules/tslib": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz",
-      "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==",
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz",
+      "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==",
       "dev": true
     },
-    "node_modules/tunnel-agent": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "^5.0.1"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/tweetnacl": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+    "node_modules/tslib": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
+      "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==",
       "dev": true
     },
     "node_modules/type-check": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
-      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+      "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
       "dev": true,
       "dependencies": {
-        "prelude-ls": "~1.1.2"
+        "prelude-ls": "^1.2.1"
       },
       "engines": {
         "node": ">= 0.8.0"
@@ -9617,12 +9935,15 @@
       }
     },
     "node_modules/type-fest": {
-      "version": "0.8.1",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
-      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
       "dev": true,
       "engines": {
-        "node": ">=8"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/typedarray-to-buffer": {
@@ -9635,9 +9956,9 @@
       }
     },
     "node_modules/typescript": {
-      "version": "4.6.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz",
-      "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==",
+      "version": "4.9.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
+      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
       "dev": true,
       "bin": {
         "tsc": "bin/tsc",
@@ -9672,6 +9993,15 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/union-value/node_modules/is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/unique-filename": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
@@ -9691,9 +10021,9 @@
       }
     },
     "node_modules/universalify": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
-      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
+      "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
       "dev": true,
       "engines": {
         "node": ">= 4.0.0"
@@ -9702,7 +10032,7 @@
     "node_modules/unset-value": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
-      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==",
       "dev": true,
       "dependencies": {
         "has-value": "^0.3.1",
@@ -9715,7 +10045,7 @@
     "node_modules/unset-value/node_modules/has-value": {
       "version": "0.3.1",
       "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
-      "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+      "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==",
       "dev": true,
       "dependencies": {
         "get-value": "^2.0.3",
@@ -9729,7 +10059,7 @@
     "node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
-      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+      "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==",
       "dev": true,
       "dependencies": {
         "isarray": "1.0.0"
@@ -9741,12 +10071,38 @@
     "node_modules/unset-value/node_modules/has-values": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
-      "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+      "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
+    "node_modules/update-browserslist-db": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
+      "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        }
+      ],
+      "dependencies": {
+        "escalade": "^3.1.1",
+        "picocolors": "^1.0.0"
+      },
+      "bin": {
+        "browserslist-lint": "cli.js"
+      },
+      "peerDependencies": {
+        "browserslist": ">= 4.21.0"
+      }
+    },
     "node_modules/uri-js": {
       "version": "4.4.1",
       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -9759,10 +10115,20 @@
     "node_modules/urix": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
-      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==",
       "deprecated": "Please see https://github.com/lydell/urix#deprecated",
       "dev": true
     },
+    "node_modules/url-parse": {
+      "version": "1.5.10",
+      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
+      "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
+      "dev": true,
+      "dependencies": {
+        "querystringify": "^2.1.1",
+        "requires-port": "^1.0.0"
+      }
+    },
     "node_modules/use": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
@@ -9773,38 +10139,31 @@
       }
     },
     "node_modules/util": {
-      "version": "0.12.3",
-      "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz",
-      "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==",
+      "version": "0.12.5",
+      "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
+      "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
       "dependencies": {
         "inherits": "^2.0.3",
         "is-arguments": "^1.0.4",
         "is-generator-function": "^1.0.7",
         "is-typed-array": "^1.1.3",
-        "safe-buffer": "^5.1.2",
         "which-typed-array": "^1.1.2"
       }
     },
     "node_modules/util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
       "dev": true
     },
     "node_modules/uuid": {
-      "version": "8.3.2",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
-      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
+      "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
       "bin": {
         "uuid": "dist/bin/uuid"
       }
     },
-    "node_modules/v8-compile-cache": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
-      "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
-      "dev": true
-    },
     "node_modules/v8-to-istanbul": {
       "version": "7.1.2",
       "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz",
@@ -9820,9 +10179,9 @@
       }
     },
     "node_modules/v8-to-istanbul/node_modules/source-map": {
-      "version": "0.7.3",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
-      "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+      "version": "0.7.4",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+      "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
       "dev": true,
       "engines": {
         "node": ">= 8"
@@ -9838,20 +10197,6 @@
         "spdx-expression-parse": "^3.0.0"
       }
     },
-    "node_modules/verror": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
-      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
-      "dev": true,
-      "engines": [
-        "node >=0.6.0"
-      ],
-      "dependencies": {
-        "assert-plus": "^1.0.0",
-        "core-util-is": "1.0.2",
-        "extsprintf": "^1.2.0"
-      }
-    },
     "node_modules/vlq": {
       "version": "0.2.3",
       "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz",
@@ -9862,6 +10207,7 @@
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
       "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
+      "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.",
       "dev": true,
       "dependencies": {
         "browser-process-hrtime": "^1.0.0"
@@ -9880,22 +10226,19 @@
       }
     },
     "node_modules/walker": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz",
-      "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=",
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
+      "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
       "dev": true,
       "dependencies": {
-        "makeerror": "1.0.x"
+        "makeerror": "1.0.12"
       }
     },
     "node_modules/webidl-conversions": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
-      "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
-      "dev": true,
-      "engines": {
-        "node": ">=10.4"
-      }
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+      "dev": true
     },
     "node_modules/whatwg-encoding": {
       "version": "1.0.5",
@@ -9906,6 +10249,18 @@
         "iconv-lite": "0.4.24"
       }
     },
+    "node_modules/whatwg-encoding/node_modules/iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/whatwg-mimetype": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
@@ -9913,49 +10268,47 @@
       "dev": true
     },
     "node_modules/whatwg-url": {
-      "version": "8.5.0",
-      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.5.0.tgz",
-      "integrity": "sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
       "dev": true,
       "dependencies": {
-        "lodash": "^4.7.0",
-        "tr46": "^2.0.2",
-        "webidl-conversions": "^6.1.0"
-      },
-      "engines": {
-        "node": ">=10"
+        "tr46": "~0.0.3",
+        "webidl-conversions": "^3.0.0"
       }
     },
     "node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
       "dev": true,
       "dependencies": {
         "isexe": "^2.0.0"
       },
       "bin": {
-        "which": "bin/which"
+        "node-which": "bin/node-which"
+      },
+      "engines": {
+        "node": ">= 8"
       }
     },
     "node_modules/which-module": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
-      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+      "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==",
       "dev": true
     },
     "node_modules/which-typed-array": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz",
-      "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==",
+      "version": "1.1.9",
+      "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
+      "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==",
       "dependencies": {
-        "available-typed-arrays": "^1.0.2",
-        "call-bind": "^1.0.0",
-        "es-abstract": "^1.18.0-next.1",
-        "foreach": "^2.0.5",
-        "function-bind": "^1.1.1",
-        "has-symbols": "^1.0.1",
-        "is-typed-array": "^1.1.3"
+        "available-typed-arrays": "^1.0.5",
+        "call-bind": "^1.0.2",
+        "for-each": "^0.3.3",
+        "gopd": "^1.0.1",
+        "has-tostringtag": "^1.0.0",
+        "is-typed-array": "^1.1.10"
       },
       "engines": {
         "node": ">= 0.4"
@@ -9999,7 +10352,7 @@
     "node_modules/wrappy": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
     },
     "node_modules/write-file-atomic": {
       "version": "3.0.3",
@@ -10014,16 +10367,16 @@
       }
     },
     "node_modules/ws": {
-      "version": "7.4.6",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
-      "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
+      "version": "8.13.0",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
+      "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==",
       "dev": true,
       "engines": {
-        "node": ">=8.3.0"
+        "node": ">=10.0.0"
       },
       "peerDependencies": {
         "bufferutil": "^4.0.1",
-        "utf-8-validate": "^5.0.2"
+        "utf-8-validate": ">=5.0.2"
       },
       "peerDependenciesMeta": {
         "bufferutil": {
@@ -10047,15 +10400,15 @@
       "dev": true
     },
     "node_modules/y18n": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
-      "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+      "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
       "dev": true
     },
     "node_modules/yallist": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
       "dev": true
     },
     "node_modules/yargs": {
@@ -10081,6 +10434,67 @@
       }
     },
     "node_modules/yargs-parser": {
+      "version": "20.2.9",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/yargs/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/yargs/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/yargs/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/yargs/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/yargs/node_modules/yargs-parser": {
       "version": "18.1.3",
       "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
       "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
@@ -10096,234 +10510,243 @@
     "node_modules/yauzl": {
       "version": "2.10.0",
       "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
-      "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
+      "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
       "dev": true,
       "dependencies": {
         "buffer-crc32": "~0.2.3",
         "fd-slicer": "~1.1.0"
       }
     },
+    "node_modules/yocto-queue": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "src/base/utils": {
       "name": "custom_utils",
-      "version": "0.0.1",
-      "integrity": "sha1-3AufWZiBOAkOPn+w8VkAwJ7lslY="
+      "version": "0.0.1"
     }
   },
   "dependencies": {
-    "@babel/code-frame": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
-      "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+    "@ampproject/remapping": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+      "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
       "dev": true,
       "requires": {
-        "@babel/highlight": "^7.12.13"
+        "@jridgewell/gen-mapping": "^0.1.0",
+        "@jridgewell/trace-mapping": "^0.3.9"
+      }
+    },
+    "@babel/code-frame": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+      "dev": true,
+      "requires": {
+        "@babel/highlight": "^7.18.6"
       }
     },
     "@babel/compat-data": {
-      "version": "7.14.4",
-      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.4.tgz",
-      "integrity": "sha512-i2wXrWQNkH6JplJQGn3Rd2I4Pij8GdHkXwHMxm+zV5YG/Jci+bCNrWZEWC4o+umiDkRrRs4dVzH3X4GP7vyjQQ==",
+      "version": "7.21.0",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz",
+      "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==",
       "dev": true
     },
     "@babel/core": {
-      "version": "7.14.3",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.3.tgz",
-      "integrity": "sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg==",
+      "version": "7.21.3",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.3.tgz",
+      "integrity": "sha512-qIJONzoa/qiHghnm0l1n4i/6IIziDpzqc36FBs4pzMhDUraHqponwJLiAKm1hGLP3OSB/TVNz6rMwVGpwxxySw==",
       "dev": true,
       "requires": {
-        "@babel/code-frame": "^7.12.13",
-        "@babel/generator": "^7.14.3",
-        "@babel/helper-compilation-targets": "^7.13.16",
-        "@babel/helper-module-transforms": "^7.14.2",
-        "@babel/helpers": "^7.14.0",
-        "@babel/parser": "^7.14.3",
-        "@babel/template": "^7.12.13",
-        "@babel/traverse": "^7.14.2",
-        "@babel/types": "^7.14.2",
+        "@ampproject/remapping": "^2.2.0",
+        "@babel/code-frame": "^7.18.6",
+        "@babel/generator": "^7.21.3",
+        "@babel/helper-compilation-targets": "^7.20.7",
+        "@babel/helper-module-transforms": "^7.21.2",
+        "@babel/helpers": "^7.21.0",
+        "@babel/parser": "^7.21.3",
+        "@babel/template": "^7.20.7",
+        "@babel/traverse": "^7.21.3",
+        "@babel/types": "^7.21.3",
         "convert-source-map": "^1.7.0",
         "debug": "^4.1.0",
         "gensync": "^1.0.0-beta.2",
-        "json5": "^2.1.2",
-        "semver": "^6.3.0",
-        "source-map": "^0.5.0"
+        "json5": "^2.2.2",
+        "semver": "^6.3.0"
       },
       "dependencies": {
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
           "dev": true
         }
       }
     },
     "@babel/generator": {
-      "version": "7.14.3",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz",
-      "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==",
+      "version": "7.21.3",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.3.tgz",
+      "integrity": "sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.14.2",
-        "jsesc": "^2.5.1",
-        "source-map": "^0.5.0"
+        "@babel/types": "^7.21.3",
+        "@jridgewell/gen-mapping": "^0.3.2",
+        "@jridgewell/trace-mapping": "^0.3.17",
+        "jsesc": "^2.5.1"
       },
       "dependencies": {
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
+        "@jridgewell/gen-mapping": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+          "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+          "dev": true,
+          "requires": {
+            "@jridgewell/set-array": "^1.0.1",
+            "@jridgewell/sourcemap-codec": "^1.4.10",
+            "@jridgewell/trace-mapping": "^0.3.9"
+          }
         }
       }
     },
     "@babel/helper-compilation-targets": {
-      "version": "7.14.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.4.tgz",
-      "integrity": "sha512-JgdzOYZ/qGaKTVkn5qEDV/SXAh8KcyUVkCoSWGN8T3bwrgd6m+/dJa2kVGi6RJYJgEYPBdZ84BZp9dUjNWkBaA==",
+      "version": "7.20.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz",
+      "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==",
       "dev": true,
       "requires": {
-        "@babel/compat-data": "^7.14.4",
-        "@babel/helper-validator-option": "^7.12.17",
-        "browserslist": "^4.16.6",
+        "@babel/compat-data": "^7.20.5",
+        "@babel/helper-validator-option": "^7.18.6",
+        "browserslist": "^4.21.3",
+        "lru-cache": "^5.1.1",
         "semver": "^6.3.0"
-      }
-    },
-    "@babel/helper-function-name": {
-      "version": "7.14.2",
-      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz",
-      "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-get-function-arity": "^7.12.13",
-        "@babel/template": "^7.12.13",
-        "@babel/types": "^7.14.2"
-      }
-    },
-    "@babel/helper-get-function-arity": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
-      "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.12.13"
-      }
-    },
-    "@babel/helper-member-expression-to-functions": {
-      "version": "7.13.12",
-      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz",
-      "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.13.12"
-      }
-    },
-    "@babel/helper-module-imports": {
-      "version": "7.13.12",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz",
-      "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.13.12"
-      }
-    },
-    "@babel/helper-module-transforms": {
-      "version": "7.14.2",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz",
-      "integrity": "sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-imports": "^7.13.12",
-        "@babel/helper-replace-supers": "^7.13.12",
-        "@babel/helper-simple-access": "^7.13.12",
-        "@babel/helper-split-export-declaration": "^7.12.13",
-        "@babel/helper-validator-identifier": "^7.14.0",
-        "@babel/template": "^7.12.13",
-        "@babel/traverse": "^7.14.2",
-        "@babel/types": "^7.14.2"
       },
       "dependencies": {
-        "@babel/helper-validator-identifier": {
-          "version": "7.14.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
-          "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
           "dev": true
         }
       }
     },
-    "@babel/helper-optimise-call-expression": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz",
-      "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==",
+    "@babel/helper-environment-visitor": {
+      "version": "7.18.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
+      "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
+      "dev": true
+    },
+    "@babel/helper-function-name": {
+      "version": "7.21.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz",
+      "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.12.13"
+        "@babel/template": "^7.20.7",
+        "@babel/types": "^7.21.0"
+      }
+    },
+    "@babel/helper-hoist-variables": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
+      "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.18.6"
+      }
+    },
+    "@babel/helper-module-imports": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz",
+      "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.18.6"
+      }
+    },
+    "@babel/helper-module-transforms": {
+      "version": "7.21.2",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz",
+      "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-environment-visitor": "^7.18.9",
+        "@babel/helper-module-imports": "^7.18.6",
+        "@babel/helper-simple-access": "^7.20.2",
+        "@babel/helper-split-export-declaration": "^7.18.6",
+        "@babel/helper-validator-identifier": "^7.19.1",
+        "@babel/template": "^7.20.7",
+        "@babel/traverse": "^7.21.2",
+        "@babel/types": "^7.21.2"
       }
     },
     "@babel/helper-plugin-utils": {
-      "version": "7.13.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz",
-      "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==",
+      "version": "7.20.2",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
+      "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==",
       "dev": true
     },
-    "@babel/helper-replace-supers": {
-      "version": "7.14.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.4.tgz",
-      "integrity": "sha512-zZ7uHCWlxfEAAOVDYQpEf/uyi1dmeC7fX4nCf2iz9drnCwi1zvwXL3HwWWNXUQEJ1k23yVn3VbddiI9iJEXaTQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-member-expression-to-functions": "^7.13.12",
-        "@babel/helper-optimise-call-expression": "^7.12.13",
-        "@babel/traverse": "^7.14.2",
-        "@babel/types": "^7.14.4"
-      }
-    },
     "@babel/helper-simple-access": {
-      "version": "7.13.12",
-      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz",
-      "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==",
+      "version": "7.20.2",
+      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
+      "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.13.12"
+        "@babel/types": "^7.20.2"
       }
     },
     "@babel/helper-split-export-declaration": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz",
-      "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
+      "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.12.13"
+        "@babel/types": "^7.18.6"
       }
     },
+    "@babel/helper-string-parser": {
+      "version": "7.19.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
+      "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
+      "dev": true
+    },
     "@babel/helper-validator-identifier": {
-      "version": "7.12.11",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
-      "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==",
+      "version": "7.19.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+      "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
       "dev": true
     },
     "@babel/helper-validator-option": {
-      "version": "7.12.17",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz",
-      "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==",
+      "version": "7.21.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz",
+      "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==",
       "dev": true
     },
     "@babel/helpers": {
-      "version": "7.14.0",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz",
-      "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==",
+      "version": "7.21.0",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz",
+      "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==",
       "dev": true,
       "requires": {
-        "@babel/template": "^7.12.13",
-        "@babel/traverse": "^7.14.0",
-        "@babel/types": "^7.14.0"
+        "@babel/template": "^7.20.7",
+        "@babel/traverse": "^7.21.0",
+        "@babel/types": "^7.21.0"
       }
     },
     "@babel/highlight": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz",
-      "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
       "dev": true,
       "requires": {
-        "@babel/helper-validator-identifier": "^7.12.11",
+        "@babel/helper-validator-identifier": "^7.18.6",
         "chalk": "^2.0.0",
         "js-tokens": "^4.0.0"
       },
@@ -10360,13 +10783,19 @@
         "color-name": {
           "version": "1.1.3",
           "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+          "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+          "dev": true
+        },
+        "escape-string-regexp": {
+          "version": "1.0.5",
+          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+          "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
           "dev": true
         },
         "has-flag": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
           "dev": true
         },
         "supports-color": {
@@ -10381,9 +10810,9 @@
       }
     },
     "@babel/parser": {
-      "version": "7.14.4",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz",
-      "integrity": "sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==",
+      "version": "7.21.3",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.3.tgz",
+      "integrity": "sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==",
       "dev": true
     },
     "@babel/plugin-syntax-async-generators": {
@@ -10486,57 +10915,60 @@
       }
     },
     "@babel/plugin-syntax-top-level-await": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz",
-      "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==",
+      "version": "7.14.5",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+      "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.12.13"
+        "@babel/helper-plugin-utils": "^7.14.5"
       }
     },
     "@babel/template": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
-      "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
+      "version": "7.20.7",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz",
+      "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==",
       "dev": true,
       "requires": {
-        "@babel/code-frame": "^7.12.13",
-        "@babel/parser": "^7.12.13",
-        "@babel/types": "^7.12.13"
+        "@babel/code-frame": "^7.18.6",
+        "@babel/parser": "^7.20.7",
+        "@babel/types": "^7.20.7"
       }
     },
     "@babel/traverse": {
-      "version": "7.14.2",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz",
-      "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==",
+      "version": "7.21.3",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.3.tgz",
+      "integrity": "sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==",
       "dev": true,
       "requires": {
-        "@babel/code-frame": "^7.12.13",
-        "@babel/generator": "^7.14.2",
-        "@babel/helper-function-name": "^7.14.2",
-        "@babel/helper-split-export-declaration": "^7.12.13",
-        "@babel/parser": "^7.14.2",
-        "@babel/types": "^7.14.2",
+        "@babel/code-frame": "^7.18.6",
+        "@babel/generator": "^7.21.3",
+        "@babel/helper-environment-visitor": "^7.18.9",
+        "@babel/helper-function-name": "^7.21.0",
+        "@babel/helper-hoist-variables": "^7.18.6",
+        "@babel/helper-split-export-declaration": "^7.18.6",
+        "@babel/parser": "^7.21.3",
+        "@babel/types": "^7.21.3",
         "debug": "^4.1.0",
         "globals": "^11.1.0"
+      },
+      "dependencies": {
+        "globals": {
+          "version": "11.12.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+          "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+          "dev": true
+        }
       }
     },
     "@babel/types": {
-      "version": "7.14.4",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
-      "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+      "version": "7.21.3",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.3.tgz",
+      "integrity": "sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==",
       "dev": true,
       "requires": {
-        "@babel/helper-validator-identifier": "^7.14.0",
+        "@babel/helper-string-parser": "^7.19.4",
+        "@babel/helper-validator-identifier": "^7.19.1",
         "to-fast-properties": "^2.0.0"
-      },
-      "dependencies": {
-        "@babel/helper-validator-identifier": {
-          "version": "7.14.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
-          "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
-          "dev": true
-        }
       }
     },
     "@bcoe/v8-coverage": {
@@ -10556,75 +10988,55 @@
       }
     },
     "@esbuild/android-arm": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.12.tgz",
-      "integrity": "sha512-IC7TqIqiyE0MmvAhWkl/8AEzpOtbhRNDo7aph47We1NbE5w2bt/Q+giAhe0YYeVpYnIhGMcuZY92qDK6dQauvA==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.18.tgz",
+      "integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==",
       "optional": true
     },
     "@esbuild/linux-loong64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.12.tgz",
-      "integrity": "sha512-tZEowDjvU7O7I04GYvWQOS4yyP9E/7YlsB0jjw1Ycukgr2ycEzKyIk5tms5WnLBymaewc6VmRKnn5IJWgK4eFw==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz",
+      "integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==",
       "optional": true
     },
+    "@eslint-community/eslint-utils": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+      "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+      "dev": true,
+      "requires": {
+        "eslint-visitor-keys": "^3.3.0"
+      }
+    },
+    "@eslint-community/regexpp": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.1.tgz",
+      "integrity": "sha512-BISJ6ZE4xQsuL/FmsyRaiffpq977bMlsKfGHTQrOGFErfByxIe6iZTxPf/00Zon9b9a7iUykfQwejN3s2ZW/Bw==",
+      "dev": true
+    },
     "@eslint/eslintrc": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz",
-      "integrity": "sha512-uGo44hIwoLGNyduRpjdEpovcbMdd+Nv7amtmJxnKmI8xj6yd5LncmSwDa5NgX/41lIFJtkjD6YdVfgEzPfJ5UA==",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz",
+      "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==",
       "dev": true,
       "requires": {
         "ajv": "^6.12.4",
         "debug": "^4.3.2",
-        "espree": "^9.3.2",
-        "globals": "^13.9.0",
+        "espree": "^9.5.0",
+        "globals": "^13.19.0",
         "ignore": "^5.2.0",
         "import-fresh": "^3.2.1",
         "js-yaml": "^4.1.0",
         "minimatch": "^3.1.2",
         "strip-json-comments": "^3.1.1"
-      },
-      "dependencies": {
-        "argparse": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
-          "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
-          "dev": true
-        },
-        "globals": {
-          "version": "13.15.0",
-          "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz",
-          "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==",
-          "dev": true,
-          "requires": {
-            "type-fest": "^0.20.2"
-          }
-        },
-        "js-yaml": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
-          "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
-          "dev": true,
-          "requires": {
-            "argparse": "^2.0.1"
-          }
-        },
-        "minimatch": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-          "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        },
-        "type-fest": {
-          "version": "0.20.2",
-          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
-          "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
-          "dev": true
-        }
       }
     },
+    "@eslint/js": {
+      "version": "8.36.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz",
+      "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==",
+      "dev": true
+    },
     "@gar/promisify": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
@@ -10632,16 +11044,22 @@
       "dev": true
     },
     "@humanwhocodes/config-array": {
-      "version": "0.9.5",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
-      "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
+      "version": "0.11.8",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
+      "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==",
       "dev": true,
       "requires": {
         "@humanwhocodes/object-schema": "^1.2.1",
         "debug": "^4.1.1",
-        "minimatch": "^3.0.4"
+        "minimatch": "^3.0.5"
       }
     },
+    "@humanwhocodes/module-importer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+      "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+      "dev": true
+    },
     "@humanwhocodes/object-schema": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
@@ -10659,6 +11077,70 @@
         "get-package-type": "^0.1.0",
         "js-yaml": "^3.13.1",
         "resolve-from": "^5.0.0"
+      },
+      "dependencies": {
+        "argparse": {
+          "version": "1.0.10",
+          "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+          "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+          "dev": true,
+          "requires": {
+            "sprintf-js": "~1.0.2"
+          }
+        },
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "js-yaml": {
+          "version": "3.14.1",
+          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+          "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+          "dev": true,
+          "requires": {
+            "argparse": "^1.0.7",
+            "esprima": "^4.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "resolve-from": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+          "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+          "dev": true
+        }
       }
     },
     "@istanbuljs/schema": {
@@ -10715,6 +11197,34 @@
         "rimraf": "^3.0.0",
         "slash": "^3.0.0",
         "strip-ansi": "^6.0.0"
+      },
+      "dependencies": {
+        "jest-config": {
+          "version": "26.6.3",
+          "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz",
+          "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==",
+          "dev": true,
+          "requires": {
+            "@babel/core": "^7.1.0",
+            "@jest/test-sequencer": "^26.6.3",
+            "@jest/types": "^26.6.2",
+            "babel-jest": "^26.6.3",
+            "chalk": "^4.0.0",
+            "deepmerge": "^4.2.2",
+            "glob": "^7.1.1",
+            "graceful-fs": "^4.2.4",
+            "jest-environment-jsdom": "^26.6.2",
+            "jest-environment-node": "^26.6.2",
+            "jest-get-type": "^26.3.0",
+            "jest-jasmine2": "^26.6.3",
+            "jest-regex-util": "^26.0.0",
+            "jest-resolve": "^26.6.2",
+            "jest-util": "^26.6.2",
+            "jest-validate": "^26.6.2",
+            "micromatch": "^4.0.2",
+            "pretty-format": "^26.6.2"
+          }
+        }
       }
     },
     "@jest/environment": {
@@ -10859,6 +11369,44 @@
         "chalk": "^4.0.0"
       }
     },
+    "@jridgewell/gen-mapping": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+      "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+      "dev": true,
+      "requires": {
+        "@jridgewell/set-array": "^1.0.0",
+        "@jridgewell/sourcemap-codec": "^1.4.10"
+      }
+    },
+    "@jridgewell/resolve-uri": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+      "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+      "dev": true
+    },
+    "@jridgewell/set-array": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+      "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+      "dev": true
+    },
+    "@jridgewell/sourcemap-codec": {
+      "version": "1.4.14",
+      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+      "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+      "dev": true
+    },
+    "@jridgewell/trace-mapping": {
+      "version": "0.3.17",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+      "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+      "dev": true,
+      "requires": {
+        "@jridgewell/resolve-uri": "3.1.0",
+        "@jridgewell/sourcemap-codec": "1.4.14"
+      }
+    },
     "@nodelib/fs.scandir": {
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -10893,17 +11441,6 @@
       "requires": {
         "@gar/promisify": "^1.0.1",
         "semver": "^7.3.5"
-      },
-      "dependencies": {
-        "semver": {
-          "version": "7.3.7",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
-          "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
-          "dev": true,
-          "requires": {
-            "lru-cache": "^6.0.0"
-          }
-        }
       }
     },
     "@npmcli/move-file": {
@@ -10914,25 +11451,17 @@
       "requires": {
         "mkdirp": "^1.0.4",
         "rimraf": "^3.0.2"
-      },
-      "dependencies": {
-        "mkdirp": {
-          "version": "1.0.4",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
-          "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
-          "dev": true
-        }
       }
     },
     "@popperjs/core": {
-      "version": "2.11.6",
-      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
-      "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw=="
+      "version": "2.11.7",
+      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz",
+      "integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw=="
     },
     "@protobufjs/aspromise": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
-      "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78="
+      "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
     },
     "@protobufjs/base64": {
       "version": "1.1.2",
@@ -10947,12 +11476,12 @@
     "@protobufjs/eventemitter": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
-      "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A="
+      "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
     },
     "@protobufjs/fetch": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
-      "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=",
+      "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
       "requires": {
         "@protobufjs/aspromise": "^1.1.1",
         "@protobufjs/inquire": "^1.1.0"
@@ -10961,56 +11490,135 @@
     "@protobufjs/float": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
-      "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E="
+      "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
     },
     "@protobufjs/inquire": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
-      "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik="
+      "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
     },
     "@protobufjs/path": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
-      "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0="
+      "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
     },
     "@protobufjs/pool": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
-      "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q="
+      "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
     },
     "@protobufjs/utf8": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
-      "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
+      "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
     },
     "@rollup/plugin-commonjs": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-14.0.0.tgz",
-      "integrity": "sha512-+PSmD9ePwTAeU106i9FRdc+Zb3XUWyW26mo5Atr2mk82hor8+nPwkztEjFo8/B1fJKfaQDg9aM2bzQkjhi7zOw==",
+      "version": "24.0.1",
+      "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.1.tgz",
+      "integrity": "sha512-15LsiWRZk4eOGqvrJyu3z3DaBu5BhXIMeWnijSRvd8irrrg9SHpQ1pH+BUK4H6Z9wL9yOxZJMTLU+Au86XHxow==",
       "dev": true,
       "requires": {
-        "@rollup/pluginutils": "^3.0.8",
+        "@rollup/pluginutils": "^5.0.1",
         "commondir": "^1.0.1",
-        "estree-walker": "^1.0.1",
-        "glob": "^7.1.2",
-        "is-reference": "^1.1.2",
-        "magic-string": "^0.25.2",
-        "resolve": "^1.11.0"
+        "estree-walker": "^2.0.2",
+        "glob": "^8.0.3",
+        "is-reference": "1.2.1",
+        "magic-string": "^0.27.0"
+      },
+      "dependencies": {
+        "@rollup/pluginutils": {
+          "version": "5.0.2",
+          "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
+          "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
+          "dev": true,
+          "requires": {
+            "@types/estree": "^1.0.0",
+            "estree-walker": "^2.0.2",
+            "picomatch": "^2.3.1"
+          }
+        },
+        "@types/estree": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
+          "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==",
+          "dev": true
+        },
+        "brace-expansion": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+          "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+          "dev": true,
+          "requires": {
+            "balanced-match": "^1.0.0"
+          }
+        },
+        "estree-walker": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+          "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+          "dev": true
+        },
+        "glob": {
+          "version": "8.1.0",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+          "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^5.0.1",
+            "once": "^1.3.0"
+          }
+        },
+        "minimatch": {
+          "version": "5.1.6",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+          "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^2.0.1"
+          }
+        }
       }
     },
     "@rollup/plugin-node-resolve": {
-      "version": "8.4.0",
-      "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-8.4.0.tgz",
-      "integrity": "sha512-LFqKdRLn0ShtQyf6SBYO69bGE1upV6wUhBX0vFOUnLAyzx5cwp8svA0eHUnu8+YU57XOkrMtfG63QOpQx25pHQ==",
+      "version": "15.0.1",
+      "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz",
+      "integrity": "sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg==",
       "dev": true,
       "requires": {
-        "@rollup/pluginutils": "^3.1.0",
-        "@types/resolve": "1.17.1",
-        "builtin-modules": "^3.1.0",
-        "deep-freeze": "^0.0.1",
+        "@rollup/pluginutils": "^5.0.1",
+        "@types/resolve": "1.20.2",
         "deepmerge": "^4.2.2",
+        "is-builtin-module": "^3.2.0",
         "is-module": "^1.0.0",
-        "resolve": "^1.17.0"
+        "resolve": "^1.22.1"
+      },
+      "dependencies": {
+        "@rollup/pluginutils": {
+          "version": "5.0.2",
+          "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
+          "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
+          "dev": true,
+          "requires": {
+            "@types/estree": "^1.0.0",
+            "estree-walker": "^2.0.2",
+            "picomatch": "^2.3.1"
+          }
+        },
+        "@types/estree": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
+          "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==",
+          "dev": true
+        },
+        "estree-walker": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+          "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+          "dev": true
+        }
       }
     },
     "@rollup/pluginutils": {
@@ -11025,9 +11633,9 @@
       }
     },
     "@sinonjs/commons": {
-      "version": "1.8.3",
-      "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
-      "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==",
+      "version": "1.8.6",
+      "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
+      "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==",
       "dev": true,
       "requires": {
         "type-detect": "4.0.8"
@@ -11049,31 +11657,31 @@
       "dev": true
     },
     "@types/babel__core": {
-      "version": "7.1.14",
-      "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz",
-      "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==",
+      "version": "7.20.0",
+      "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz",
+      "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==",
       "dev": true,
       "requires": {
-        "@babel/parser": "^7.1.0",
-        "@babel/types": "^7.0.0",
+        "@babel/parser": "^7.20.7",
+        "@babel/types": "^7.20.7",
         "@types/babel__generator": "*",
         "@types/babel__template": "*",
         "@types/babel__traverse": "*"
       }
     },
     "@types/babel__generator": {
-      "version": "7.6.2",
-      "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz",
-      "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==",
+      "version": "7.6.4",
+      "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz",
+      "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==",
       "dev": true,
       "requires": {
         "@babel/types": "^7.0.0"
       }
     },
     "@types/babel__template": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz",
-      "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==",
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
+      "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==",
       "dev": true,
       "requires": {
         "@babel/parser": "^7.1.0",
@@ -11081,9 +11689,9 @@
       }
     },
     "@types/babel__traverse": {
-      "version": "7.11.1",
-      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.1.tgz",
-      "integrity": "sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==",
+      "version": "7.18.3",
+      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz",
+      "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==",
       "dev": true,
       "requires": {
         "@babel/types": "^7.3.0"
@@ -11126,28 +11734,28 @@
       }
     },
     "@types/filewriter": {
-      "version": "0.0.28",
-      "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.28.tgz",
-      "integrity": "sha1-wFTor02d11205jq8dviFFocU1LM="
+      "version": "0.0.29",
+      "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.29.tgz",
+      "integrity": "sha512-BsPXH/irW0ht0Ji6iw/jJaK8Lj3FJemon2gvEqHKpCdDCeemHa+rI3WBGq5z7cDMZgoLjY40oninGxqk+8NzNQ=="
     },
     "@types/graceful-fs": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
-      "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==",
+      "version": "4.1.6",
+      "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz",
+      "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==",
       "dev": true,
       "requires": {
         "@types/node": "*"
       }
     },
     "@types/har-format": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.8.tgz",
-      "integrity": "sha512-OP6L9VuZNdskgNN3zFQQ54ceYD8OLq5IbqO4VK91ORLfOm7WdT/CiT/pHEBSQEqCInJ2y3O6iCm/zGtPElpgJQ=="
+      "version": "1.2.10",
+      "resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.10.tgz",
+      "integrity": "sha512-o0J30wqycjF5miWDKYKKzzOU1ZTLuA42HZ4HE7/zqTOc/jTLdQ5NhYWvsRQo45Nfi1KHoRdNhteSI4BAxTF1Pg=="
     },
     "@types/istanbul-lib-coverage": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
-      "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==",
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
+      "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
       "dev": true
     },
     "@types/istanbul-lib-report": {
@@ -11169,9 +11777,9 @@
       }
     },
     "@types/jest": {
-      "version": "26.0.23",
-      "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz",
-      "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==",
+      "version": "26.0.24",
+      "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.24.tgz",
+      "integrity": "sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==",
       "dev": true,
       "requires": {
         "jest-diff": "^26.0.0",
@@ -11185,9 +11793,9 @@
       "dev": true
     },
     "@types/long": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
-      "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
+      "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="
     },
     "@types/minimist": {
       "version": "1.2.2",
@@ -11196,30 +11804,30 @@
       "dev": true
     },
     "@types/mithril": {
-      "version": "2.0.11",
-      "resolved": "https://registry.npmjs.org/@types/mithril/-/mithril-2.0.11.tgz",
-      "integrity": "sha512-2tYTImXc7RzWkPpgcbnSKpV46DQI4Bm8CfgmkrIbst8MJlX6d8hdgy2yQCEf5NZYLGNyK4xbzb4rr8VPmk0iXQ=="
+      "version": "2.0.12",
+      "resolved": "https://registry.npmjs.org/@types/mithril/-/mithril-2.0.12.tgz",
+      "integrity": "sha512-vedzt04n3EB7rcnfSLCv3+w3qJLkGWdsNRBKvelTqhSJSfg73Roq9b+rcnn9zeqGYtQAMqNcO6vNBR/w0OzipQ=="
     },
     "@types/node": {
-      "version": "14.14.25",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.25.tgz",
-      "integrity": "sha512-EPpXLOVqDvisVxtlbvzfyqSsFeQxltFbluZNRndIb8tr9KiBnYNLzrc1N3pyKUCww2RNrfHDViqDWWE1LCJQtQ=="
+      "version": "14.18.41",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.41.tgz",
+      "integrity": "sha512-2cfHr8AsUjKx6u4Q+d2eqK51z8+HueoumCQGCKVt95y/yGG4uajOuCANSnE20mbLw94h3tMcddIJ8nYkTu2mFw=="
     },
     "@types/normalize-package-data": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
-      "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
+      "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
       "dev": true
     },
     "@types/pako": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.1.tgz",
-      "integrity": "sha512-GdZbRSJ3Cv5fiwT6I0SQ3ckeN2PWNqxd26W9Z2fCK1tGrrasGy4puvNFtnddqH9UJFMQYXxEuuB7B8UK+LLwSg=="
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.4.tgz",
+      "integrity": "sha512-Z+5bJSm28EXBSUJEgx29ioWeEEHUh6TiMkZHDhLwjc9wVFH+ressbkmX6waUZc5R3Gobn4Qu5llGxaoflZ+yhA=="
     },
     "@types/pixelmatch": {
-      "version": "5.2.3",
-      "resolved": "https://registry.npmjs.org/@types/pixelmatch/-/pixelmatch-5.2.3.tgz",
-      "integrity": "sha512-p+nAQVYK/DUx7+s1Xyu9dqAg0gobf7VmJ+iDA4lljg1o4XRgQHr7R2h1NwFt3gdNOZiftxWB11+0TuZqXYf19w==",
+      "version": "5.2.4",
+      "resolved": "https://registry.npmjs.org/@types/pixelmatch/-/pixelmatch-5.2.4.tgz",
+      "integrity": "sha512-HDaSHIAv9kwpMN7zlmwfTv6gax0PiporJOipcrGsVNF3Ba+kryOZc0Pio5pn6NhisgWr7TaajlPEKTbTAypIBQ==",
       "dev": true,
       "requires": {
         "@types/node": "*"
@@ -11234,33 +11842,27 @@
       }
     },
     "@types/prettier": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz",
-      "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==",
+      "version": "2.7.2",
+      "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz",
+      "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==",
       "dev": true
     },
-    "@types/puppeteer": {
-      "version": "5.4.6",
-      "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.6.tgz",
-      "integrity": "sha512-98Kghehs7+/GD9b56qryhqdqVCXUTbetTv3PlvDnmFRTHQH0j9DIp1f7rkAW3BAj4U3yoeSEQnKgdW8bDq0Y0Q==",
-      "dev": true,
-      "requires": {
-        "@types/node": "*"
-      }
-    },
     "@types/resolve": {
-      "version": "1.17.1",
-      "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
-      "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==",
-      "dev": true,
-      "requires": {
-        "@types/node": "*"
-      }
+      "version": "1.20.2",
+      "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
+      "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
+      "dev": true
+    },
+    "@types/semver": {
+      "version": "7.3.13",
+      "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
+      "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
+      "dev": true
     },
     "@types/stack-utils": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz",
-      "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
+      "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
       "dev": true
     },
     "@types/uuid": {
@@ -11269,29 +11871,29 @@
       "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw=="
     },
     "@types/w3c-web-usb": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.4.tgz",
-      "integrity": "sha512-aaOB3EL5WCWBBOYX7W1MKuzspOM9ZJI9s3iziRVypr1N+QyvIgXzCM4lm1iiOQ1VFzZioUPX9bsa23myCbKK4A=="
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.6.tgz",
+      "integrity": "sha512-cSjhgrr8g4KbPnnijAr/KJDNKa/bBa+ixYkywFRvrhvi9n1WEl7yYbtRyzE6jqNQiSxxJxoAW3STaOQwJHndaw=="
     },
     "@types/yargs": {
-      "version": "15.0.13",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz",
-      "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==",
+      "version": "15.0.15",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.15.tgz",
+      "integrity": "sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg==",
       "dev": true,
       "requires": {
         "@types/yargs-parser": "*"
       }
     },
     "@types/yargs-parser": {
-      "version": "20.2.0",
-      "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz",
-      "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==",
+      "version": "21.0.0",
+      "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
+      "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
       "dev": true
     },
     "@types/yauzl": {
-      "version": "2.9.1",
-      "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz",
-      "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==",
+      "version": "2.10.0",
+      "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz",
+      "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==",
       "dev": true,
       "optional": true,
       "requires": {
@@ -11299,31 +11901,23 @@
       }
     },
     "@typescript-eslint/eslint-plugin": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.25.0.tgz",
-      "integrity": "sha512-icYrFnUzvm+LhW0QeJNKkezBu6tJs9p/53dpPLFH8zoM9w1tfaKzVurkPotEpAqQ8Vf8uaFyL5jHd0Vs6Z0ZQg==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.56.0.tgz",
+      "integrity": "sha512-ZNW37Ccl3oMZkzxrYDUX4o7cnuPgU+YrcaYXzsRtLB16I1FR5SHMqga3zGsaSliZADCWo2v8qHWqAYIj8nWCCg==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/scope-manager": "5.25.0",
-        "@typescript-eslint/type-utils": "5.25.0",
-        "@typescript-eslint/utils": "5.25.0",
+        "@eslint-community/regexpp": "^4.4.0",
+        "@typescript-eslint/scope-manager": "5.56.0",
+        "@typescript-eslint/type-utils": "5.56.0",
+        "@typescript-eslint/utils": "5.56.0",
         "debug": "^4.3.4",
-        "functional-red-black-tree": "^1.0.1",
+        "grapheme-splitter": "^1.0.4",
         "ignore": "^5.2.0",
-        "regexpp": "^3.2.0",
+        "natural-compare-lite": "^1.4.0",
         "semver": "^7.3.7",
         "tsutils": "^3.21.0"
       },
       "dependencies": {
-        "semver": {
-          "version": "7.3.7",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
-          "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
-          "dev": true,
-          "requires": {
-            "lru-cache": "^6.0.0"
-          }
-        },
         "tslib": {
           "version": "1.14.1",
           "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@@ -11342,34 +11936,35 @@
       }
     },
     "@typescript-eslint/parser": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.25.0.tgz",
-      "integrity": "sha512-r3hwrOWYbNKP1nTcIw/aZoH+8bBnh/Lh1iDHoFpyG4DnCpvEdctrSl6LOo19fZbzypjQMHdajolxs6VpYoChgA==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.56.0.tgz",
+      "integrity": "sha512-sn1OZmBxUsgxMmR8a8U5QM/Wl+tyqlH//jTqCg8daTAmhAk26L2PFhcqPLlYBhYUJMZJK276qLXlHN3a83o2cg==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/scope-manager": "5.25.0",
-        "@typescript-eslint/types": "5.25.0",
-        "@typescript-eslint/typescript-estree": "5.25.0",
+        "@typescript-eslint/scope-manager": "5.56.0",
+        "@typescript-eslint/types": "5.56.0",
+        "@typescript-eslint/typescript-estree": "5.56.0",
         "debug": "^4.3.4"
       }
     },
     "@typescript-eslint/scope-manager": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.25.0.tgz",
-      "integrity": "sha512-p4SKTFWj+2VpreUZ5xMQsBMDdQ9XdRvODKXN4EksyBjFp2YvQdLkyHqOffakYZPuWJUDNu3jVXtHALDyTv3cww==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.56.0.tgz",
+      "integrity": "sha512-jGYKyt+iBakD0SA5Ww8vFqGpoV2asSjwt60Gl6YcO8ksQ8s2HlUEyHBMSa38bdLopYqGf7EYQMUIGdT/Luw+sw==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "5.25.0",
-        "@typescript-eslint/visitor-keys": "5.25.0"
+        "@typescript-eslint/types": "5.56.0",
+        "@typescript-eslint/visitor-keys": "5.56.0"
       }
     },
     "@typescript-eslint/type-utils": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.25.0.tgz",
-      "integrity": "sha512-B6nb3GK3Gv1Rsb2pqalebe/RyQoyG/WDy9yhj8EE0Ikds4Xa8RR28nHz+wlt4tMZk5bnAr0f3oC8TuDAd5CPrw==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.56.0.tgz",
+      "integrity": "sha512-8WxgOgJjWRy6m4xg9KoSHPzBNZeQbGlQOH7l2QEhQID/+YseaFxg5J/DLwWSsi9Axj4e/cCiKx7PVzOq38tY4A==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/utils": "5.25.0",
+        "@typescript-eslint/typescript-estree": "5.56.0",
+        "@typescript-eslint/utils": "5.56.0",
         "debug": "^4.3.4",
         "tsutils": "^3.21.0"
       },
@@ -11392,19 +11987,19 @@
       }
     },
     "@typescript-eslint/types": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.25.0.tgz",
-      "integrity": "sha512-7fWqfxr0KNHj75PFqlGX24gWjdV/FDBABXL5dyvBOWHpACGyveok8Uj4ipPX/1fGU63fBkzSIycEje4XsOxUFA==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.56.0.tgz",
+      "integrity": "sha512-JyAzbTJcIyhuUhogmiu+t79AkdnqgPUEsxMTMc/dCZczGMJQh1MK2wgrju++yMN6AWroVAy2jxyPcPr3SWCq5w==",
       "dev": true
     },
     "@typescript-eslint/typescript-estree": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.25.0.tgz",
-      "integrity": "sha512-MrPODKDych/oWs/71LCnuO7NyR681HuBly2uLnX3r5i4ME7q/yBqC4hW33kmxtuauLTM0OuBOhhkFaxCCOjEEw==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.56.0.tgz",
+      "integrity": "sha512-41CH/GncsLXOJi0jb74SnC7jVPWeVJ0pxQj8bOjH1h2O26jXN3YHKDT1ejkVz5YeTEQPeLCCRY0U2r68tfNOcg==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "5.25.0",
-        "@typescript-eslint/visitor-keys": "5.25.0",
+        "@typescript-eslint/types": "5.56.0",
+        "@typescript-eslint/visitor-keys": "5.56.0",
         "debug": "^4.3.4",
         "globby": "^11.1.0",
         "is-glob": "^4.0.3",
@@ -11412,15 +12007,6 @@
         "tsutils": "^3.21.0"
       },
       "dependencies": {
-        "semver": {
-          "version": "7.3.7",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
-          "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
-          "dev": true,
-          "requires": {
-            "lru-cache": "^6.0.0"
-          }
-        },
         "tslib": {
           "version": "1.14.1",
           "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@@ -11439,51 +12025,35 @@
       }
     },
     "@typescript-eslint/utils": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.25.0.tgz",
-      "integrity": "sha512-qNC9bhnz/n9Kba3yI6HQgQdBLuxDoMgdjzdhSInZh6NaDnFpTUlwNGxplUFWfY260Ya0TRPvkg9dd57qxrJI9g==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.56.0.tgz",
+      "integrity": "sha512-XhZDVdLnUJNtbzaJeDSCIYaM+Tgr59gZGbFuELgF7m0IY03PlciidS7UQNKLE0+WpUTn1GlycEr6Ivb/afjbhA==",
       "dev": true,
       "requires": {
+        "@eslint-community/eslint-utils": "^4.2.0",
         "@types/json-schema": "^7.0.9",
-        "@typescript-eslint/scope-manager": "5.25.0",
-        "@typescript-eslint/types": "5.25.0",
-        "@typescript-eslint/typescript-estree": "5.25.0",
+        "@types/semver": "^7.3.12",
+        "@typescript-eslint/scope-manager": "5.56.0",
+        "@typescript-eslint/types": "5.56.0",
+        "@typescript-eslint/typescript-estree": "5.56.0",
         "eslint-scope": "^5.1.1",
-        "eslint-utils": "^3.0.0"
-      },
-      "dependencies": {
-        "eslint-scope": {
-          "version": "5.1.1",
-          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
-          "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
-          "dev": true,
-          "requires": {
-            "esrecurse": "^4.3.0",
-            "estraverse": "^4.1.1"
-          }
-        },
-        "estraverse": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
-          "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
-          "dev": true
-        }
+        "semver": "^7.3.7"
       }
     },
     "@typescript-eslint/visitor-keys": {
-      "version": "5.25.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.25.0.tgz",
-      "integrity": "sha512-yd26vFgMsC4h2dgX4+LR+GeicSKIfUvZREFLf3DDjZPtqgLx5AJZr6TetMNwFP9hcKreTTeztQYBTNbNoOycwA==",
+      "version": "5.56.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.56.0.tgz",
+      "integrity": "sha512-1mFdED7u5bZpX6Xxf5N9U2c18sb+8EvU3tyOIj6LQZ5OOvnmj8BVeNNP603OFPm5KkS1a7IvCIcwrdHXaEMG/Q==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "5.25.0",
+        "@typescript-eslint/types": "5.56.0",
         "eslint-visitor-keys": "^3.3.0"
       }
     },
     "abab": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
-      "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==",
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
+      "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==",
       "dev": true
     },
     "abbrev": {
@@ -11493,9 +12063,9 @@
       "dev": true
     },
     "acorn": {
-      "version": "8.7.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
-      "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+      "version": "8.8.2",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
+      "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
       "dev": true
     },
     "acorn-globals": {
@@ -11539,13 +12109,13 @@
       }
     },
     "agentkeepalive": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz",
-      "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==",
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz",
+      "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==",
       "dev": true,
       "requires": {
         "debug": "^4.1.0",
-        "depd": "^1.1.2",
+        "depd": "^2.0.0",
         "humanize-ms": "^1.2.1"
       }
     },
@@ -11604,9 +12174,9 @@
       }
     },
     "anymatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
-      "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
       "dev": true,
       "requires": {
         "normalize-path": "^3.0.0",
@@ -11619,42 +12189,16 @@
       "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
       "dev": true
     },
-    "are-we-there-yet": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
-      "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
-      "dev": true,
-      "requires": {
-        "delegates": "^1.0.0",
-        "readable-stream": "^3.6.0"
-      },
-      "dependencies": {
-        "readable-stream": {
-          "version": "3.6.0",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
-          "dev": true,
-          "requires": {
-            "inherits": "^2.0.3",
-            "string_decoder": "^1.1.1",
-            "util-deprecate": "^1.0.1"
-          }
-        }
-      }
-    },
     "argparse": {
-      "version": "1.0.10",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
-      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
-      "dev": true,
-      "requires": {
-        "sprintf-js": "~1.0.2"
-      }
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+      "dev": true
     },
     "arr-diff": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
-      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==",
       "dev": true
     },
     "arr-flatten": {
@@ -11666,14 +12210,9 @@
     "arr-union": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
-      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==",
       "dev": true
     },
-    "array-filter": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz",
-      "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM="
-    },
     "array-union": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@@ -11683,46 +12222,31 @@
     "array-unique": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
-      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+      "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==",
       "dev": true
     },
     "arrify": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
-      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
-      "dev": true
-    },
-    "asn1": {
-      "version": "0.2.6",
-      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
-      "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
-      "dev": true,
-      "requires": {
-        "safer-buffer": "~2.1.0"
-      }
-    },
-    "assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
       "dev": true
     },
     "assign-symbols": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
-      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==",
       "dev": true
     },
     "async-foreach": {
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
-      "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
+      "integrity": "sha512-VUeSMD8nEGBWaZK4lizI1sf3yEC7pnAQ/mrI7pC2fBz2s/tq5jWWEngTwaf0Gruu/OoXRGLGg1XFqpYBiGTYJA==",
       "dev": true
     },
     "asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
       "dev": true
     },
     "atob": {
@@ -11732,24 +12256,9 @@
       "dev": true
     },
     "available-typed-arrays": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz",
-      "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==",
-      "requires": {
-        "array-filter": "^1.0.0"
-      }
-    },
-    "aws-sign2": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
-      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
-      "dev": true
-    },
-    "aws4": {
-      "version": "1.11.0",
-      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
-      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
-      "dev": true
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+      "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
     },
     "babel-jest": {
       "version": "26.6.3",
@@ -11768,16 +12277,37 @@
       }
     },
     "babel-plugin-istanbul": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz",
-      "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==",
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
+      "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
       "dev": true,
       "requires": {
         "@babel/helper-plugin-utils": "^7.0.0",
         "@istanbuljs/load-nyc-config": "^1.0.0",
         "@istanbuljs/schema": "^0.1.2",
-        "istanbul-lib-instrument": "^4.0.0",
+        "istanbul-lib-instrument": "^5.0.4",
         "test-exclude": "^6.0.0"
+      },
+      "dependencies": {
+        "istanbul-lib-instrument": {
+          "version": "5.2.1",
+          "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
+          "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
+          "dev": true,
+          "requires": {
+            "@babel/core": "^7.12.3",
+            "@babel/parser": "^7.14.7",
+            "@istanbuljs/schema": "^0.1.2",
+            "istanbul-lib-coverage": "^3.2.0",
+            "semver": "^6.3.0"
+          }
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
       }
     },
     "babel-plugin-jest-hoist": {
@@ -11823,9 +12353,9 @@
       }
     },
     "balanced-match": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
     },
     "base": {
       "version": "0.11.2",
@@ -11845,40 +12375,11 @@
         "define-property": {
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
           "dev": true,
           "requires": {
             "is-descriptor": "^1.0.0"
           }
-        },
-        "is-accessor-descriptor": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
-          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
-          "dev": true,
-          "requires": {
-            "kind-of": "^6.0.0"
-          }
-        },
-        "is-data-descriptor": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
-          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
-          "dev": true,
-          "requires": {
-            "kind-of": "^6.0.0"
-          }
-        },
-        "is-descriptor": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
-          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
-          "dev": true,
-          "requires": {
-            "is-accessor-descriptor": "^1.0.0",
-            "is-data-descriptor": "^1.0.0",
-            "kind-of": "^6.0.2"
-          }
         }
       }
     },
@@ -11888,15 +12389,6 @@
       "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
       "dev": true
     },
-    "bcrypt-pbkdf": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
-      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
-      "dev": true,
-      "requires": {
-        "tweetnacl": "^0.14.3"
-      }
-    },
     "bl": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
@@ -11906,19 +12398,6 @@
         "buffer": "^5.5.0",
         "inherits": "^2.0.4",
         "readable-stream": "^3.4.0"
-      },
-      "dependencies": {
-        "readable-stream": {
-          "version": "3.6.0",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
-          "dev": true,
-          "requires": {
-            "inherits": "^2.0.3",
-            "string_decoder": "^1.1.1",
-            "util-deprecate": "^1.0.1"
-          }
-        }
       }
     },
     "brace-expansion": {
@@ -11946,16 +12425,15 @@
       "dev": true
     },
     "browserslist": {
-      "version": "4.16.6",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
-      "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
+      "version": "4.21.5",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
+      "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==",
       "dev": true,
       "requires": {
-        "caniuse-lite": "^1.0.30001219",
-        "colorette": "^1.2.2",
-        "electron-to-chromium": "^1.3.723",
-        "escalade": "^3.1.1",
-        "node-releases": "^1.1.71"
+        "caniuse-lite": "^1.0.30001449",
+        "electron-to-chromium": "^1.4.284",
+        "node-releases": "^2.0.8",
+        "update-browserslist-db": "^1.0.10"
       }
     },
     "bser": {
@@ -11980,19 +12458,19 @@
     "buffer-crc32": {
       "version": "0.2.13",
       "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
-      "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+      "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
       "dev": true
     },
     "buffer-from": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
-      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
       "dev": true
     },
     "builtin-modules": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz",
-      "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==",
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
+      "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
       "dev": true
     },
     "cacache": {
@@ -12021,16 +12499,19 @@
         "unique-filename": "^1.1.1"
       },
       "dependencies": {
-        "chownr": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
-          "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
-          "dev": true
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "dev": true,
+          "requires": {
+            "yallist": "^4.0.0"
+          }
         },
-        "mkdirp": {
-          "version": "1.0.4",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
-          "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
           "dev": true
         }
       }
@@ -12085,9 +12566,9 @@
       }
     },
     "caniuse-lite": {
-      "version": "1.0.30001233",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001233.tgz",
-      "integrity": "sha512-BmkbxLfStqiPA7IEzQpIk0UFZFf3A4E6fzjPJ6OR+bFC2L8ES9J8zGA/asoi47p8XDVkev+WJo2I2Nc8c/34Yg==",
+      "version": "1.0.30001470",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001470.tgz",
+      "integrity": "sha512-065uNwY6QtHCBOExzbV6m236DDhYCCtPmQUCoQtwkVqzud8v5QPidoMr6CoMkC2nfp6nksjttqWQRRh75LqUmA==",
       "dev": true
     },
     "capture-exit": {
@@ -12099,12 +12580,6 @@
         "rsvp": "^4.8.4"
       }
     },
-    "caseless": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
-      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
-      "dev": true
-    },
     "chalk": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -12122,9 +12597,9 @@
       "dev": true
     },
     "chownr": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
-      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+      "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
       "dev": true
     },
     "ci-info": {
@@ -12154,11 +12629,68 @@
         "define-property": {
           "version": "0.2.5",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
           "dev": true,
           "requires": {
             "is-descriptor": "^0.1.0"
           }
+        },
+        "is-accessor-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+          "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+              "dev": true,
+              "requires": {
+                "is-buffer": "^1.1.5"
+              }
+            }
+          }
+        },
+        "is-data-descriptor": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+          "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+              "dev": true,
+              "requires": {
+                "is-buffer": "^1.1.5"
+              }
+            }
+          }
+        },
+        "is-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^0.1.6",
+            "is-data-descriptor": "^0.1.4",
+            "kind-of": "^5.0.0"
+          }
+        },
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
         }
       }
     },
@@ -12182,7 +12714,7 @@
     "co": {
       "version": "4.6.0",
       "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
-      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+      "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
       "dev": true
     },
     "collect-v8-coverage": {
@@ -12194,7 +12726,7 @@
     "collection-visit": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
-      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==",
       "dev": true,
       "requires": {
         "map-visit": "^1.0.0",
@@ -12220,12 +12752,6 @@
       "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
       "dev": true
     },
-    "colorette": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
-      "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
-      "dev": true
-    },
     "combined-stream": {
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -12238,7 +12764,7 @@
     "commondir": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
-      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
       "dev": true
     },
     "component-emitter": {
@@ -12250,43 +12776,44 @@
     "concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
     },
     "console-control-strings": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
-      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+      "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
       "dev": true
     },
     "convert-source-map": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
-      "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
-      "dev": true,
-      "requires": {
-        "safe-buffer": "~5.1.1"
-      },
-      "dependencies": {
-        "safe-buffer": {
-          "version": "5.1.2",
-          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-          "dev": true
-        }
-      }
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+      "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+      "dev": true
     },
     "copy-descriptor": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
-      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==",
       "dev": true
     },
     "core-util-is": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
-      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
       "dev": true
     },
+    "cosmiconfig": {
+      "version": "8.1.3",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz",
+      "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==",
+      "dev": true,
+      "requires": {
+        "import-fresh": "^3.2.1",
+        "js-yaml": "^4.1.0",
+        "parse-json": "^5.0.0",
+        "path-type": "^4.0.0"
+      }
+    },
     "cross-fetch": {
       "version": "3.1.5",
       "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
@@ -12297,24 +12824,14 @@
       }
     },
     "cross-spawn": {
-      "version": "6.0.5",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
-      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
       "dev": true,
       "requires": {
-        "nice-try": "^1.0.4",
-        "path-key": "^2.0.1",
-        "semver": "^5.5.0",
-        "shebang-command": "^1.2.0",
-        "which": "^1.2.9"
-      },
-      "dependencies": {
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-          "dev": true
-        }
+        "path-key": "^3.1.0",
+        "shebang-command": "^2.0.0",
+        "which": "^2.0.1"
       }
     },
     "cssom": {
@@ -12343,15 +12860,6 @@
     "custom_utils": {
       "version": "file:src/base/utils"
     },
-    "dashdash": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "^1.0.0"
-      }
-    },
     "data-urls": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz",
@@ -12361,6 +12869,34 @@
         "abab": "^2.0.3",
         "whatwg-mimetype": "^2.3.0",
         "whatwg-url": "^8.0.0"
+      },
+      "dependencies": {
+        "tr46": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
+          "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
+          "dev": true,
+          "requires": {
+            "punycode": "^2.1.1"
+          }
+        },
+        "webidl-conversions": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
+          "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
+          "dev": true
+        },
+        "whatwg-url": {
+          "version": "8.7.0",
+          "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz",
+          "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==",
+          "dev": true,
+          "requires": {
+            "lodash": "^4.7.0",
+            "tr46": "^2.1.0",
+            "webidl-conversions": "^6.1.0"
+          }
+        }
       }
     },
     "debug": {
@@ -12375,13 +12911,13 @@
     "decamelize": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
-      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
       "dev": true
     },
     "decamelize-keys": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz",
-      "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=",
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
+      "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
       "dev": true,
       "requires": {
         "decamelize": "^1.1.0",
@@ -12391,49 +12927,35 @@
         "map-obj": {
           "version": "1.0.1",
           "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
-          "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+          "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
           "dev": true
         }
       }
     },
     "decimal.js": {
-      "version": "10.2.1",
-      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz",
-      "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==",
+      "version": "10.4.3",
+      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
+      "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==",
       "dev": true
     },
     "decode-uri-component": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
-      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
-      "dev": true
-    },
-    "deep-freeze": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/deep-freeze/-/deep-freeze-0.0.1.tgz",
-      "integrity": "sha1-OgsABd4YZygZ39OM0x+RF5yJPoQ=",
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
+      "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
       "dev": true
     },
     "deep-is": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
-      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
       "dev": true
     },
     "deepmerge": {
-      "version": "4.2.2",
-      "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
-      "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+      "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
       "dev": true
     },
-    "define-properties": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
-      "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
-      "requires": {
-        "object-keys": "^1.0.12"
-      }
-    },
     "define-property": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
@@ -12442,55 +12964,24 @@
       "requires": {
         "is-descriptor": "^1.0.2",
         "isobject": "^3.0.1"
-      },
-      "dependencies": {
-        "is-accessor-descriptor": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
-          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
-          "dev": true,
-          "requires": {
-            "kind-of": "^6.0.0"
-          }
-        },
-        "is-data-descriptor": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
-          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
-          "dev": true,
-          "requires": {
-            "kind-of": "^6.0.0"
-          }
-        },
-        "is-descriptor": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
-          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
-          "dev": true,
-          "requires": {
-            "is-accessor-descriptor": "^1.0.0",
-            "is-data-descriptor": "^1.0.0",
-            "kind-of": "^6.0.2"
-          }
-        }
       }
     },
     "delayed-stream": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
       "dev": true
     },
     "delegates": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
-      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+      "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
       "dev": true
     },
     "depd": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
-      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
       "dev": true
     },
     "detect-newline": {
@@ -12551,20 +13042,10 @@
         }
       }
     },
-    "ecc-jsbn": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
-      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
-      "dev": true,
-      "requires": {
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.1.0"
-      }
-    },
     "electron-to-chromium": {
-      "version": "1.3.747",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.747.tgz",
-      "integrity": "sha512-+K1vnBc08GNYxCWwdRe9o3Ml30DhsNyK/qIl/NE1Dic+qCy9ZREcqGNiV4jiLiAdALK1DUG3pakJHGkJUd9QQw==",
+      "version": "1.4.340",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.340.tgz",
+      "integrity": "sha512-zx8hqumOqltKsv/MF50yvdAlPF9S/4PXbyfzJS6ZGhbddGkRegdwImmfSVqCkEziYzrIGZ/TlrzBND4FysfkDg==",
       "dev": true
     },
     "emittery": {
@@ -12587,18 +13068,6 @@
       "optional": true,
       "requires": {
         "iconv-lite": "^0.6.2"
-      },
-      "dependencies": {
-        "iconv-lite": {
-          "version": "0.6.3",
-          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
-          "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "safer-buffer": ">= 2.1.2 < 3.0.0"
-          }
-        }
       }
     },
     "end-of-stream": {
@@ -12631,184 +13100,153 @@
         "is-arrayish": "^0.2.1"
       }
     },
-    "es-abstract": {
-      "version": "1.18.0-next.2",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz",
-      "integrity": "sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==",
-      "requires": {
-        "call-bind": "^1.0.2",
-        "es-to-primitive": "^1.2.1",
-        "function-bind": "^1.1.1",
-        "get-intrinsic": "^1.0.2",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.1",
-        "is-callable": "^1.2.2",
-        "is-negative-zero": "^2.0.1",
-        "is-regex": "^1.1.1",
-        "object-inspect": "^1.9.0",
-        "object-keys": "^1.1.1",
-        "object.assign": "^4.1.2",
-        "string.prototype.trimend": "^1.0.3",
-        "string.prototype.trimstart": "^1.0.3"
-      }
-    },
-    "es-to-primitive": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
-      "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
-      "requires": {
-        "is-callable": "^1.1.4",
-        "is-date-object": "^1.0.1",
-        "is-symbol": "^1.0.2"
-      }
-    },
     "esbuild": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.12.tgz",
-      "integrity": "sha512-PcT+/wyDqJQsRVhaE9uX/Oq4XLrFh0ce/bs2TJh4CSaw9xuvI+xFrH2nAYOADbhQjUgAhNWC5LKoUsakm4dxng==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.18.tgz",
+      "integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==",
       "requires": {
-        "@esbuild/android-arm": "0.15.12",
-        "@esbuild/linux-loong64": "0.15.12",
-        "esbuild-android-64": "0.15.12",
-        "esbuild-android-arm64": "0.15.12",
-        "esbuild-darwin-64": "0.15.12",
-        "esbuild-darwin-arm64": "0.15.12",
-        "esbuild-freebsd-64": "0.15.12",
-        "esbuild-freebsd-arm64": "0.15.12",
-        "esbuild-linux-32": "0.15.12",
-        "esbuild-linux-64": "0.15.12",
-        "esbuild-linux-arm": "0.15.12",
-        "esbuild-linux-arm64": "0.15.12",
-        "esbuild-linux-mips64le": "0.15.12",
-        "esbuild-linux-ppc64le": "0.15.12",
-        "esbuild-linux-riscv64": "0.15.12",
-        "esbuild-linux-s390x": "0.15.12",
-        "esbuild-netbsd-64": "0.15.12",
-        "esbuild-openbsd-64": "0.15.12",
-        "esbuild-sunos-64": "0.15.12",
-        "esbuild-windows-32": "0.15.12",
-        "esbuild-windows-64": "0.15.12",
-        "esbuild-windows-arm64": "0.15.12"
+        "@esbuild/android-arm": "0.15.18",
+        "@esbuild/linux-loong64": "0.15.18",
+        "esbuild-android-64": "0.15.18",
+        "esbuild-android-arm64": "0.15.18",
+        "esbuild-darwin-64": "0.15.18",
+        "esbuild-darwin-arm64": "0.15.18",
+        "esbuild-freebsd-64": "0.15.18",
+        "esbuild-freebsd-arm64": "0.15.18",
+        "esbuild-linux-32": "0.15.18",
+        "esbuild-linux-64": "0.15.18",
+        "esbuild-linux-arm": "0.15.18",
+        "esbuild-linux-arm64": "0.15.18",
+        "esbuild-linux-mips64le": "0.15.18",
+        "esbuild-linux-ppc64le": "0.15.18",
+        "esbuild-linux-riscv64": "0.15.18",
+        "esbuild-linux-s390x": "0.15.18",
+        "esbuild-netbsd-64": "0.15.18",
+        "esbuild-openbsd-64": "0.15.18",
+        "esbuild-sunos-64": "0.15.18",
+        "esbuild-windows-32": "0.15.18",
+        "esbuild-windows-64": "0.15.18",
+        "esbuild-windows-arm64": "0.15.18"
       }
     },
     "esbuild-android-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.12.tgz",
-      "integrity": "sha512-MJKXwvPY9g0rGps0+U65HlTsM1wUs9lbjt5CU19RESqycGFDRijMDQsh68MtbzkqWSRdEtiKS1mtPzKneaAI0Q==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz",
+      "integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==",
       "optional": true
     },
     "esbuild-android-arm64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.12.tgz",
-      "integrity": "sha512-Hc9SEcZbIMhhLcvhr1DH+lrrec9SFTiRzfJ7EGSBZiiw994gfkVV6vG0sLWqQQ6DD7V4+OggB+Hn0IRUdDUqvA==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz",
+      "integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==",
       "optional": true
     },
     "esbuild-darwin-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.12.tgz",
-      "integrity": "sha512-qkmqrTVYPFiePt5qFjP8w/S+GIUMbt6k8qmiPraECUWfPptaPJUGkCKrWEfYFRWB7bY23FV95rhvPyh/KARP8Q==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz",
+      "integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==",
       "optional": true
     },
     "esbuild-darwin-arm64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.12.tgz",
-      "integrity": "sha512-z4zPX02tQ41kcXMyN3c/GfZpIjKoI/BzHrdKUwhC/Ki5BAhWv59A9M8H+iqaRbwpzYrYidTybBwiZAIWCLJAkw==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz",
+      "integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==",
       "optional": true
     },
     "esbuild-freebsd-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.12.tgz",
-      "integrity": "sha512-XFL7gKMCKXLDiAiBjhLG0XECliXaRLTZh6hsyzqUqPUf/PY4C6EJDTKIeqqPKXaVJ8+fzNek88285krSz1QECw==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz",
+      "integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==",
       "optional": true
     },
     "esbuild-freebsd-arm64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.12.tgz",
-      "integrity": "sha512-jwEIu5UCUk6TjiG1X+KQnCGISI+ILnXzIzt9yDVrhjug2fkYzlLbl0K43q96Q3KB66v6N1UFF0r5Ks4Xo7i72g==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz",
+      "integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==",
       "optional": true
     },
     "esbuild-linux-32": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.12.tgz",
-      "integrity": "sha512-uSQuSEyF1kVzGzuIr4XM+v7TPKxHjBnLcwv2yPyCz8riV8VUCnO/C4BF3w5dHiVpCd5Z1cebBtZJNlC4anWpwA==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz",
+      "integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==",
       "optional": true
     },
     "esbuild-linux-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.12.tgz",
-      "integrity": "sha512-QcgCKb7zfJxqT9o5z9ZUeGH1k8N6iX1Y7VNsEi5F9+HzN1OIx7ESxtQXDN9jbeUSPiRH1n9cw6gFT3H4qbdvcA==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz",
+      "integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==",
       "optional": true
     },
     "esbuild-linux-arm": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.12.tgz",
-      "integrity": "sha512-Wf7T0aNylGcLu7hBnzMvsTfEXdEdJY/hY3u36Vla21aY66xR0MS5I1Hw8nVquXjTN0A6fk/vnr32tkC/C2lb0A==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz",
+      "integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==",
       "optional": true
     },
     "esbuild-linux-arm64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.12.tgz",
-      "integrity": "sha512-HtNq5xm8fUpZKwWKS2/YGwSfTF+339L4aIA8yphNKYJckd5hVdhfdl6GM2P3HwLSCORS++++7++//ApEwXEuAQ==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz",
+      "integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==",
       "optional": true
     },
     "esbuild-linux-mips64le": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.12.tgz",
-      "integrity": "sha512-Qol3+AvivngUZkTVFgLpb0H6DT+N5/zM3V1YgTkryPYFeUvuT5JFNDR3ZiS6LxhyF8EE+fiNtzwlPqMDqVcc6A==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz",
+      "integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==",
       "optional": true
     },
     "esbuild-linux-ppc64le": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.12.tgz",
-      "integrity": "sha512-4D8qUCo+CFKaR0cGXtGyVsOI7w7k93Qxb3KFXWr75An0DHamYzq8lt7TNZKoOq/Gh8c40/aKaxvcZnTgQ0TJNg==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz",
+      "integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==",
       "optional": true
     },
     "esbuild-linux-riscv64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.12.tgz",
-      "integrity": "sha512-G9w6NcuuCI6TUUxe6ka0enjZHDnSVK8bO+1qDhMOCtl7Tr78CcZilJj8SGLN00zO5iIlwNRZKHjdMpfFgNn1VA==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz",
+      "integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==",
       "optional": true
     },
     "esbuild-linux-s390x": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.12.tgz",
-      "integrity": "sha512-Lt6BDnuXbXeqSlVuuUM5z18GkJAZf3ERskGZbAWjrQoi9xbEIsj/hEzVnSAFLtkfLuy2DE4RwTcX02tZFunXww==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz",
+      "integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==",
       "optional": true
     },
     "esbuild-netbsd-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.12.tgz",
-      "integrity": "sha512-jlUxCiHO1dsqoURZDQts+HK100o0hXfi4t54MNRMCAqKGAV33JCVvMplLAa2FwviSojT/5ZG5HUfG3gstwAG8w==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz",
+      "integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==",
       "optional": true
     },
     "esbuild-openbsd-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.12.tgz",
-      "integrity": "sha512-1o1uAfRTMIWNOmpf8v7iudND0L6zRBYSH45sofCZywrcf7NcZA+c7aFsS1YryU+yN7aRppTqdUK1PgbZVaB1Dw==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz",
+      "integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==",
       "optional": true
     },
     "esbuild-sunos-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.12.tgz",
-      "integrity": "sha512-nkl251DpoWoBO9Eq9aFdoIt2yYmp4I3kvQjba3jFKlMXuqQ9A4q+JaqdkCouG3DHgAGnzshzaGu6xofGcXyPXg==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz",
+      "integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==",
       "optional": true
     },
     "esbuild-windows-32": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.12.tgz",
-      "integrity": "sha512-WlGeBZHgPC00O08luIp5B2SP4cNCp/PcS+3Pcg31kdcJPopHxLkdCXtadLU9J82LCfw4TVls21A6lilQ9mzHrw==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz",
+      "integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==",
       "optional": true
     },
     "esbuild-windows-64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.12.tgz",
-      "integrity": "sha512-VActO3WnWZSN//xjSfbiGOSyC+wkZtI8I4KlgrTo5oHJM6z3MZZBCuFaZHd8hzf/W9KPhF0lY8OqlmWC9HO5AA==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz",
+      "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==",
       "optional": true
     },
     "esbuild-windows-arm64": {
-      "version": "0.15.12",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.12.tgz",
-      "integrity": "sha512-Of3MIacva1OK/m4zCNIvBfz8VVROBmQT+gRX6pFTLPngFYcj6TFH/12VveAqq1k9VB2l28EoVMNMUCcmsfwyuA==",
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz",
+      "integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==",
       "optional": true
     },
     "escalade": {
@@ -12818,9 +13256,9 @@
       "dev": true
     },
     "escape-string-regexp": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
       "dev": true
     },
     "escodegen": {
@@ -12834,16 +13272,68 @@
         "esutils": "^2.0.2",
         "optionator": "^0.8.1",
         "source-map": "~0.6.1"
+      },
+      "dependencies": {
+        "estraverse": {
+          "version": "5.3.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+          "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+          "dev": true
+        },
+        "levn": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+          "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==",
+          "dev": true,
+          "requires": {
+            "prelude-ls": "~1.1.2",
+            "type-check": "~0.3.2"
+          }
+        },
+        "optionator": {
+          "version": "0.8.3",
+          "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+          "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+          "dev": true,
+          "requires": {
+            "deep-is": "~0.1.3",
+            "fast-levenshtein": "~2.0.6",
+            "levn": "~0.3.0",
+            "prelude-ls": "~1.1.2",
+            "type-check": "~0.3.2",
+            "word-wrap": "~1.2.3"
+          }
+        },
+        "prelude-ls": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+          "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==",
+          "dev": true
+        },
+        "type-check": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+          "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
+          "dev": true,
+          "requires": {
+            "prelude-ls": "~1.1.2"
+          }
+        }
       }
     },
     "eslint": {
-      "version": "8.15.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz",
-      "integrity": "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==",
+      "version": "8.36.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz",
+      "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==",
       "dev": true,
       "requires": {
-        "@eslint/eslintrc": "^1.2.3",
-        "@humanwhocodes/config-array": "^0.9.2",
+        "@eslint-community/eslint-utils": "^4.2.0",
+        "@eslint-community/regexpp": "^4.4.0",
+        "@eslint/eslintrc": "^2.0.1",
+        "@eslint/js": "8.36.0",
+        "@humanwhocodes/config-array": "^0.11.8",
+        "@humanwhocodes/module-importer": "^1.0.1",
+        "@nodelib/fs.walk": "^1.2.8",
         "ajv": "^6.10.0",
         "chalk": "^4.0.0",
         "cross-spawn": "^7.0.2",
@@ -12851,20 +13341,22 @@
         "doctrine": "^3.0.0",
         "escape-string-regexp": "^4.0.0",
         "eslint-scope": "^7.1.1",
-        "eslint-utils": "^3.0.0",
         "eslint-visitor-keys": "^3.3.0",
-        "espree": "^9.3.2",
-        "esquery": "^1.4.0",
+        "espree": "^9.5.0",
+        "esquery": "^1.4.2",
         "esutils": "^2.0.2",
         "fast-deep-equal": "^3.1.3",
         "file-entry-cache": "^6.0.1",
-        "functional-red-black-tree": "^1.0.1",
-        "glob-parent": "^6.0.1",
-        "globals": "^13.6.0",
+        "find-up": "^5.0.0",
+        "glob-parent": "^6.0.2",
+        "globals": "^13.19.0",
+        "grapheme-splitter": "^1.0.4",
         "ignore": "^5.2.0",
         "import-fresh": "^3.0.0",
         "imurmurhash": "^0.1.4",
         "is-glob": "^4.0.0",
+        "is-path-inside": "^3.0.3",
+        "js-sdsl": "^4.1.4",
         "js-yaml": "^4.1.0",
         "json-stable-stringify-without-jsonify": "^1.0.1",
         "levn": "^0.4.1",
@@ -12872,137 +13364,26 @@
         "minimatch": "^3.1.2",
         "natural-compare": "^1.4.0",
         "optionator": "^0.9.1",
-        "regexpp": "^3.2.0",
         "strip-ansi": "^6.0.1",
         "strip-json-comments": "^3.1.0",
-        "text-table": "^0.2.0",
-        "v8-compile-cache": "^2.0.3"
+        "text-table": "^0.2.0"
       },
       "dependencies": {
-        "argparse": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
-          "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+        "eslint-scope": {
+          "version": "7.1.1",
+          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
+          "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
+          "dev": true,
+          "requires": {
+            "esrecurse": "^4.3.0",
+            "estraverse": "^5.2.0"
+          }
+        },
+        "estraverse": {
+          "version": "5.3.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+          "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
           "dev": true
-        },
-        "cross-spawn": {
-          "version": "7.0.3",
-          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-          "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
-          "dev": true,
-          "requires": {
-            "path-key": "^3.1.0",
-            "shebang-command": "^2.0.0",
-            "which": "^2.0.1"
-          }
-        },
-        "escape-string-regexp": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-          "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
-          "dev": true
-        },
-        "globals": {
-          "version": "13.15.0",
-          "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz",
-          "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==",
-          "dev": true,
-          "requires": {
-            "type-fest": "^0.20.2"
-          }
-        },
-        "js-yaml": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
-          "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
-          "dev": true,
-          "requires": {
-            "argparse": "^2.0.1"
-          }
-        },
-        "levn": {
-          "version": "0.4.1",
-          "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
-          "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
-          "dev": true,
-          "requires": {
-            "prelude-ls": "^1.2.1",
-            "type-check": "~0.4.0"
-          }
-        },
-        "minimatch": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-          "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        },
-        "optionator": {
-          "version": "0.9.1",
-          "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
-          "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
-          "dev": true,
-          "requires": {
-            "deep-is": "^0.1.3",
-            "fast-levenshtein": "^2.0.6",
-            "levn": "^0.4.1",
-            "prelude-ls": "^1.2.1",
-            "type-check": "^0.4.0",
-            "word-wrap": "^1.2.3"
-          }
-        },
-        "path-key": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-          "dev": true
-        },
-        "prelude-ls": {
-          "version": "1.2.1",
-          "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
-          "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
-          "dev": true
-        },
-        "shebang-command": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-          "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
-          "dev": true,
-          "requires": {
-            "shebang-regex": "^3.0.0"
-          }
-        },
-        "shebang-regex": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-          "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-          "dev": true
-        },
-        "type-check": {
-          "version": "0.4.0",
-          "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
-          "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
-          "dev": true,
-          "requires": {
-            "prelude-ls": "^1.2.1"
-          }
-        },
-        "type-fest": {
-          "version": "0.20.2",
-          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
-          "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
-          "dev": true
-        },
-        "which": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-          "dev": true,
-          "requires": {
-            "isexe": "^2.0.0"
-          }
         }
       }
     },
@@ -13014,30 +13395,13 @@
       "requires": {}
     },
     "eslint-scope": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
-      "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
       "dev": true,
       "requires": {
         "esrecurse": "^4.3.0",
-        "estraverse": "^5.2.0"
-      }
-    },
-    "eslint-utils": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
-      "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
-      "dev": true,
-      "requires": {
-        "eslint-visitor-keys": "^2.0.0"
-      },
-      "dependencies": {
-        "eslint-visitor-keys": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-          "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
-          "dev": true
-        }
+        "estraverse": "^4.1.1"
       }
     },
     "eslint-visitor-keys": {
@@ -13047,12 +13411,12 @@
       "dev": true
     },
     "espree": {
-      "version": "9.3.2",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
-      "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==",
+      "version": "9.5.0",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz",
+      "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==",
       "dev": true,
       "requires": {
-        "acorn": "^8.7.1",
+        "acorn": "^8.8.0",
         "acorn-jsx": "^5.3.2",
         "eslint-visitor-keys": "^3.3.0"
       }
@@ -13064,12 +13428,20 @@
       "dev": true
     },
     "esquery": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
-      "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+      "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
       "dev": true,
       "requires": {
         "estraverse": "^5.1.0"
+      },
+      "dependencies": {
+        "estraverse": {
+          "version": "5.3.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+          "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+          "dev": true
+        }
       }
     },
     "esrecurse": {
@@ -13079,12 +13451,20 @@
       "dev": true,
       "requires": {
         "estraverse": "^5.2.0"
+      },
+      "dependencies": {
+        "estraverse": {
+          "version": "5.3.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+          "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+          "dev": true
+        }
       }
     },
     "estraverse": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
-      "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
       "dev": true
     },
     "estree-walker": {
@@ -13100,9 +13480,9 @@
       "dev": true
     },
     "events": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz",
-      "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg=="
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+      "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="
     },
     "exec-sh": {
       "version": "0.3.6",
@@ -13111,30 +13491,32 @@
       "dev": true
     },
     "execa": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
-      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
+      "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
       "dev": true,
       "requires": {
-        "cross-spawn": "^6.0.0",
-        "get-stream": "^4.0.0",
-        "is-stream": "^1.1.0",
-        "npm-run-path": "^2.0.0",
-        "p-finally": "^1.0.0",
-        "signal-exit": "^3.0.0",
-        "strip-eof": "^1.0.0"
+        "cross-spawn": "^7.0.0",
+        "get-stream": "^5.0.0",
+        "human-signals": "^1.1.1",
+        "is-stream": "^2.0.0",
+        "merge-stream": "^2.0.0",
+        "npm-run-path": "^4.0.0",
+        "onetime": "^5.1.0",
+        "signal-exit": "^3.0.2",
+        "strip-final-newline": "^2.0.0"
       }
     },
     "exit": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
-      "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+      "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
       "dev": true
     },
     "expand-brackets": {
       "version": "2.1.4",
       "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
-      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==",
       "dev": true,
       "requires": {
         "debug": "^2.3.3",
@@ -13158,7 +13540,7 @@
         "define-property": {
           "version": "0.2.5",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
           "dev": true,
           "requires": {
             "is-descriptor": "^0.1.0"
@@ -13167,16 +13549,79 @@
         "extend-shallow": {
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
           "dev": true,
           "requires": {
             "is-extendable": "^0.1.0"
           }
         },
+        "is-accessor-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+          "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+              "dev": true,
+              "requires": {
+                "is-buffer": "^1.1.5"
+              }
+            }
+          }
+        },
+        "is-data-descriptor": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+          "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+              "dev": true,
+              "requires": {
+                "is-buffer": "^1.1.5"
+              }
+            }
+          }
+        },
+        "is-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^0.1.6",
+            "is-data-descriptor": "^0.1.4",
+            "kind-of": "^5.0.0"
+          }
+        },
+        "is-extendable": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+          "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        },
         "ms": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
           "dev": true
         }
       }
@@ -13195,31 +13640,14 @@
         "jest-regex-util": "^26.0.0"
       }
     },
-    "extend": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
-      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
-      "dev": true
-    },
     "extend-shallow": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
-      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
       "dev": true,
       "requires": {
         "assign-symbols": "^1.0.0",
         "is-extendable": "^1.0.1"
-      },
-      "dependencies": {
-        "is-extendable": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
-          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
-          "dev": true,
-          "requires": {
-            "is-plain-object": "^2.0.4"
-          }
-        }
       }
     },
     "extglob": {
@@ -13241,7 +13669,7 @@
         "define-property": {
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
           "dev": true,
           "requires": {
             "is-descriptor": "^1.0.0"
@@ -13250,40 +13678,17 @@
         "extend-shallow": {
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
           "dev": true,
           "requires": {
             "is-extendable": "^0.1.0"
           }
         },
-        "is-accessor-descriptor": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
-          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
-          "dev": true,
-          "requires": {
-            "kind-of": "^6.0.0"
-          }
-        },
-        "is-data-descriptor": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
-          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
-          "dev": true,
-          "requires": {
-            "kind-of": "^6.0.0"
-          }
-        },
-        "is-descriptor": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
-          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
-          "dev": true,
-          "requires": {
-            "is-accessor-descriptor": "^1.0.0",
-            "is-data-descriptor": "^1.0.0",
-            "kind-of": "^6.0.2"
-          }
+        "is-extendable": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+          "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+          "dev": true
         }
       }
     },
@@ -13297,25 +13702,8 @@
         "debug": "^4.1.1",
         "get-stream": "^5.1.0",
         "yauzl": "^2.10.0"
-      },
-      "dependencies": {
-        "get-stream": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
-          "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
-          "dev": true,
-          "requires": {
-            "pump": "^3.0.0"
-          }
-        }
       }
     },
-    "extsprintf": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
-      "dev": true
-    },
     "fast-deep-equal": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -13323,9 +13711,9 @@
       "dev": true
     },
     "fast-glob": {
-      "version": "3.2.11",
-      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
-      "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
+      "version": "3.2.12",
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
+      "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
       "dev": true,
       "requires": {
         "@nodelib/fs.stat": "^2.0.2",
@@ -13355,22 +13743,22 @@
     "fast-levenshtein": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
-      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+      "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
       "dev": true
     },
     "fastq": {
-      "version": "1.13.0",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
-      "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+      "version": "1.15.0",
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
+      "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
       "dev": true,
       "requires": {
         "reusify": "^1.0.4"
       }
     },
     "fb-watchman": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
-      "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
+      "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
       "dev": true,
       "requires": {
         "bser": "2.1.1"
@@ -13379,7 +13767,7 @@
     "fd-slicer": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
-      "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+      "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
       "dev": true,
       "requires": {
         "pend": "~1.2.0"
@@ -13404,12 +13792,12 @@
       }
     },
     "find-up": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
-      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+      "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
       "dev": true,
       "requires": {
-        "locate-path": "^5.0.0",
+        "locate-path": "^6.0.0",
         "path-exists": "^4.0.0"
       }
     },
@@ -13424,43 +13812,29 @@
       }
     },
     "flatted": {
-      "version": "3.2.5",
-      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz",
-      "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==",
+      "version": "3.2.7",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
+      "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
       "dev": true
     },
+    "for-each": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+      "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+      "requires": {
+        "is-callable": "^1.1.3"
+      }
+    },
     "for-in": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
-      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==",
       "dev": true
     },
-    "foreach": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
-      "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
-    },
-    "forever-agent": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
-      "dev": true
-    },
-    "form-data": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
-      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
-      "dev": true,
-      "requires": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.6",
-        "mime-types": "^2.1.12"
-      }
-    },
     "fragment-cache": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
-      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==",
       "dev": true,
       "requires": {
         "map-cache": "^0.2.2"
@@ -13484,7 +13858,7 @@
     "fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
     },
     "fsevents": {
       "version": "2.3.2",
@@ -13498,29 +13872,6 @@
       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
       "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
     },
-    "functional-red-black-tree": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
-      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
-      "dev": true
-    },
-    "gauge": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
-      "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
-      "dev": true,
-      "requires": {
-        "aproba": "^1.0.3 || ^2.0.0",
-        "color-support": "^1.1.2",
-        "console-control-strings": "^1.0.0",
-        "has-unicode": "^2.0.1",
-        "object-assign": "^4.1.1",
-        "signal-exit": "^3.0.0",
-        "string-width": "^4.2.3",
-        "strip-ansi": "^6.0.1",
-        "wide-align": "^1.1.2"
-      }
-    },
     "gaze": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
@@ -13543,13 +13894,13 @@
       "dev": true
     },
     "get-intrinsic": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
-      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
+      "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==",
       "requires": {
         "function-bind": "^1.1.1",
         "has": "^1.0.3",
-        "has-symbols": "^1.0.1"
+        "has-symbols": "^1.0.3"
       }
     },
     "get-package-type": {
@@ -13561,13 +13912,13 @@
     "get-stdin": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
-      "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+      "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==",
       "dev": true
     },
     "get-stream": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
-      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
       "dev": true,
       "requires": {
         "pump": "^3.0.0"
@@ -13576,27 +13927,18 @@
     "get-value": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
-      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==",
       "dev": true
     },
-    "getpass": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "^1.0.0"
-      }
-    },
     "glob": {
-      "version": "7.1.6",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
-      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
       "requires": {
         "fs.realpath": "^1.0.0",
         "inflight": "^1.0.4",
         "inherits": "2",
-        "minimatch": "^3.0.4",
+        "minimatch": "^3.1.1",
         "once": "^1.3.0",
         "path-is-absolute": "^1.0.0"
       }
@@ -13611,10 +13953,13 @@
       }
     },
     "globals": {
-      "version": "11.12.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
-      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
-      "dev": true
+      "version": "13.20.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
+      "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
+      "dev": true,
+      "requires": {
+        "type-fest": "^0.20.2"
+      }
     },
     "globby": {
       "version": "11.1.0",
@@ -13631,45 +13976,68 @@
       }
     },
     "globule": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz",
-      "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==",
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz",
+      "integrity": "sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==",
       "dev": true,
       "requires": {
         "glob": "~7.1.1",
-        "lodash": "~4.17.10",
+        "lodash": "^4.17.21",
         "minimatch": "~3.0.2"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.7",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+          "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "minimatch": {
+          "version": "3.0.8",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
+          "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^1.1.7"
+          }
+        }
+      }
+    },
+    "gopd": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+      "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+      "requires": {
+        "get-intrinsic": "^1.1.3"
       }
     },
     "graceful-fs": {
-      "version": "4.2.10",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
-      "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+      "version": "4.2.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+      "dev": true
+    },
+    "grapheme-splitter": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+      "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
       "dev": true
     },
     "growly": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
-      "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
+      "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==",
       "dev": true,
       "optional": true
     },
-    "har-schema": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
-      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
-      "dev": true
-    },
-    "har-validator": {
-      "version": "5.1.5",
-      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
-      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
-      "dev": true,
-      "requires": {
-        "ajv": "^6.12.3",
-        "har-schema": "^2.0.0"
-      }
-    },
     "hard-rejection": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
@@ -13691,20 +14059,28 @@
       "dev": true
     },
     "has-symbols": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
-      "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
+    },
+    "has-tostringtag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+      "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+      "requires": {
+        "has-symbols": "^1.0.2"
+      }
     },
     "has-unicode": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
-      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
+      "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
       "dev": true
     },
     "has-value": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
-      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==",
       "dev": true,
       "requires": {
         "get-value": "^2.0.6",
@@ -13715,7 +14091,7 @@
     "has-values": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
-      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+      "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==",
       "dev": true,
       "requires": {
         "is-number": "^3.0.0",
@@ -13725,7 +14101,7 @@
         "is-number": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
-          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
           "dev": true,
           "requires": {
             "kind-of": "^3.0.2"
@@ -13734,7 +14110,7 @@
             "kind-of": {
               "version": "3.2.2",
               "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
               "dev": true,
               "requires": {
                 "is-buffer": "^1.1.5"
@@ -13745,7 +14121,7 @@
         "kind-of": {
           "version": "4.0.0",
           "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
-          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==",
           "dev": true,
           "requires": {
             "is-buffer": "^1.1.5"
@@ -13754,10 +14130,30 @@
       }
     },
     "hosted-git-info": {
-      "version": "2.8.9",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
-      "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
-      "dev": true
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+      "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
+      "dev": true,
+      "requires": {
+        "lru-cache": "^6.0.0"
+      },
+      "dependencies": {
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "dev": true,
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+          "dev": true
+        }
+      }
     },
     "hsluv": {
       "version": "0.1.0",
@@ -13780,9 +14176,9 @@
       "dev": true
     },
     "http-cache-semantics": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
-      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
+      "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
       "dev": true
     },
     "http-proxy-agent": {
@@ -13796,17 +14192,6 @@
         "debug": "4"
       }
     },
-    "http-signature": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
-      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "^1.0.0",
-        "jsprim": "^1.2.2",
-        "sshpk": "^1.7.0"
-      }
-    },
     "https-proxy-agent": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
@@ -13826,19 +14211,20 @@
     "humanize-ms": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
-      "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=",
+      "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
       "dev": true,
       "requires": {
         "ms": "^2.0.0"
       }
     },
     "iconv-lite": {
-      "version": "0.4.24",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
-      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
       "dev": true,
+      "optional": true,
       "requires": {
-        "safer-buffer": ">= 2.1.2 < 3"
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
       }
     },
     "ieee754": {
@@ -13848,15 +14234,15 @@
       "dev": true
     },
     "ignore": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
-      "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+      "version": "5.2.4",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+      "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
       "dev": true
     },
     "immer": {
-      "version": "9.0.14",
-      "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.14.tgz",
-      "integrity": "sha512-ubBeqQutOSLIFCUBN03jGeOS6a3DoYlSYwYJTa+gSKEZKU5redJIqkIdZ3JVv/4RZpfcXdAWH5zCNLWPRv2WDw=="
+      "version": "9.0.21",
+      "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
+      "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA=="
     },
     "import-fresh": {
       "version": "3.3.0",
@@ -13866,20 +14252,12 @@
       "requires": {
         "parent-module": "^1.0.0",
         "resolve-from": "^4.0.0"
-      },
-      "dependencies": {
-        "resolve-from": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
-          "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-          "dev": true
-        }
       }
     },
     "import-local": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz",
-      "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+      "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
       "dev": true,
       "requires": {
         "pkg-dir": "^4.2.0",
@@ -13889,7 +14267,7 @@
     "imurmurhash": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
-      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
       "dev": true
     },
     "indent-string": {
@@ -13907,7 +14285,7 @@
     "inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
       "requires": {
         "once": "^1.3.0",
         "wrappy": "1"
@@ -13919,43 +14297,33 @@
       "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
     },
     "ip": {
-      "version": "1.1.8",
-      "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
-      "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
+      "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==",
       "dev": true
     },
     "is-accessor-descriptor": {
-      "version": "0.1.6",
-      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
-      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
       "dev": true,
       "requires": {
-        "kind-of": "^3.0.2"
-      },
-      "dependencies": {
-        "kind-of": {
-          "version": "3.2.2",
-          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-          "dev": true,
-          "requires": {
-            "is-buffer": "^1.1.5"
-          }
-        }
+        "kind-of": "^6.0.0"
       }
     },
     "is-arguments": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz",
-      "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==",
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
+      "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
       "requires": {
-        "call-bind": "^1.0.0"
+        "call-bind": "^1.0.2",
+        "has-tostringtag": "^1.0.0"
       }
     },
     "is-arrayish": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
       "dev": true
     },
     "is-buffer": {
@@ -13964,10 +14332,19 @@
       "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
       "dev": true
     },
+    "is-builtin-module": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz",
+      "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==",
+      "dev": true,
+      "requires": {
+        "builtin-modules": "^3.3.0"
+      }
+    },
     "is-callable": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz",
-      "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ=="
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+      "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="
     },
     "is-ci": {
       "version": "2.0.0",
@@ -13979,56 +14356,32 @@
       }
     },
     "is-core-module": {
-      "version": "2.9.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
-      "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
+      "version": "2.11.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+      "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
       "dev": true,
       "requires": {
         "has": "^1.0.3"
       }
     },
     "is-data-descriptor": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
-      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
       "dev": true,
       "requires": {
-        "kind-of": "^3.0.2"
-      },
-      "dependencies": {
-        "kind-of": {
-          "version": "3.2.2",
-          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-          "dev": true,
-          "requires": {
-            "is-buffer": "^1.1.5"
-          }
-        }
+        "kind-of": "^6.0.0"
       }
     },
-    "is-date-object": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
-      "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g=="
-    },
     "is-descriptor": {
-      "version": "0.1.6",
-      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
-      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
       "dev": true,
       "requires": {
-        "is-accessor-descriptor": "^0.1.6",
-        "is-data-descriptor": "^0.1.4",
-        "kind-of": "^5.0.0"
-      },
-      "dependencies": {
-        "kind-of": {
-          "version": "5.1.0",
-          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
-          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
-          "dev": true
-        }
+        "is-accessor-descriptor": "^1.0.0",
+        "is-data-descriptor": "^1.0.0",
+        "kind-of": "^6.0.2"
       }
     },
     "is-docker": {
@@ -14039,15 +14392,18 @@
       "optional": true
     },
     "is-extendable": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
-      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
-      "dev": true
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+      "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+      "dev": true,
+      "requires": {
+        "is-plain-object": "^2.0.4"
+      }
     },
     "is-extglob": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
       "dev": true
     },
     "is-fullwidth-code-point": {
@@ -14063,9 +14419,12 @@
       "dev": true
     },
     "is-generator-function": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz",
-      "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ=="
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
+      "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
+      "requires": {
+        "has-tostringtag": "^1.0.0"
+      }
     },
     "is-glob": {
       "version": "4.0.3",
@@ -14079,30 +14438,31 @@
     "is-lambda": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
-      "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=",
+      "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
       "dev": true
     },
     "is-module": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
-      "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
+      "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
       "dev": true
     },
-    "is-negative-zero": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
-      "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w=="
-    },
     "is-number": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
       "dev": true
     },
+    "is-path-inside": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+      "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+      "dev": true
+    },
     "is-plain-obj": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
-      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+      "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
       "dev": true
     },
     "is-plain-object": {
@@ -14129,45 +14489,28 @@
         "@types/estree": "*"
       }
     },
-    "is-regex": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz",
-      "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==",
-      "requires": {
-        "call-bind": "^1.0.2",
-        "has-symbols": "^1.0.1"
-      }
-    },
     "is-stream": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
       "dev": true
     },
-    "is-symbol": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
-      "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
-      "requires": {
-        "has-symbols": "^1.0.1"
-      }
-    },
     "is-typed-array": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.4.tgz",
-      "integrity": "sha512-ILaRgn4zaSrVNXNGtON6iFNotXW3hAPF3+0fB1usg2jFlWqo5fEDdmJkz0zBfoi7Dgskr8Khi2xZ8cXqZEfXNA==",
+      "version": "1.1.10",
+      "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
+      "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
       "requires": {
-        "available-typed-arrays": "^1.0.2",
-        "call-bind": "^1.0.0",
-        "es-abstract": "^1.18.0-next.1",
-        "foreach": "^2.0.5",
-        "has-symbols": "^1.0.1"
+        "available-typed-arrays": "^1.0.5",
+        "call-bind": "^1.0.2",
+        "for-each": "^0.3.3",
+        "gopd": "^1.0.1",
+        "has-tostringtag": "^1.0.0"
       }
     },
     "is-typedarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
-      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
       "dev": true
     },
     "is-windows": {
@@ -14189,31 +14532,25 @@
     "isarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
       "dev": true
     },
     "isexe": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
       "dev": true
     },
     "isobject": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-      "dev": true
-    },
-    "isstream": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+      "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
       "dev": true
     },
     "istanbul-lib-coverage": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
-      "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
+      "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
       "dev": true
     },
     "istanbul-lib-instrument": {
@@ -14226,6 +14563,14 @@
         "@istanbuljs/schema": "^0.1.2",
         "istanbul-lib-coverage": "^3.0.0",
         "semver": "^6.3.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
       }
     },
     "istanbul-lib-report": {
@@ -14240,9 +14585,9 @@
       }
     },
     "istanbul-lib-source-maps": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz",
-      "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+      "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
       "dev": true,
       "requires": {
         "debug": "^4.1.1",
@@ -14251,9 +14596,9 @@
       }
     },
     "istanbul-reports": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz",
-      "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==",
+      "version": "3.1.5",
+      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
+      "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
       "dev": true,
       "requires": {
         "html-escaper": "^2.0.0",
@@ -14269,29 +14614,6 @@
         "@jest/core": "^26.6.3",
         "import-local": "^3.0.2",
         "jest-cli": "^26.6.3"
-      },
-      "dependencies": {
-        "jest-cli": {
-          "version": "26.6.3",
-          "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz",
-          "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==",
-          "dev": true,
-          "requires": {
-            "@jest/core": "^26.6.3",
-            "@jest/test-result": "^26.6.2",
-            "@jest/types": "^26.6.2",
-            "chalk": "^4.0.0",
-            "exit": "^0.1.2",
-            "graceful-fs": "^4.2.4",
-            "import-local": "^3.0.2",
-            "is-ci": "^2.0.0",
-            "jest-config": "^26.6.3",
-            "jest-util": "^26.6.2",
-            "jest-validate": "^26.6.2",
-            "prompts": "^2.0.1",
-            "yargs": "^15.4.1"
-          }
-        }
       }
     },
     "jest-changed-files": {
@@ -14303,116 +14625,55 @@
         "@jest/types": "^26.6.2",
         "execa": "^4.0.0",
         "throat": "^5.0.0"
-      },
-      "dependencies": {
-        "cross-spawn": {
-          "version": "7.0.3",
-          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-          "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
-          "dev": true,
-          "requires": {
-            "path-key": "^3.1.0",
-            "shebang-command": "^2.0.0",
-            "which": "^2.0.1"
-          }
-        },
-        "execa": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
-          "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
-          "dev": true,
-          "requires": {
-            "cross-spawn": "^7.0.0",
-            "get-stream": "^5.0.0",
-            "human-signals": "^1.1.1",
-            "is-stream": "^2.0.0",
-            "merge-stream": "^2.0.0",
-            "npm-run-path": "^4.0.0",
-            "onetime": "^5.1.0",
-            "signal-exit": "^3.0.2",
-            "strip-final-newline": "^2.0.0"
-          }
-        },
-        "get-stream": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
-          "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
-          "dev": true,
-          "requires": {
-            "pump": "^3.0.0"
-          }
-        },
-        "is-stream": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
-          "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
-          "dev": true
-        },
-        "npm-run-path": {
-          "version": "4.0.1",
-          "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
-          "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
-          "dev": true,
-          "requires": {
-            "path-key": "^3.0.0"
-          }
-        },
-        "path-key": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-          "dev": true
-        },
-        "shebang-command": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-          "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
-          "dev": true,
-          "requires": {
-            "shebang-regex": "^3.0.0"
-          }
-        },
-        "shebang-regex": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-          "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-          "dev": true
-        },
-        "which": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-          "dev": true,
-          "requires": {
-            "isexe": "^2.0.0"
-          }
-        }
       }
     },
-    "jest-config": {
+    "jest-cli": {
       "version": "26.6.3",
-      "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz",
-      "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==",
+      "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz",
+      "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==",
       "dev": true,
       "requires": {
-        "@babel/core": "^7.1.0",
-        "@jest/test-sequencer": "^26.6.3",
+        "@jest/core": "^26.6.3",
+        "@jest/test-result": "^26.6.2",
         "@jest/types": "^26.6.2",
-        "babel-jest": "^26.6.3",
         "chalk": "^4.0.0",
-        "deepmerge": "^4.2.2",
-        "glob": "^7.1.1",
+        "exit": "^0.1.2",
         "graceful-fs": "^4.2.4",
-        "jest-environment-jsdom": "^26.6.2",
-        "jest-environment-node": "^26.6.2",
-        "jest-get-type": "^26.3.0",
-        "jest-jasmine2": "^26.6.3",
-        "jest-regex-util": "^26.0.0",
-        "jest-resolve": "^26.6.2",
+        "import-local": "^3.0.2",
+        "is-ci": "^2.0.0",
+        "jest-config": "^26.6.3",
         "jest-util": "^26.6.2",
         "jest-validate": "^26.6.2",
-        "micromatch": "^4.0.2",
-        "pretty-format": "^26.6.2"
+        "prompts": "^2.0.1",
+        "yargs": "^15.4.1"
+      },
+      "dependencies": {
+        "jest-config": {
+          "version": "26.6.3",
+          "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz",
+          "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==",
+          "dev": true,
+          "requires": {
+            "@babel/core": "^7.1.0",
+            "@jest/test-sequencer": "^26.6.3",
+            "@jest/types": "^26.6.2",
+            "babel-jest": "^26.6.3",
+            "chalk": "^4.0.0",
+            "deepmerge": "^4.2.2",
+            "glob": "^7.1.1",
+            "graceful-fs": "^4.2.4",
+            "jest-environment-jsdom": "^26.6.2",
+            "jest-environment-node": "^26.6.2",
+            "jest-get-type": "^26.3.0",
+            "jest-jasmine2": "^26.6.3",
+            "jest-regex-util": "^26.0.0",
+            "jest-resolve": "^26.6.2",
+            "jest-util": "^26.6.2",
+            "jest-validate": "^26.6.2",
+            "micromatch": "^4.0.2",
+            "pretty-format": "^26.6.2"
+          }
+        }
       }
     },
     "jest-diff": {
@@ -14582,9 +14843,9 @@
       }
     },
     "jest-pnp-resolver": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz",
-      "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==",
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
+      "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
       "dev": true,
       "requires": {}
     },
@@ -14647,6 +14908,34 @@
         "jest-worker": "^26.6.2",
         "source-map-support": "^0.5.6",
         "throat": "^5.0.0"
+      },
+      "dependencies": {
+        "jest-config": {
+          "version": "26.6.3",
+          "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz",
+          "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==",
+          "dev": true,
+          "requires": {
+            "@babel/core": "^7.1.0",
+            "@jest/test-sequencer": "^26.6.3",
+            "@jest/types": "^26.6.2",
+            "babel-jest": "^26.6.3",
+            "chalk": "^4.0.0",
+            "deepmerge": "^4.2.2",
+            "glob": "^7.1.1",
+            "graceful-fs": "^4.2.4",
+            "jest-environment-jsdom": "^26.6.2",
+            "jest-environment-node": "^26.6.2",
+            "jest-get-type": "^26.3.0",
+            "jest-jasmine2": "^26.6.3",
+            "jest-regex-util": "^26.0.0",
+            "jest-resolve": "^26.6.2",
+            "jest-util": "^26.6.2",
+            "jest-validate": "^26.6.2",
+            "micromatch": "^4.0.2",
+            "pretty-format": "^26.6.2"
+          }
+        }
       }
     },
     "jest-runtime": {
@@ -14682,6 +14971,34 @@
         "slash": "^3.0.0",
         "strip-bom": "^4.0.0",
         "yargs": "^15.4.1"
+      },
+      "dependencies": {
+        "jest-config": {
+          "version": "26.6.3",
+          "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz",
+          "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==",
+          "dev": true,
+          "requires": {
+            "@babel/core": "^7.1.0",
+            "@jest/test-sequencer": "^26.6.3",
+            "@jest/types": "^26.6.2",
+            "babel-jest": "^26.6.3",
+            "chalk": "^4.0.0",
+            "deepmerge": "^4.2.2",
+            "glob": "^7.1.1",
+            "graceful-fs": "^4.2.4",
+            "jest-environment-jsdom": "^26.6.2",
+            "jest-environment-node": "^26.6.2",
+            "jest-get-type": "^26.3.0",
+            "jest-jasmine2": "^26.6.3",
+            "jest-regex-util": "^26.0.0",
+            "jest-resolve": "^26.6.2",
+            "jest-util": "^26.6.2",
+            "jest-validate": "^26.6.2",
+            "micromatch": "^4.0.2",
+            "pretty-format": "^26.6.2"
+          }
+        }
       }
     },
     "jest-serializer": {
@@ -14716,17 +15033,6 @@
         "natural-compare": "^1.4.0",
         "pretty-format": "^26.6.2",
         "semver": "^7.3.2"
-      },
-      "dependencies": {
-        "semver": {
-          "version": "7.3.5",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-          "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
-          "dev": true,
-          "requires": {
-            "lru-cache": "^6.0.0"
-          }
-        }
       }
     },
     "jest-util": {
@@ -14758,9 +15064,9 @@
       },
       "dependencies": {
         "camelcase": {
-          "version": "6.2.0",
-          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
-          "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+          "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
           "dev": true
         }
       }
@@ -14797,6 +15103,12 @@
       "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==",
       "dev": true
     },
+    "js-sdsl": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz",
+      "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==",
+      "dev": true
+    },
     "js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -14804,30 +15116,23 @@
       "dev": true
     },
     "js-yaml": {
-      "version": "3.14.1",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
-      "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
       "dev": true,
       "requires": {
-        "argparse": "^1.0.7",
-        "esprima": "^4.0.0"
+        "argparse": "^2.0.1"
       }
     },
-    "jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
-      "dev": true
-    },
     "jsbn-rsa": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/jsbn-rsa/-/jsbn-rsa-1.0.4.tgz",
       "integrity": "sha512-unHyEPFGjr6WCzrcMiwdNhYMlq4gXt6Hg5JuKOyE7OXJ7GbVMpottnqsUkPeZCAYqByAkn4N8gJwCpnacduOew=="
     },
     "jsdom": {
-      "version": "16.6.0",
-      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz",
-      "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==",
+      "version": "16.7.0",
+      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz",
+      "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==",
       "dev": true,
       "requires": {
         "abab": "^2.0.5",
@@ -14855,7 +15160,7 @@
         "whatwg-encoding": "^1.0.5",
         "whatwg-mimetype": "^2.3.0",
         "whatwg-url": "^8.5.0",
-        "ws": "^7.4.5",
+        "ws": "^7.4.6",
         "xml-name-validator": "^3.0.0"
       },
       "dependencies": {
@@ -14869,6 +15174,51 @@
             "combined-stream": "^1.0.8",
             "mime-types": "^2.1.12"
           }
+        },
+        "tough-cookie": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz",
+          "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==",
+          "dev": true,
+          "requires": {
+            "psl": "^1.1.33",
+            "punycode": "^2.1.1",
+            "universalify": "^0.2.0",
+            "url-parse": "^1.5.3"
+          }
+        },
+        "tr46": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
+          "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
+          "dev": true,
+          "requires": {
+            "punycode": "^2.1.1"
+          }
+        },
+        "webidl-conversions": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
+          "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
+          "dev": true
+        },
+        "whatwg-url": {
+          "version": "8.7.0",
+          "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz",
+          "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==",
+          "dev": true,
+          "requires": {
+            "lodash": "^4.7.0",
+            "tr46": "^2.1.0",
+            "webidl-conversions": "^6.1.0"
+          }
+        },
+        "ws": {
+          "version": "7.5.9",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
+          "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
+          "dev": true,
+          "requires": {}
         }
       }
     },
@@ -14884,12 +15234,6 @@
       "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
       "dev": true
     },
-    "json-schema": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
-      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
-      "dev": true
-    },
     "json-schema-traverse": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -14899,35 +15243,14 @@
     "json-stable-stringify-without-jsonify": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
-      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
-      "dev": true
-    },
-    "json-stringify-safe": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+      "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
       "dev": true
     },
     "json5": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
-      "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
-      "dev": true,
-      "requires": {
-        "minimist": "^1.2.5"
-      }
-    },
-    "jsprim": {
-      "version": "1.4.2",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
-      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
-      "dev": true,
-      "requires": {
-        "assert-plus": "1.0.0",
-        "extsprintf": "1.3.0",
-        "json-schema": "0.4.0",
-        "verror": "1.10.0"
-      }
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+      "dev": true
     },
     "kind-of": {
       "version": "6.0.3",
@@ -14948,28 +15271,28 @@
       "dev": true
     },
     "levn": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
-      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+      "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
       "dev": true,
       "requires": {
-        "prelude-ls": "~1.1.2",
-        "type-check": "~0.3.2"
+        "prelude-ls": "^1.2.1",
+        "type-check": "~0.4.0"
       }
     },
     "lines-and-columns": {
-      "version": "1.1.6",
-      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
-      "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
       "dev": true
     },
     "locate-path": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
-      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+      "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
       "dev": true,
       "requires": {
-        "p-locate": "^4.1.0"
+        "p-locate": "^5.0.0"
       }
     },
     "lodash": {
@@ -14990,21 +15313,21 @@
       "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
     },
     "lru-cache": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
-      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
       "dev": true,
       "requires": {
-        "yallist": "^4.0.0"
+        "yallist": "^3.0.2"
       }
     },
     "magic-string": {
-      "version": "0.25.7",
-      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
-      "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
+      "version": "0.27.0",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz",
+      "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==",
       "dev": true,
       "requires": {
-        "sourcemap-codec": "^1.4.4"
+        "@jridgewell/sourcemap-codec": "^1.4.13"
       }
     },
     "make-dir": {
@@ -15014,6 +15337,14 @@
       "dev": true,
       "requires": {
         "semver": "^6.0.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
       }
     },
     "make-fetch-happen": {
@@ -15038,21 +15369,38 @@
         "promise-retry": "^2.0.1",
         "socks-proxy-agent": "^6.0.0",
         "ssri": "^8.0.0"
+      },
+      "dependencies": {
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "dev": true,
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+          "dev": true
+        }
       }
     },
     "makeerror": {
-      "version": "1.0.11",
-      "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz",
-      "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=",
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+      "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
       "dev": true,
       "requires": {
-        "tmpl": "1.0.x"
+        "tmpl": "1.0.5"
       }
     },
     "map-cache": {
       "version": "0.2.2",
       "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
-      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==",
       "dev": true
     },
     "map-obj": {
@@ -15064,7 +15412,7 @@
     "map-visit": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
-      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+      "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==",
       "dev": true,
       "requires": {
         "object-visit": "^1.0.0"
@@ -15090,47 +15438,11 @@
         "yargs-parser": "^20.2.3"
       },
       "dependencies": {
-        "hosted-git-info": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
-          "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
-          "dev": true,
-          "requires": {
-            "lru-cache": "^6.0.0"
-          }
-        },
-        "normalize-package-data": {
-          "version": "3.0.3",
-          "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
-          "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
-          "dev": true,
-          "requires": {
-            "hosted-git-info": "^4.0.1",
-            "is-core-module": "^2.5.0",
-            "semver": "^7.3.4",
-            "validate-npm-package-license": "^3.0.1"
-          }
-        },
-        "semver": {
-          "version": "7.3.7",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
-          "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
-          "dev": true,
-          "requires": {
-            "lru-cache": "^6.0.0"
-          }
-        },
         "type-fest": {
           "version": "0.18.1",
           "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
           "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
           "dev": true
-        },
-        "yargs-parser": {
-          "version": "20.2.9",
-          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
-          "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
-          "dev": true
         }
       }
     },
@@ -15147,36 +15459,28 @@
       "dev": true
     },
     "micromatch": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
-      "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
       "dev": true,
       "requires": {
-        "braces": "^3.0.1",
-        "picomatch": "^2.2.3"
-      },
-      "dependencies": {
-        "picomatch": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
-          "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
-          "dev": true
-        }
+        "braces": "^3.0.2",
+        "picomatch": "^2.3.1"
       }
     },
     "mime-db": {
-      "version": "1.45.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
-      "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==",
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
       "dev": true
     },
     "mime-types": {
-      "version": "2.1.28",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz",
-      "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==",
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
       "dev": true,
       "requires": {
-        "mime-db": "1.45.0"
+        "mime-db": "1.52.0"
       }
     },
     "mimic-fn": {
@@ -15192,17 +15496,17 @@
       "dev": true
     },
     "minimatch": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
       "requires": {
         "brace-expansion": "^1.1.7"
       }
     },
     "minimist": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
-      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
       "dev": true
     },
     "minimist-options": {
@@ -15217,12 +15521,20 @@
       }
     },
     "minipass": {
-      "version": "3.1.6",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz",
-      "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==",
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
       "dev": true,
       "requires": {
         "yallist": "^4.0.0"
+      },
+      "dependencies": {
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+          "dev": true
+        }
       }
     },
     "minipass-collect": {
@@ -15281,16 +15593,30 @@
       "requires": {
         "minipass": "^3.0.0",
         "yallist": "^4.0.0"
+      },
+      "dependencies": {
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+          "dev": true
+        }
       }
     },
     "mithril": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/mithril/-/mithril-2.2.0.tgz",
-      "integrity": "sha512-Dqdp2As819R5Wgtjbe+L2mww+K5/sVAqb4K/d4wmNg9Qp5IzzQbanbiU2l8GCWu/k44gClqDQBwNytEMLagVJQ==",
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/mithril/-/mithril-2.2.2.tgz",
+      "integrity": "sha512-YRm6eLv2UUaWaWHdH8L+desW9+DN7+oM34CxJv6tT2e1lNVue8bxQlknQeDRn9aKlO8sIujm2wqUHwM+Hb1wGQ==",
       "requires": {
         "ospec": "4.0.0"
       }
     },
+    "mitt": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz",
+      "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==",
+      "dev": true
+    },
     "mixin-deep": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
@@ -15299,19 +15625,14 @@
       "requires": {
         "for-in": "^1.0.2",
         "is-extendable": "^1.0.1"
-      },
-      "dependencies": {
-        "is-extendable": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
-          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
-          "dev": true,
-          "requires": {
-            "is-plain-object": "^2.0.4"
-          }
-        }
       }
     },
+    "mkdirp": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+      "dev": true
+    },
     "mkdirp-classic": {
       "version": "0.5.3",
       "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
@@ -15325,9 +15646,9 @@
       "dev": true
     },
     "nan": {
-      "version": "2.14.2",
-      "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
-      "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
+      "version": "2.17.0",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
+      "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==",
       "dev": true
     },
     "nanomatch": {
@@ -15352,7 +15673,13 @@
     "natural-compare": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
-      "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+      "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+      "dev": true
+    },
+    "natural-compare-lite": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
+      "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
       "dev": true
     },
     "negotiator": {
@@ -15374,30 +15701,6 @@
       "dev": true,
       "requires": {
         "whatwg-url": "^5.0.0"
-      },
-      "dependencies": {
-        "tr46": {
-          "version": "0.0.3",
-          "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-          "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
-          "dev": true
-        },
-        "webidl-conversions": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
-          "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
-          "dev": true
-        },
-        "whatwg-url": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
-          "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
-          "dev": true,
-          "requires": {
-            "tr46": "~0.0.3",
-            "webidl-conversions": "^3.0.0"
-          }
-        }
       }
     },
     "node-gyp": {
@@ -15419,9 +15722,9 @@
       },
       "dependencies": {
         "are-we-there-yet": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz",
-          "integrity": "sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==",
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
+          "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
           "dev": true,
           "requires": {
             "delegates": "^1.0.0",
@@ -15455,48 +15758,13 @@
             "gauge": "^4.0.3",
             "set-blocking": "^2.0.0"
           }
-        },
-        "readable-stream": {
-          "version": "3.6.0",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
-          "dev": true,
-          "requires": {
-            "inherits": "^2.0.3",
-            "string_decoder": "^1.1.1",
-            "util-deprecate": "^1.0.1"
-          }
-        },
-        "semver": {
-          "version": "7.3.7",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
-          "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
-          "dev": true,
-          "requires": {
-            "lru-cache": "^6.0.0"
-          }
-        },
-        "which": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-          "dev": true,
-          "requires": {
-            "isexe": "^2.0.0"
-          }
         }
       }
     },
     "node-int64": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
-      "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=",
-      "dev": true
-    },
-    "node-modules-regexp": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
-      "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=",
+      "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
       "dev": true
     },
     "node-notifier": {
@@ -15514,38 +15782,25 @@
         "which": "^2.0.2"
       },
       "dependencies": {
-        "semver": {
-          "version": "7.3.5",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-          "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+        "uuid": {
+          "version": "8.3.2",
+          "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+          "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
           "dev": true,
-          "optional": true,
-          "requires": {
-            "lru-cache": "^6.0.0"
-          }
-        },
-        "which": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "isexe": "^2.0.0"
-          }
+          "optional": true
         }
       }
     },
     "node-releases": {
-      "version": "1.1.72",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz",
-      "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==",
+      "version": "2.0.10",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz",
+      "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==",
       "dev": true
     },
     "node-sass": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-7.0.1.tgz",
-      "integrity": "sha512-uMy+Xt29NlqKCFdFRZyXKOTqGt+QaKHexv9STj2WeLottnlqZEEWx6Bj0MXNthmFRRdM/YwyNo/8Tr46TOM0jQ==",
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-8.0.0.tgz",
+      "integrity": "sha512-jPzqCF2/e6JXw6r3VxfIqYc8tKQdkj5Z/BDATYyG6FL6b/LuYBNFGFVhus0mthcWifHm/JzBpKAd+3eXsWeK/A==",
       "dev": true,
       "requires": {
         "async-foreach": "^0.1.3",
@@ -15555,63 +15810,197 @@
         "get-stdin": "^4.0.1",
         "glob": "^7.0.3",
         "lodash": "^4.17.15",
+        "make-fetch-happen": "^10.0.4",
         "meow": "^9.0.0",
-        "nan": "^2.13.2",
+        "nan": "^2.17.0",
         "node-gyp": "^8.4.1",
-        "npmlog": "^5.0.0",
-        "request": "^2.88.0",
-        "sass-graph": "4.0.0",
+        "sass-graph": "^4.0.1",
         "stdout-stream": "^1.4.0",
-        "true-case-path": "^1.0.2"
+        "true-case-path": "^2.2.1"
       },
       "dependencies": {
-        "cross-spawn": {
-          "version": "7.0.3",
-          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-          "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+        "@npmcli/fs": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz",
+          "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==",
           "dev": true,
           "requires": {
-            "path-key": "^3.1.0",
-            "shebang-command": "^2.0.0",
-            "which": "^2.0.1"
+            "@gar/promisify": "^1.1.3",
+            "semver": "^7.3.5"
           }
         },
-        "path-key": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-          "dev": true
+        "@npmcli/move-file": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz",
+          "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==",
+          "dev": true,
+          "requires": {
+            "mkdirp": "^1.0.4",
+            "rimraf": "^3.0.2"
+          }
         },
-        "shebang-command": {
+        "@tootallnate/once": {
           "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-          "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
-          "dev": true,
-          "requires": {
-            "shebang-regex": "^3.0.0"
-          }
-        },
-        "shebang-regex": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-          "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+          "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
+          "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
           "dev": true
         },
-        "which": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+        "brace-expansion": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+          "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
           "dev": true,
           "requires": {
-            "isexe": "^2.0.0"
+            "balanced-match": "^1.0.0"
+          }
+        },
+        "cacache": {
+          "version": "16.1.3",
+          "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz",
+          "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==",
+          "dev": true,
+          "requires": {
+            "@npmcli/fs": "^2.1.0",
+            "@npmcli/move-file": "^2.0.0",
+            "chownr": "^2.0.0",
+            "fs-minipass": "^2.1.0",
+            "glob": "^8.0.1",
+            "infer-owner": "^1.0.4",
+            "lru-cache": "^7.7.1",
+            "minipass": "^3.1.6",
+            "minipass-collect": "^1.0.2",
+            "minipass-flush": "^1.0.5",
+            "minipass-pipeline": "^1.2.4",
+            "mkdirp": "^1.0.4",
+            "p-map": "^4.0.0",
+            "promise-inflight": "^1.0.1",
+            "rimraf": "^3.0.2",
+            "ssri": "^9.0.0",
+            "tar": "^6.1.11",
+            "unique-filename": "^2.0.0"
+          },
+          "dependencies": {
+            "glob": {
+              "version": "8.1.0",
+              "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+              "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+              "dev": true,
+              "requires": {
+                "fs.realpath": "^1.0.0",
+                "inflight": "^1.0.4",
+                "inherits": "2",
+                "minimatch": "^5.0.1",
+                "once": "^1.3.0"
+              }
+            }
+          }
+        },
+        "http-proxy-agent": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
+          "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
+          "dev": true,
+          "requires": {
+            "@tootallnate/once": "2",
+            "agent-base": "6",
+            "debug": "4"
+          }
+        },
+        "lru-cache": {
+          "version": "7.18.3",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+          "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+          "dev": true
+        },
+        "make-fetch-happen": {
+          "version": "10.2.1",
+          "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz",
+          "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==",
+          "dev": true,
+          "requires": {
+            "agentkeepalive": "^4.2.1",
+            "cacache": "^16.1.0",
+            "http-cache-semantics": "^4.1.0",
+            "http-proxy-agent": "^5.0.0",
+            "https-proxy-agent": "^5.0.0",
+            "is-lambda": "^1.0.1",
+            "lru-cache": "^7.7.1",
+            "minipass": "^3.1.6",
+            "minipass-collect": "^1.0.2",
+            "minipass-fetch": "^2.0.3",
+            "minipass-flush": "^1.0.5",
+            "minipass-pipeline": "^1.2.4",
+            "negotiator": "^0.6.3",
+            "promise-retry": "^2.0.1",
+            "socks-proxy-agent": "^7.0.0",
+            "ssri": "^9.0.0"
+          }
+        },
+        "minimatch": {
+          "version": "5.1.6",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+          "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^2.0.1"
+          }
+        },
+        "minipass-fetch": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz",
+          "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==",
+          "dev": true,
+          "requires": {
+            "encoding": "^0.1.13",
+            "minipass": "^3.1.6",
+            "minipass-sized": "^1.0.3",
+            "minizlib": "^2.1.2"
+          }
+        },
+        "socks-proxy-agent": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz",
+          "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==",
+          "dev": true,
+          "requires": {
+            "agent-base": "^6.0.2",
+            "debug": "^4.3.3",
+            "socks": "^2.6.2"
+          }
+        },
+        "ssri": {
+          "version": "9.0.1",
+          "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz",
+          "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==",
+          "dev": true,
+          "requires": {
+            "minipass": "^3.1.1"
+          }
+        },
+        "unique-filename": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz",
+          "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==",
+          "dev": true,
+          "requires": {
+            "unique-slug": "^3.0.0"
+          }
+        },
+        "unique-slug": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz",
+          "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==",
+          "dev": true,
+          "requires": {
+            "imurmurhash": "^0.1.4"
           }
         }
       }
     },
     "node-watch": {
-      "version": "0.7.1",
-      "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.1.tgz",
-      "integrity": "sha512-UWblPYuZYrkCQCW5PxAwYSxaELNBLUckrTBBk8xr1/bUgyOkYYTsUcV4e3ytcazFEOyiRyiUrsG37pu6I0I05g==",
+      "version": "0.7.3",
+      "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.3.tgz",
+      "integrity": "sha512-3l4E8uMPY1HdMMryPRUAl+oIHtXtyiTlIiESNSVSNxcPfzAFzeTbXFQkZfAwBbo0B1qMSG8nUABx+Gd+YrbKrQ==",
       "dev": true
     },
     "noice-json-rpc": {
@@ -15629,23 +16018,15 @@
       }
     },
     "normalize-package-data": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
-      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
+      "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
       "dev": true,
       "requires": {
-        "hosted-git-info": "^2.1.4",
-        "resolve": "^1.10.0",
-        "semver": "2 || 3 || 4 || 5",
+        "hosted-git-info": "^4.0.1",
+        "is-core-module": "^2.5.0",
+        "semver": "^7.3.4",
         "validate-npm-package-license": "^3.0.1"
-      },
-      "dependencies": {
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-          "dev": true
-        }
       }
     },
     "normalize-path": {
@@ -15655,48 +16036,24 @@
       "dev": true
     },
     "npm-run-path": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
-      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
       "dev": true,
       "requires": {
-        "path-key": "^2.0.0"
-      }
-    },
-    "npmlog": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
-      "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
-      "dev": true,
-      "requires": {
-        "are-we-there-yet": "^2.0.0",
-        "console-control-strings": "^1.1.0",
-        "gauge": "^3.0.0",
-        "set-blocking": "^2.0.0"
+        "path-key": "^3.0.0"
       }
     },
     "nwsapi": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
-      "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
-      "dev": true
-    },
-    "oauth-sign": {
-      "version": "0.9.0",
-      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
-      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
-      "dev": true
-    },
-    "object-assign": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz",
+      "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==",
       "dev": true
     },
     "object-copy": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
-      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==",
       "dev": true,
       "requires": {
         "copy-descriptor": "^0.1.0",
@@ -15707,16 +16064,53 @@
         "define-property": {
           "version": "0.2.5",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
           "dev": true,
           "requires": {
             "is-descriptor": "^0.1.0"
           }
         },
+        "is-accessor-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+          "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+          "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^0.1.6",
+            "is-data-descriptor": "^0.1.4",
+            "kind-of": "^5.0.0"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "5.1.0",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+              "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+              "dev": true
+            }
+          }
+        },
         "kind-of": {
           "version": "3.2.2",
           "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
           "dev": true,
           "requires": {
             "is-buffer": "^1.1.5"
@@ -15724,40 +16118,19 @@
         }
       }
     },
-    "object-inspect": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-      "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw=="
-    },
-    "object-keys": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
-      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
-    },
     "object-visit": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
-      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==",
       "dev": true,
       "requires": {
         "isobject": "^3.0.0"
       }
     },
-    "object.assign": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-      "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
-      "requires": {
-        "call-bind": "^1.0.0",
-        "define-properties": "^1.1.3",
-        "has-symbols": "^1.0.1",
-        "object-keys": "^1.1.1"
-      }
-    },
     "object.pick": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
-      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+      "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==",
       "dev": true,
       "requires": {
         "isobject": "^3.0.1"
@@ -15766,7 +16139,7 @@
     "once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
       "requires": {
         "wrappy": "1"
       }
@@ -15781,17 +16154,17 @@
       }
     },
     "optionator": {
-      "version": "0.8.3",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
-      "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+      "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
       "dev": true,
       "requires": {
-        "deep-is": "~0.1.3",
-        "fast-levenshtein": "~2.0.6",
-        "levn": "~0.3.0",
-        "prelude-ls": "~1.1.2",
-        "type-check": "~0.3.2",
-        "word-wrap": "~1.2.3"
+        "deep-is": "^0.1.3",
+        "fast-levenshtein": "^2.0.6",
+        "levn": "^0.4.1",
+        "prelude-ls": "^1.2.1",
+        "type-check": "^0.4.0",
+        "word-wrap": "^1.2.3"
       }
     },
     "ospec": {
@@ -15811,25 +16184,25 @@
     "p-finally": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
-      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+      "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
       "dev": true
     },
     "p-limit": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
       "dev": true,
       "requires": {
-        "p-try": "^2.0.0"
+        "yocto-queue": "^0.1.0"
       }
     },
     "p-locate": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
-      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+      "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
       "dev": true,
       "requires": {
-        "p-limit": "^2.2.0"
+        "p-limit": "^3.0.2"
       }
     },
     "p-map": {
@@ -15882,7 +16255,7 @@
     "pascalcase": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
-      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==",
       "dev": true
     },
     "path-exists": {
@@ -15894,12 +16267,12 @@
     "path-is-absolute": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
     },
     "path-key": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
-      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
       "dev": true
     },
     "path-parse": {
@@ -15917,45 +16290,34 @@
     "pend": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
-      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+      "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
       "dev": true
     },
-    "performance-now": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
-      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+    "picocolors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
       "dev": true
     },
     "picomatch": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
-      "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
       "dev": true
     },
     "pirates": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz",
-      "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==",
-      "dev": true,
-      "requires": {
-        "node-modules-regexp": "^1.0.0"
-      }
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
+      "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
+      "dev": true
     },
     "pixelmatch": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.2.1.tgz",
-      "integrity": "sha512-WjcAdYSnKrrdDdqTcVEY7aB7UhhwjYQKYhHiBXdJef0MOaQeYpUdQ+iVyBLa5YBKS8MPVPPMX7rpOByISLpeEQ==",
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.3.0.tgz",
+      "integrity": "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==",
       "dev": true,
       "requires": {
-        "pngjs": "^4.0.1"
-      },
-      "dependencies": {
-        "pngjs": {
-          "version": "4.0.1",
-          "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-4.0.1.tgz",
-          "integrity": "sha512-rf5+2/ioHeQxR6IxuYNYGFytUyG3lma/WW1nsmjeHlWwtb2aByla6dkVc8pmJ9nplzkTA0q2xx7mMWrOTqT4Gg==",
-          "dev": true
-        }
+        "pngjs": "^6.0.0"
       }
     },
     "pkg-dir": {
@@ -15965,6 +16327,45 @@
       "dev": true,
       "requires": {
         "find-up": "^4.0.0"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        }
       }
     },
     "pngjs": {
@@ -15976,19 +16377,19 @@
     "posix-character-classes": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
-      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+      "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==",
       "dev": true
     },
     "prelude-ls": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
-      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+      "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
       "dev": true
     },
     "prettier": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.0.tgz",
-      "integrity": "sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==",
+      "version": "2.8.7",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz",
+      "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==",
       "dev": true
     },
     "pretty-format": {
@@ -16018,7 +16419,7 @@
     "promise-inflight": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
-      "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
+      "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
       "dev": true
     },
     "promise-retry": {
@@ -16032,9 +16433,9 @@
       }
     },
     "prompts": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz",
-      "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==",
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
+      "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
       "dev": true,
       "requires": {
         "kleur": "^3.0.3",
@@ -16042,9 +16443,9 @@
       }
     },
     "protobufjs": {
-      "version": "6.10.2",
-      "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz",
-      "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==",
+      "version": "6.11.3",
+      "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz",
+      "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==",
       "requires": {
         "@protobufjs/aspromise": "^1.1.2",
         "@protobufjs/base64": "^1.1.2",
@@ -16057,15 +16458,8 @@
         "@protobufjs/pool": "^1.1.0",
         "@protobufjs/utf8": "^1.1.0",
         "@types/long": "^4.0.1",
-        "@types/node": "^13.7.0",
+        "@types/node": ">=13.7.0",
         "long": "^4.0.0"
-      },
-      "dependencies": {
-        "@types/node": {
-          "version": "13.13.41",
-          "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.41.tgz",
-          "integrity": "sha512-qLT9IvHiXJfdrje9VmsLzun7cQ65obsBTmtU3EOnCSLFOoSHx1hpiRHoBnpdbyFqnzqdUUIv81JcEJQCB8un9g=="
-        }
       }
     },
     "proxy-from-env": {
@@ -16075,9 +16469,9 @@
       "dev": true
     },
     "psl": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
-      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
+      "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
       "dev": true
     },
     "pump": {
@@ -16091,50 +16485,63 @@
       }
     },
     "punycode": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+      "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
       "dev": true
     },
     "puppeteer": {
-      "version": "14.1.0",
-      "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-14.1.0.tgz",
-      "integrity": "sha512-T3eB4f6k9HVttYvyy8drGIKb04M+vxhepqM7qqcVCBTNT3T6M9cUaJT4k7P+a6wSonObJSJUP98JkPDQG+3fJw==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-19.8.0.tgz",
+      "integrity": "sha512-MpQClmttCUxv4bVokX/YSXLCU12CUApuRf0rIJyGknYcIrDQNkLUx1N7hNt88Ya4lq9VDsdiDEJ3bcPijqJYPQ==",
       "dev": true,
       "requires": {
-        "cross-fetch": "3.1.5",
-        "debug": "4.3.4",
-        "devtools-protocol": "0.0.982423",
-        "extract-zip": "2.0.1",
+        "cosmiconfig": "8.1.3",
         "https-proxy-agent": "5.0.1",
-        "pkg-dir": "4.2.0",
         "progress": "2.0.3",
         "proxy-from-env": "1.1.0",
-        "rimraf": "3.0.2",
-        "tar-fs": "2.1.1",
-        "unbzip2-stream": "1.4.3",
-        "ws": "8.6.0"
+        "puppeteer-core": "19.8.0"
       },
       "dependencies": {
+        "chromium-bidi": {
+          "version": "0.4.5",
+          "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.5.tgz",
+          "integrity": "sha512-rkav9YzRfAshSTG3wNXF7P7yNiI29QAo1xBXElPoCoSQR5n20q3cOyVhDv6S7+GlF/CJ/emUxlQiR0xOPurkGg==",
+          "dev": true,
+          "requires": {
+            "mitt": "3.0.0"
+          }
+        },
         "devtools-protocol": {
-          "version": "0.0.982423",
-          "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.982423.tgz",
-          "integrity": "sha512-FnVW2nDbjGNw1uD/JRC+9U5768W7e1TfUwqbDTcSsAu1jXFjITSX8w3rkW5FEpHRMPPGpvNSmO1pOpqByiWscA==",
+          "version": "0.0.1107588",
+          "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1107588.tgz",
+          "integrity": "sha512-yIR+pG9x65Xko7bErCUSQaDLrO/P1p3JUzEk7JCU4DowPcGHkTGUGQapcfcLc4qj0UaALwZ+cr0riFgiqpixcg==",
           "dev": true
         },
-        "ws": {
-          "version": "8.6.0",
-          "resolved": "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz",
-          "integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==",
+        "puppeteer-core": {
+          "version": "19.8.0",
+          "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-19.8.0.tgz",
+          "integrity": "sha512-5gBkLR9nae7chWDhI3mpj5QA+hPmjEOW29qw5ap5g51Uo5Lxe5Yip1uyQwZSjg5Wn/eyE9grh2Lyx3m8rPK90A==",
           "dev": true,
-          "requires": {}
+          "requires": {
+            "chromium-bidi": "0.4.5",
+            "cross-fetch": "3.1.5",
+            "debug": "4.3.4",
+            "devtools-protocol": "0.0.1107588",
+            "extract-zip": "2.0.1",
+            "https-proxy-agent": "5.0.1",
+            "proxy-from-env": "1.1.0",
+            "tar-fs": "2.1.1",
+            "unbzip2-stream": "1.4.3",
+            "ws": "8.13.0"
+          }
         }
       }
     },
-    "qs": {
-      "version": "6.5.3",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
-      "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
+    "querystringify": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
+      "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
       "dev": true
     },
     "queue-microtask": {
@@ -16167,6 +16574,30 @@
         "type-fest": "^0.6.0"
       },
       "dependencies": {
+        "hosted-git-info": {
+          "version": "2.8.9",
+          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+          "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+          "dev": true
+        },
+        "normalize-package-data": {
+          "version": "2.5.0",
+          "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+          "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+          "dev": true,
+          "requires": {
+            "hosted-git-info": "^2.1.4",
+            "resolve": "^1.10.0",
+            "semver": "2 || 3 || 4 || 5",
+            "validate-npm-package-license": "^3.0.1"
+          }
+        },
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "dev": true
+        },
         "type-fest": {
           "version": "0.6.0",
           "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
@@ -16184,29 +16615,62 @@
         "find-up": "^4.1.0",
         "read-pkg": "^5.2.0",
         "type-fest": "^0.8.1"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "type-fest": {
+          "version": "0.8.1",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+          "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+          "dev": true
+        }
       }
     },
     "readable-stream": {
-      "version": "2.3.7",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
-      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+      "version": "3.6.2",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
       "dev": true,
       "requires": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.3",
-        "isarray": "~1.0.0",
-        "process-nextick-args": "~2.0.0",
-        "safe-buffer": "~5.1.1",
-        "string_decoder": "~1.1.1",
-        "util-deprecate": "~1.0.1"
-      },
-      "dependencies": {
-        "safe-buffer": {
-          "version": "5.1.2",
-          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-          "dev": true
-        }
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
       }
     },
     "redent": {
@@ -16229,16 +16693,10 @@
         "safe-regex": "^1.1.0"
       }
     },
-    "regexpp": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
-      "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
-      "dev": true
-    },
     "remove-trailing-separator": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
-      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+      "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
       "dev": true
     },
     "repeat-element": {
@@ -16250,59 +16708,13 @@
     "repeat-string": {
       "version": "1.6.1",
       "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
-      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+      "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
       "dev": true
     },
-    "request": {
-      "version": "2.88.2",
-      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
-      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
-      "dev": true,
-      "requires": {
-        "aws-sign2": "~0.7.0",
-        "aws4": "^1.8.0",
-        "caseless": "~0.12.0",
-        "combined-stream": "~1.0.6",
-        "extend": "~3.0.2",
-        "forever-agent": "~0.6.1",
-        "form-data": "~2.3.2",
-        "har-validator": "~5.1.3",
-        "http-signature": "~1.2.0",
-        "is-typedarray": "~1.0.0",
-        "isstream": "~0.1.2",
-        "json-stringify-safe": "~5.0.1",
-        "mime-types": "~2.1.19",
-        "oauth-sign": "~0.9.0",
-        "performance-now": "^2.1.0",
-        "qs": "~6.5.2",
-        "safe-buffer": "^5.1.2",
-        "tough-cookie": "~2.5.0",
-        "tunnel-agent": "^0.6.0",
-        "uuid": "^3.3.2"
-      },
-      "dependencies": {
-        "tough-cookie": {
-          "version": "2.5.0",
-          "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
-          "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
-          "dev": true,
-          "requires": {
-            "psl": "^1.1.28",
-            "punycode": "^2.1.1"
-          }
-        },
-        "uuid": {
-          "version": "3.4.0",
-          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
-          "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
-          "dev": true
-        }
-      }
-    },
     "require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
       "dev": true
     },
     "require-main-filename": {
@@ -16311,14 +16723,21 @@
       "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
       "dev": true
     },
+    "requires-port": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+      "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+      "dev": true
+    },
     "resolve": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
-      "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
+      "version": "1.22.1",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+      "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
       "dev": true,
       "requires": {
-        "is-core-module": "^2.1.0",
-        "path-parse": "^1.0.6"
+        "is-core-module": "^2.9.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
       }
     },
     "resolve-cwd": {
@@ -16328,18 +16747,26 @@
       "dev": true,
       "requires": {
         "resolve-from": "^5.0.0"
+      },
+      "dependencies": {
+        "resolve-from": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+          "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+          "dev": true
+        }
       }
     },
     "resolve-from": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
-      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
       "dev": true
     },
     "resolve-url": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
-      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==",
       "dev": true
     },
     "ret": {
@@ -16351,7 +16778,7 @@
     "retry": {
       "version": "0.12.0",
       "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
-      "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
+      "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
       "dev": true
     },
     "reusify": {
@@ -16370,18 +16797,18 @@
       }
     },
     "rollup": {
-      "version": "2.38.5",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.38.5.tgz",
-      "integrity": "sha512-VoWt8DysFGDVRGWuHTqZzT02J0ASgjVq/hPs9QcBOGMd7B+jfTr/iqMVEyOi901rE3xq+Deq66GzIT1yt7sGwQ==",
+      "version": "2.79.1",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
+      "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
       "dev": true,
       "requires": {
-        "fsevents": "~2.3.1"
+        "fsevents": "~2.3.2"
       }
     },
     "rollup-plugin-re": {
       "version": "1.0.7",
       "resolved": "https://registry.npmjs.org/rollup-plugin-re/-/rollup-plugin-re-1.0.7.tgz",
-      "integrity": "sha1-/hdHBO1ZzahMrwK9ATtYLm/apPY=",
+      "integrity": "sha512-TyFf3QaV/eJ/50k4wp5BM0SodGy0Idq0uOgvA1q3gHRwgXLPVX5y3CRKkBuHzKTZPC9CTZX7igKw5UvgjDls8w==",
       "dev": true,
       "requires": {
         "magic-string": "^0.16.0",
@@ -16391,7 +16818,7 @@
         "magic-string": {
           "version": "0.16.0",
           "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.16.0.tgz",
-          "integrity": "sha1-lw67DacZMwEoX7GqZQ85vdgetFo=",
+          "integrity": "sha512-c4BEos3y6G2qO0B9X7K0FVLOPT9uGrjYwYRLFmDqyl5YMboUviyecnXWp94fJTSMwPw2/sf+CEYt5AGpmklkkQ==",
           "dev": true,
           "requires": {
             "vlq": "^0.2.1"
@@ -16407,18 +16834,6 @@
       "requires": {
         "@rollup/pluginutils": "^3.0.9",
         "source-map-resolve": "^0.6.0"
-      },
-      "dependencies": {
-        "source-map-resolve": {
-          "version": "0.6.0",
-          "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz",
-          "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==",
-          "dev": true,
-          "requires": {
-            "atob": "^2.1.2",
-            "decode-uri-component": "^0.2.0"
-          }
-        }
       }
     },
     "rollup-pluginutils": {
@@ -16456,12 +16871,13 @@
     "safe-buffer": {
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
-      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+      "dev": true
     },
     "safe-regex": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
-      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==",
       "dev": true,
       "requires": {
         "ret": "~0.1.10"
@@ -16521,7 +16937,7 @@
             "extend-shallow": {
               "version": "2.0.1",
               "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
               "dev": true,
               "requires": {
                 "is-extendable": "^0.1.0"
@@ -16529,10 +16945,38 @@
             }
           }
         },
+        "cross-spawn": {
+          "version": "6.0.5",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+          "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+          "dev": true,
+          "requires": {
+            "nice-try": "^1.0.4",
+            "path-key": "^2.0.1",
+            "semver": "^5.5.0",
+            "shebang-command": "^1.2.0",
+            "which": "^1.2.9"
+          }
+        },
+        "execa": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+          "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^6.0.0",
+            "get-stream": "^4.0.0",
+            "is-stream": "^1.1.0",
+            "npm-run-path": "^2.0.0",
+            "p-finally": "^1.0.0",
+            "signal-exit": "^3.0.0",
+            "strip-eof": "^1.0.0"
+          }
+        },
         "fill-range": {
           "version": "4.0.0",
           "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
-          "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+          "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==",
           "dev": true,
           "requires": {
             "extend-shallow": "^2.0.1",
@@ -16544,7 +16988,7 @@
             "extend-shallow": {
               "version": "2.0.1",
               "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
               "dev": true,
               "requires": {
                 "is-extendable": "^0.1.0"
@@ -16552,10 +16996,25 @@
             }
           }
         },
+        "get-stream": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+          "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+          "dev": true,
+          "requires": {
+            "pump": "^3.0.0"
+          }
+        },
+        "is-extendable": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+          "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+          "dev": true
+        },
         "is-number": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
-          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
           "dev": true,
           "requires": {
             "kind-of": "^3.0.2"
@@ -16564,7 +17023,7 @@
             "kind-of": {
               "version": "3.2.2",
               "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
               "dev": true,
               "requires": {
                 "is-buffer": "^1.1.5"
@@ -16572,6 +17031,12 @@
             }
           }
         },
+        "is-stream": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+          "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
+          "dev": true
+        },
         "micromatch": {
           "version": "3.1.10",
           "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
@@ -16596,44 +17061,89 @@
         "normalize-path": {
           "version": "2.1.1",
           "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
-          "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+          "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==",
           "dev": true,
           "requires": {
             "remove-trailing-separator": "^1.0.1"
           }
         },
+        "npm-run-path": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+          "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
+          "dev": true,
+          "requires": {
+            "path-key": "^2.0.0"
+          }
+        },
+        "path-key": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+          "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+          "dev": true
+        },
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "dev": true
+        },
+        "shebang-command": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+          "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+          "dev": true,
+          "requires": {
+            "shebang-regex": "^1.0.0"
+          }
+        },
+        "shebang-regex": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+          "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
+          "dev": true
+        },
         "to-regex-range": {
           "version": "2.1.1",
           "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
-          "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+          "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==",
           "dev": true,
           "requires": {
             "is-number": "^3.0.0",
             "repeat-string": "^1.6.1"
           }
+        },
+        "which": {
+          "version": "1.3.1",
+          "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+          "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
         }
       }
     },
     "sass-graph": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-4.0.0.tgz",
-      "integrity": "sha512-WSO/MfXqKH7/TS8RdkCX3lVkPFQzCgbqdGsmSKq6tlPU+GpGEsa/5aW18JqItnqh+lPtcjifqdZ/VmiILkKckQ==",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-4.0.1.tgz",
+      "integrity": "sha512-5YCfmGBmxoIRYHnKK2AKzrAkCoQ8ozO+iumT8K4tXJXRVCPf+7s1/9KxTSW3Rbvf+7Y7b4FR3mWyLnQr3PHocA==",
       "dev": true,
       "requires": {
         "glob": "^7.0.0",
         "lodash": "^4.17.11",
-        "scss-tokenizer": "^0.3.0",
+        "scss-tokenizer": "^0.4.3",
         "yargs": "^17.2.1"
       },
       "dependencies": {
         "cliui": {
-          "version": "7.0.4",
-          "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-          "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+          "version": "8.0.1",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+          "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
           "dev": true,
           "requires": {
             "string-width": "^4.2.0",
-            "strip-ansi": "^6.0.0",
+            "strip-ansi": "^6.0.1",
             "wrap-ansi": "^7.0.0"
           }
         },
@@ -16655,24 +17165,24 @@
           "dev": true
         },
         "yargs": {
-          "version": "17.5.0",
-          "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.0.tgz",
-          "integrity": "sha512-3sLxVhbAB5OC8qvVRebCLWuouhwh/rswsiDYx3WGxajUk/l4G20SKfrKKFeNIHboUFt2JFgv2yfn+5cgOr/t5A==",
+          "version": "17.7.1",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz",
+          "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
           "dev": true,
           "requires": {
-            "cliui": "^7.0.2",
+            "cliui": "^8.0.1",
             "escalade": "^3.1.1",
             "get-caller-file": "^2.0.5",
             "require-directory": "^2.1.1",
             "string-width": "^4.2.3",
             "y18n": "^5.0.5",
-            "yargs-parser": "^21.0.0"
+            "yargs-parser": "^21.1.1"
           }
         },
         "yargs-parser": {
-          "version": "21.0.1",
-          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
-          "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==",
+          "version": "21.1.1",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+          "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
           "dev": true
         }
       }
@@ -16687,33 +17197,53 @@
       }
     },
     "scss-tokenizer": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.3.0.tgz",
-      "integrity": "sha512-14Zl9GcbBvOT9057ZKjpz5yPOyUWG2ojd9D5io28wHRYsOrs7U95Q+KNL87+32p8rc+LvDpbu/i9ZYjM9Q+FsQ==",
+      "version": "0.4.3",
+      "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.4.3.tgz",
+      "integrity": "sha512-raKLgf1LI5QMQnG+RxHz6oK0sL3x3I4FN2UDLqgLOGO8hodECNnNh5BXn7fAyBxrA8zVzdQizQ6XjNJQ+uBwMw==",
       "dev": true,
       "requires": {
-        "js-base64": "^2.4.3",
-        "source-map": "^0.7.1"
+        "js-base64": "^2.4.9",
+        "source-map": "^0.7.3"
       },
       "dependencies": {
         "source-map": {
-          "version": "0.7.3",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
-          "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+          "version": "0.7.4",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+          "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
           "dev": true
         }
       }
     },
     "semver": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-      "dev": true
+      "version": "7.3.8",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+      "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+      "dev": true,
+      "requires": {
+        "lru-cache": "^6.0.0"
+      },
+      "dependencies": {
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "dev": true,
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+          "dev": true
+        }
+      }
     },
     "set-blocking": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+      "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
       "dev": true
     },
     "set-value": {
@@ -16731,27 +17261,33 @@
         "extend-shallow": {
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
           "dev": true,
           "requires": {
             "is-extendable": "^0.1.0"
           }
+        },
+        "is-extendable": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+          "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+          "dev": true
         }
       }
     },
     "shebang-command": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
-      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
       "dev": true,
       "requires": {
-        "shebang-regex": "^1.0.0"
+        "shebang-regex": "^3.0.0"
       }
     },
     "shebang-regex": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
-      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
       "dev": true
     },
     "shellwords": {
@@ -16813,7 +17349,7 @@
         "define-property": {
           "version": "0.2.5",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
           "dev": true,
           "requires": {
             "is-descriptor": "^0.1.0"
@@ -16822,23 +17358,99 @@
         "extend-shallow": {
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
           "dev": true,
           "requires": {
             "is-extendable": "^0.1.0"
           }
         },
+        "is-accessor-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+          "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+              "dev": true,
+              "requires": {
+                "is-buffer": "^1.1.5"
+              }
+            }
+          }
+        },
+        "is-data-descriptor": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+          "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+              "dev": true,
+              "requires": {
+                "is-buffer": "^1.1.5"
+              }
+            }
+          }
+        },
+        "is-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^0.1.6",
+            "is-data-descriptor": "^0.1.4",
+            "kind-of": "^5.0.0"
+          }
+        },
+        "is-extendable": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+          "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        },
         "ms": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
           "dev": true
         },
         "source-map": {
           "version": "0.5.7",
           "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
           "dev": true
+        },
+        "source-map-resolve": {
+          "version": "0.5.3",
+          "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+          "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+          "dev": true,
+          "requires": {
+            "atob": "^2.1.2",
+            "decode-uri-component": "^0.2.0",
+            "resolve-url": "^0.2.1",
+            "source-map-url": "^0.4.0",
+            "urix": "^0.1.0"
+          }
         }
       }
     },
@@ -16856,40 +17468,11 @@
         "define-property": {
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
           "dev": true,
           "requires": {
             "is-descriptor": "^1.0.0"
           }
-        },
-        "is-accessor-descriptor": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
-          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
-          "dev": true,
-          "requires": {
-            "kind-of": "^6.0.0"
-          }
-        },
-        "is-data-descriptor": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
-          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
-          "dev": true,
-          "requires": {
-            "kind-of": "^6.0.0"
-          }
-        },
-        "is-descriptor": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
-          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
-          "dev": true,
-          "requires": {
-            "is-accessor-descriptor": "^1.0.0",
-            "is-data-descriptor": "^1.0.0",
-            "kind-of": "^6.0.2"
-          }
         }
       }
     },
@@ -16905,7 +17488,7 @@
         "kind-of": {
           "version": "3.2.2",
           "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
           "dev": true,
           "requires": {
             "is-buffer": "^1.1.5"
@@ -16914,19 +17497,19 @@
       }
     },
     "socks": {
-      "version": "2.6.2",
-      "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz",
-      "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==",
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
+      "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
       "dev": true,
       "requires": {
-        "ip": "^1.1.5",
+        "ip": "^2.0.0",
         "smart-buffer": "^4.2.0"
       }
     },
     "socks-proxy-agent": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz",
-      "integrity": "sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ==",
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
+      "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
       "dev": true,
       "requires": {
         "agent-base": "^6.0.2",
@@ -16941,22 +17524,19 @@
       "dev": true
     },
     "source-map-resolve": {
-      "version": "0.5.3",
-      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
-      "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz",
+      "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==",
       "dev": true,
       "requires": {
         "atob": "^2.1.2",
-        "decode-uri-component": "^0.2.0",
-        "resolve-url": "^0.2.1",
-        "source-map-url": "^0.4.0",
-        "urix": "^0.1.0"
+        "decode-uri-component": "^0.2.0"
       }
     },
     "source-map-support": {
-      "version": "0.5.19",
-      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
-      "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+      "version": "0.5.21",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
       "dev": true,
       "requires": {
         "buffer-from": "^1.0.0",
@@ -16969,16 +17549,10 @@
       "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
       "dev": true
     },
-    "sourcemap-codec": {
-      "version": "1.4.8",
-      "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
-      "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
-      "dev": true
-    },
     "spdx-correct": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
-      "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
+      "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
       "dev": true,
       "requires": {
         "spdx-expression-parse": "^3.0.0",
@@ -17002,9 +17576,9 @@
       }
     },
     "spdx-license-ids": {
-      "version": "3.0.7",
-      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz",
-      "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==",
+      "version": "3.0.13",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz",
+      "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==",
       "dev": true
     },
     "split-string": {
@@ -17019,26 +17593,9 @@
     "sprintf-js": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
       "dev": true
     },
-    "sshpk": {
-      "version": "1.17.0",
-      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
-      "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
-      "dev": true,
-      "requires": {
-        "asn1": "~0.2.3",
-        "assert-plus": "^1.0.0",
-        "bcrypt-pbkdf": "^1.0.0",
-        "dashdash": "^1.12.0",
-        "ecc-jsbn": "~0.1.1",
-        "getpass": "^0.1.1",
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.0.2",
-        "tweetnacl": "~0.14.0"
-      }
-    },
     "ssri": {
       "version": "8.0.1",
       "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
@@ -17049,9 +17606,9 @@
       }
     },
     "stack-utils": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz",
-      "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==",
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+      "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
       "dev": true,
       "requires": {
         "escape-string-regexp": "^2.0.0"
@@ -17068,7 +17625,7 @@
     "static-extend": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
-      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+      "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==",
       "dev": true,
       "requires": {
         "define-property": "^0.2.5",
@@ -17078,11 +17635,68 @@
         "define-property": {
           "version": "0.2.5",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
           "dev": true,
           "requires": {
             "is-descriptor": "^0.1.0"
           }
+        },
+        "is-accessor-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+          "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+              "dev": true,
+              "requires": {
+                "is-buffer": "^1.1.5"
+              }
+            }
+          }
+        },
+        "is-data-descriptor": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+          "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+              "dev": true,
+              "requires": {
+                "is-buffer": "^1.1.5"
+              }
+            }
+          }
+        },
+        "is-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^0.1.6",
+            "is-data-descriptor": "^0.1.4",
+            "kind-of": "^5.0.0"
+          }
+        },
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
         }
       }
     },
@@ -17093,25 +17707,49 @@
       "dev": true,
       "requires": {
         "readable-stream": "^2.0.1"
-      }
-    },
-    "string_decoder": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-      "dev": true,
-      "requires": {
-        "safe-buffer": "~5.1.0"
       },
       "dependencies": {
+        "readable-stream": {
+          "version": "2.3.8",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+          "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
         "safe-buffer": {
           "version": "5.1.2",
           "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
           "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
           "dev": true
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
         }
       }
     },
+    "string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
     "string-length": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
@@ -17133,24 +17771,6 @@
         "strip-ansi": "^6.0.1"
       }
     },
-    "string.prototype.trimend": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz",
-      "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==",
-      "requires": {
-        "call-bind": "^1.0.0",
-        "define-properties": "^1.1.3"
-      }
-    },
-    "string.prototype.trimstart": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz",
-      "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==",
-      "requires": {
-        "call-bind": "^1.0.0",
-        "define-properties": "^1.1.3"
-      }
-    },
     "strip-ansi": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -17169,7 +17789,7 @@
     "strip-eof": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
-      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+      "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==",
       "dev": true
     },
     "strip-final-newline": {
@@ -17203,15 +17823,21 @@
       }
     },
     "supports-hyperlinks": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz",
-      "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz",
+      "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==",
       "dev": true,
       "requires": {
         "has-flag": "^4.0.0",
         "supports-color": "^7.0.0"
       }
     },
+    "supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "dev": true
+    },
     "symbol-tree": {
       "version": "3.2.4",
       "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
@@ -17219,29 +17845,29 @@
       "dev": true
     },
     "tar": {
-      "version": "6.1.11",
-      "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
-      "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
+      "version": "6.1.13",
+      "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz",
+      "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==",
       "dev": true,
       "requires": {
         "chownr": "^2.0.0",
         "fs-minipass": "^2.0.0",
-        "minipass": "^3.0.0",
+        "minipass": "^4.0.0",
         "minizlib": "^2.1.1",
         "mkdirp": "^1.0.3",
         "yallist": "^4.0.0"
       },
       "dependencies": {
-        "chownr": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
-          "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+        "minipass": {
+          "version": "4.2.5",
+          "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz",
+          "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==",
           "dev": true
         },
-        "mkdirp": {
-          "version": "1.0.4",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
-          "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
           "dev": true
         }
       }
@@ -17256,6 +17882,14 @@
         "mkdirp-classic": "^0.5.2",
         "pump": "^3.0.0",
         "tar-stream": "^2.1.4"
+      },
+      "dependencies": {
+        "chownr": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+          "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+          "dev": true
+        }
       }
     },
     "tar-stream": {
@@ -17269,19 +17903,6 @@
         "fs-constants": "^1.0.0",
         "inherits": "^2.0.3",
         "readable-stream": "^3.1.1"
-      },
-      "dependencies": {
-        "readable-stream": {
-          "version": "3.6.0",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
-          "dev": true,
-          "requires": {
-            "inherits": "^2.0.3",
-            "string_decoder": "^1.1.1",
-            "util-deprecate": "^1.0.1"
-          }
-        }
       }
     },
     "terminal-link": {
@@ -17308,7 +17929,7 @@
     "text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
-      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+      "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
       "dev": true
     },
     "throat": {
@@ -17320,7 +17941,7 @@
     "through": {
       "version": "2.3.8",
       "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
       "dev": true
     },
     "tmpl": {
@@ -17332,13 +17953,13 @@
     "to-fast-properties": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
-      "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+      "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
       "dev": true
     },
     "to-object-path": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
-      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+      "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==",
       "dev": true,
       "requires": {
         "kind-of": "^3.0.2"
@@ -17347,7 +17968,7 @@
         "kind-of": {
           "version": "3.2.2",
           "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
           "dev": true,
           "requires": {
             "is-buffer": "^1.1.5"
@@ -17376,25 +17997,11 @@
         "is-number": "^7.0.0"
       }
     },
-    "tough-cookie": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
-      "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
-      "dev": true,
-      "requires": {
-        "psl": "^1.1.33",
-        "punycode": "^2.1.1",
-        "universalify": "^0.1.2"
-      }
-    },
     "tr46": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
-      "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
-      "dev": true,
-      "requires": {
-        "punycode": "^2.1.1"
-      }
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+      "dev": true
     },
     "trim-newlines": {
       "version": "3.0.1",
@@ -17403,42 +18010,24 @@
       "dev": true
     },
     "true-case-path": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
-      "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
-      "dev": true,
-      "requires": {
-        "glob": "^7.1.2"
-      }
-    },
-    "tslib": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz",
-      "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==",
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz",
+      "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==",
       "dev": true
     },
-    "tunnel-agent": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
-      "dev": true,
-      "requires": {
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "tweetnacl": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+    "tslib": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
+      "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==",
       "dev": true
     },
     "type-check": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
-      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+      "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
       "dev": true,
       "requires": {
-        "prelude-ls": "~1.1.2"
+        "prelude-ls": "^1.2.1"
       }
     },
     "type-detect": {
@@ -17448,9 +18037,9 @@
       "dev": true
     },
     "type-fest": {
-      "version": "0.8.1",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
-      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
       "dev": true
     },
     "typedarray-to-buffer": {
@@ -17463,9 +18052,9 @@
       }
     },
     "typescript": {
-      "version": "4.6.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz",
-      "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==",
+      "version": "4.9.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
+      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
       "dev": true
     },
     "unbzip2-stream": {
@@ -17488,6 +18077,14 @@
         "get-value": "^2.0.6",
         "is-extendable": "^0.1.1",
         "set-value": "^2.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+          "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+          "dev": true
+        }
       }
     },
     "unique-filename": {
@@ -17509,15 +18106,15 @@
       }
     },
     "universalify": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
-      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
+      "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
       "dev": true
     },
     "unset-value": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
-      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==",
       "dev": true,
       "requires": {
         "has-value": "^0.3.1",
@@ -17527,7 +18124,7 @@
         "has-value": {
           "version": "0.3.1",
           "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
-          "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+          "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==",
           "dev": true,
           "requires": {
             "get-value": "^2.0.3",
@@ -17538,7 +18135,7 @@
             "isobject": {
               "version": "2.1.0",
               "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
-              "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+              "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==",
               "dev": true,
               "requires": {
                 "isarray": "1.0.0"
@@ -17549,11 +18146,21 @@
         "has-values": {
           "version": "0.1.4",
           "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
-          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+          "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==",
           "dev": true
         }
       }
     },
+    "update-browserslist-db": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
+      "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
+      "dev": true,
+      "requires": {
+        "escalade": "^3.1.1",
+        "picocolors": "^1.0.0"
+      }
+    },
     "uri-js": {
       "version": "4.4.1",
       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -17566,9 +18173,19 @@
     "urix": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
-      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==",
       "dev": true
     },
+    "url-parse": {
+      "version": "1.5.10",
+      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
+      "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
+      "dev": true,
+      "requires": {
+        "querystringify": "^2.1.1",
+        "requires-port": "^1.0.0"
+      }
+    },
     "use": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
@@ -17576,34 +18193,27 @@
       "dev": true
     },
     "util": {
-      "version": "0.12.3",
-      "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz",
-      "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==",
+      "version": "0.12.5",
+      "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
+      "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
       "requires": {
         "inherits": "^2.0.3",
         "is-arguments": "^1.0.4",
         "is-generator-function": "^1.0.7",
         "is-typed-array": "^1.1.3",
-        "safe-buffer": "^5.1.2",
         "which-typed-array": "^1.1.2"
       }
     },
     "util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
       "dev": true
     },
     "uuid": {
-      "version": "8.3.2",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
-      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
-    },
-    "v8-compile-cache": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
-      "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
-      "dev": true
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
+      "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg=="
     },
     "v8-to-istanbul": {
       "version": "7.1.2",
@@ -17617,9 +18227,9 @@
       },
       "dependencies": {
         "source-map": {
-          "version": "0.7.3",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
-          "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+          "version": "0.7.4",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+          "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
           "dev": true
         }
       }
@@ -17634,17 +18244,6 @@
         "spdx-expression-parse": "^3.0.0"
       }
     },
-    "verror": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
-      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "^1.0.0",
-        "core-util-is": "1.0.2",
-        "extsprintf": "^1.2.0"
-      }
-    },
     "vlq": {
       "version": "0.2.3",
       "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz",
@@ -17670,18 +18269,18 @@
       }
     },
     "walker": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz",
-      "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=",
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
+      "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
       "dev": true,
       "requires": {
-        "makeerror": "1.0.x"
+        "makeerror": "1.0.12"
       }
     },
     "webidl-conversions": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
-      "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
       "dev": true
     },
     "whatwg-encoding": {
@@ -17691,6 +18290,17 @@
       "dev": true,
       "requires": {
         "iconv-lite": "0.4.24"
+      },
+      "dependencies": {
+        "iconv-lite": {
+          "version": "0.4.24",
+          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+          "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+          "dev": true,
+          "requires": {
+            "safer-buffer": ">= 2.1.2 < 3"
+          }
+        }
       }
     },
     "whatwg-mimetype": {
@@ -17700,20 +18310,19 @@
       "dev": true
     },
     "whatwg-url": {
-      "version": "8.5.0",
-      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.5.0.tgz",
-      "integrity": "sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
       "dev": true,
       "requires": {
-        "lodash": "^4.7.0",
-        "tr46": "^2.0.2",
-        "webidl-conversions": "^6.1.0"
+        "tr46": "~0.0.3",
+        "webidl-conversions": "^3.0.0"
       }
     },
     "which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
       "dev": true,
       "requires": {
         "isexe": "^2.0.0"
@@ -17722,21 +18331,20 @@
     "which-module": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
-      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+      "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==",
       "dev": true
     },
     "which-typed-array": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz",
-      "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==",
+      "version": "1.1.9",
+      "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
+      "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==",
       "requires": {
-        "available-typed-arrays": "^1.0.2",
-        "call-bind": "^1.0.0",
-        "es-abstract": "^1.18.0-next.1",
-        "foreach": "^2.0.5",
-        "function-bind": "^1.1.1",
-        "has-symbols": "^1.0.1",
-        "is-typed-array": "^1.1.3"
+        "available-typed-arrays": "^1.0.5",
+        "call-bind": "^1.0.2",
+        "for-each": "^0.3.3",
+        "gopd": "^1.0.1",
+        "has-tostringtag": "^1.0.0",
+        "is-typed-array": "^1.1.10"
       }
     },
     "wide-align": {
@@ -17768,7 +18376,7 @@
     "wrappy": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
     },
     "write-file-atomic": {
       "version": "3.0.3",
@@ -17783,9 +18391,9 @@
       }
     },
     "ws": {
-      "version": "7.4.6",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
-      "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
+      "version": "8.13.0",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
+      "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==",
       "dev": true,
       "requires": {}
     },
@@ -17802,15 +18410,15 @@
       "dev": true
     },
     "y18n": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
-      "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+      "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
       "dev": true
     },
     "yallist": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
       "dev": true
     },
     "yargs": {
@@ -17830,27 +18438,78 @@
         "which-module": "^2.0.0",
         "y18n": "^4.0.0",
         "yargs-parser": "^18.1.2"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "yargs-parser": {
+          "version": "18.1.3",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+          "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+          "dev": true,
+          "requires": {
+            "camelcase": "^5.0.0",
+            "decamelize": "^1.2.0"
+          }
+        }
       }
     },
     "yargs-parser": {
-      "version": "18.1.3",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
-      "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
-      "dev": true,
-      "requires": {
-        "camelcase": "^5.0.0",
-        "decamelize": "^1.2.0"
-      }
+      "version": "20.2.9",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+      "dev": true
     },
     "yauzl": {
       "version": "2.10.0",
       "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
-      "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
+      "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
       "dev": true,
       "requires": {
         "buffer-crc32": "~0.2.3",
         "fd-slicer": "~1.1.0"
       }
+    },
+    "yocto-queue": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+      "dev": true
     }
   }
 }
diff --git a/ui/package.json b/ui/package.json
index 98a2bd6..0f4d69b 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -30,31 +30,30 @@
     "pako": "^1.0.11",
     "protobufjs": "^6.9.0",
     "util": "^0.12.3",
-    "uuid": "^8.3.2"
+    "uuid": "^9.0.0"
   },
   "devDependencies": {
-    "@rollup/plugin-commonjs": "^14.0.0",
-    "@rollup/plugin-node-resolve": "^8.4.0",
+    "@rollup/plugin-commonjs": "^24.0.1",
+    "@rollup/plugin-node-resolve": "^15.0.1",
     "@types/jest": "^26.0.23",
     "@types/pixelmatch": "^5.2.3",
-    "@types/puppeteer": "^5.4.6",
-    "@typescript-eslint/eslint-plugin": "^5.25.0",
+    "@typescript-eslint/eslint-plugin": "^5.56.0",
     "@typescript-eslint/parser": "^5.25.0",
     "dingusjs": "^0.0.3",
     "eslint": "^8.15.0",
     "eslint-config-google": "^0.14.0",
     "jest": "^26.6.3",
-    "node-sass": "^7.0.1",
+    "node-sass": "^8.0.0",
     "node-watch": "^0.7.1",
     "pixelmatch": "^5.2.1",
     "pngjs": "^6.0.0",
     "prettier": "^2.8.0",
-    "puppeteer": "^14.1.0",
+    "puppeteer": "^19.8.0",
     "rollup": "^2.38.5",
     "rollup-plugin-re": "^1.0.7",
     "rollup-plugin-sourcemaps": "^0.6.3",
-    "tslib": "^2.2.0",
-    "typescript": "^4.6.4"
+    "tslib": "^2.5.0",
+    "typescript": "^4.9.5"
   },
   "scripts": {
     "build": "node build.js",
diff --git a/ui/src/assets/index.html b/ui/src/assets/index.html
index 817945f..dc3216e 100644
--- a/ui/src/assets/index.html
+++ b/ui/src/assets/index.html
@@ -37,9 +37,6 @@
 
 * Clear the site data and caches from devtools, following <a target="_blank" href="https://developers.google.com/web/tools/chrome-devtools/storage/cache#deletecache">these instructions</a>.
 
-* If neither of these work, you can use an old fallback instance hosted at
-  <a target="_blank" href="https://staging-dot-perfetto-ui.appspot.com">staging-dot-perfetto-ui.appspot.com</a>
-
 In any case, **FILE A BUG** attaching logs and screenshots from devtools.
   Googlers:      <a href="http://go/perfetto-ui-bug" target="_blank">go/perfetto-ui-bug</a>
   Non-googlers:  <a href="https://github.com/google/perfetto/issues/new" target="_blank">github.com/google/perfetto/issues/new</a>
diff --git a/ui/src/assets/perfetto.scss b/ui/src/assets/perfetto.scss
index 79c8350..7a00576 100644
--- a/ui/src/assets/perfetto.scss
+++ b/ui/src/assets/perfetto.scss
@@ -37,3 +37,4 @@
 @import "widgets/menu";
 @import "widgets/spinner";
 @import "widgets/tree";
+@import "widgets/switch";
diff --git a/ui/src/assets/topbar.scss b/ui/src/assets/topbar.scss
index 7742b5a..14a42b4 100644
--- a/ui/src/assets/topbar.scss
+++ b/ui/src/assets/topbar.scss
@@ -60,7 +60,7 @@
       }
       &::placeholder {
         color: #b4b7ba;
-        font-family: "Raleway", sans-serif;
+        font-family: "Roboto Condensed", sans-serif;
         font-weight: 400;
       }
     }
diff --git a/ui/src/assets/widgets/multiselect.scss b/ui/src/assets/widgets/multiselect.scss
index 1580e56..3988ede 100644
--- a/ui/src/assets/widgets/multiselect.scss
+++ b/ui/src/assets/widgets/multiselect.scss
@@ -46,6 +46,8 @@
     z-index: 1;
     font-size: 0.75em;
     border-bottom: solid 1px $pf-minimal-foreground;
+    padding-bottom: 2px;
+    min-width: max-content;
     & > span {
       margin-right: auto;
     }
diff --git a/ui/src/assets/widgets/switch.scss b/ui/src/assets/widgets/switch.scss
new file mode 100644
index 0000000..8c81c57
--- /dev/null
+++ b/ui/src/assets/widgets/switch.scss
@@ -0,0 +1,114 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+@import "theme";
+
+// This checkbox element is expected to contain a checkbox type input followed
+// by an empty span element.
+// The input is completely hidden and an entirely new checkbox is drawn inside
+// the span element. This allows us to style it how we like, and also add some
+// fancy transitions.
+// The box of the checkbox is a fixed sized span element. The tick is also a
+// fixed sized rectange rotated 45 degrees with only the bottom and right
+// borders visible.
+// When unchecked, the tick size and border width is 0, so the tick is
+// completely invsible. When we transition to checked, the border size on the
+// bottom and right sides is immmdiately set to full width, and the tick morphs
+// into view first by expanding along the x axis first, then expanding up the
+// y-axis. This has the effect of making the tick look like it's being drawn
+// onto the page with a pen.
+// When transitioning from checked to unchecked, the animation plays in reverse,
+// and the border width is set to 0 right at the end in order to make the tick
+// completely invisible again.
+.pf-switch {
+  display: inline-block;
+  position: relative; // Turns this container into a positioned element
+  font-family: $pf-font;
+  font-size: inherit;
+  color: $pf-minimal-foreground;
+  user-select: none;
+  cursor: pointer;
+  padding-left: 32px + 6px;
+
+  // Hide the default checkbox
+  input {
+    position: absolute;
+    opacity: 0;
+    pointer-events: none;
+  }
+
+  // The span forms the "box" of the checkbox
+  span {
+    position: absolute;
+    left: 0;
+    top: 0;
+    bottom: 0;
+    margin-top: auto;
+    margin-bottom: auto;
+    height: 16px;
+    width: 32px;
+    border-radius: 8px;
+    transition: background $pf-anim-timing;
+    background: grey;
+    vertical-align: middle;
+
+    // The :after element forms the "tick" of the checkbox
+    &:after {
+      content: "";
+      display: block;
+      position: absolute;
+      left: 2px;
+      top: 0;
+      bottom: 0;
+      margin-top: auto;
+      margin-bottom: auto;
+      width: 12px;
+      height: 12px;
+      background: $pf-primary-foreground;
+      box-sizing: border-box;
+      border-radius: 50%;
+      transition: left $pf-anim-timing;
+    }
+  }
+
+  input:checked + span {
+    background: $pf-primary-background;
+  }
+
+  input:checked + span:after {
+    left: 18px;
+  }
+
+  input:focus-visible + span {
+    @include focus;
+  }
+
+  &.pf-disabled {
+    cursor: not-allowed;
+    color: $pf-minimal-foreground-disabled;
+
+    span {
+      border-color: $pf-minimal-foreground-disabled;
+      background: $pf-minimal-foreground-disabled;
+      &:after {
+        border-color: $pf-minimal-foreground-disabled;
+      }
+    }
+
+    input:checked ~ span {
+      border-color: $pf-primary-background-disabled;
+      background: $pf-primary-background-disabled;
+    }
+  }
+}
diff --git a/ui/src/common/event_set.ts b/ui/src/common/event_set.ts
index 87e62d5..3971fd8 100644
--- a/ui/src/common/event_set.ts
+++ b/ui/src/common/event_set.ts
@@ -43,7 +43,6 @@
 export interface EmptyKeySet extends KeySet {
   readonly id: typeof IdType;
 }
-;
 
 // A particular key/value pair on an Event matches the relevant entry
 // on the KeySet if the KeyType and the value type 'match':
diff --git a/ui/src/common/feature_flags.ts b/ui/src/common/feature_flags.ts
index cb22c07..de2cc7c 100644
--- a/ui/src/common/feature_flags.ts
+++ b/ui/src/common/feature_flags.ts
@@ -83,8 +83,11 @@
   allFlags(): Flag[] {
     const includeDevFlags =
         ['127.0.0.1', '::1', 'localhost'].includes(window.location.hostname);
-    return [...this.flags.values()].filter(
-        (flag) => includeDevFlags || !flag.devOnly);
+
+    let flags = [...this.flags.values()];
+    flags = flags.filter((flag) => includeDevFlags || !flag.devOnly);
+    flags.sort((a, b) => a.name.localeCompare(b.name));
+    return flags;
   }
 
   resetAll() {
diff --git a/ui/src/common/query_result.ts b/ui/src/common/query_result.ts
index 9d44c9e..708a0ab 100644
--- a/ui/src/common/query_result.ts
+++ b/ui/src/common/query_result.ts
@@ -49,6 +49,14 @@
 
 import * as protobuf from 'protobufjs/minimal';
 
+// Disable Long.js support in protobuf. This seems to be enabled only in tests
+// but not in production code. In any case, for now we want casting to number
+// accepting the 2**53 limitation. This is consistent with passing
+// --force-number in the protobuf.js codegen invocation in //ui/BUILD.gn .
+// See also https://github.com/protobufjs/protobuf.js/issues/1253 .
+protobuf.util.Long = undefined as any;
+protobuf.configure();
+
 import {defer, Deferred} from '../base/deferred';
 import {assertExists, assertFalse, assertTrue} from '../base/logging';
 import {utf8Decode} from '../base/string_utils';
@@ -147,14 +155,6 @@
   }
 }
 
-// Disable Long.js support in protobuf. This seems to be enabled only in tests
-// but not in production code. In any case, for now we want casting to number
-// accepting the 2**53 limitation. This is consistent with passing
-// --force-number in the protobuf.js codegen invocation in //ui/BUILD.gn .
-// See also https://github.com/protobufjs/protobuf.js/issues/1253 .
-(protobuf.util as {} as {Long: undefined}).Long = undefined;
-protobuf.configure();
-
 // This has to match CellType in trace_processor.proto.
 enum CellType {
   CELL_NULL = 1,
diff --git a/ui/src/common/recordingV2/auth/adb_key_manager.ts b/ui/src/common/recordingV2/auth/adb_key_manager.ts
index 0359417..73575ea 100644
--- a/ui/src/common/recordingV2/auth/adb_key_manager.ts
+++ b/ui/src/common/recordingV2/auth/adb_key_manager.ts
@@ -51,7 +51,7 @@
 export class AdbKeyManager {
   private key?: AdbKey;
   // Id of timer used to expire the key kept in memory.
-  private keyInMemoryTimerId?: number;
+  private keyInMemoryTimerId?: ReturnType<typeof setTimeout>;
 
   // Finds a key, by priority:
   // - looking in memory (i.e. this.key)
@@ -93,7 +93,7 @@
       clearTimeout(this.keyInMemoryTimerId);
     }
     this.keyInMemoryTimerId =
-        window.setTimeout(() => this.key = undefined, KEY_IN_MEMORY_TIMEOUT);
+        setTimeout(() => this.key = undefined, KEY_IN_MEMORY_TIMEOUT);
     return key;
   }
 }
diff --git a/ui/src/controller/metrics_controller.ts b/ui/src/controller/metrics_controller.ts
index 594d04c..236503d 100644
--- a/ui/src/controller/metrics_controller.ts
+++ b/ui/src/controller/metrics_controller.ts
@@ -37,7 +37,7 @@
       const metricResult = await this.engine.computeMetric([name]);
       publishMetricResult({
         name,
-        resultString: metricResult.metricsAsPrototext,
+        resultString: metricResult.metricsAsPrototext || undefined,
       });
     } catch (e) {
       if (e instanceof QueryError) {
diff --git a/ui/src/controller/trace_controller.ts b/ui/src/controller/trace_controller.ts
index 421874b..f57105d 100644
--- a/ui/src/controller/trace_controller.ts
+++ b/ui/src/controller/trace_controller.ts
@@ -122,8 +122,9 @@
 ];
 const FLAGGED_METRICS: Array<[Flag, string]> = METRICS.map((m) => {
   const id = `forceMetric${m}`;
-  let name = m.split('_').join(' ') + ' metric';
+  let name = m.split('_').join(' ');
   name = name[0].toUpperCase() + name.slice(1);
+  name = 'Metric: ' + name;
   const flag = featureFlags.register({
     id,
     name,
diff --git a/ui/src/controller/trace_stream.ts b/ui/src/controller/trace_stream.ts
index a980665..6ccb3d0 100644
--- a/ui/src/controller/trace_stream.ts
+++ b/ui/src/controller/trace_stream.ts
@@ -100,7 +100,7 @@
   private bytesRead = 0;
   private bytesTotal = 0;
   private uri: string;
-  private httpStream?: ReadableStreamReader<Uint8Array>;
+  private httpStream?: ReadableStreamDefaultReader<Uint8Array>;
 
   constructor(uri: string) {
     assertTrue(uri.startsWith('http://') || uri.startsWith('https://'));
diff --git a/ui/src/controller/track_controller.ts b/ui/src/controller/track_controller.ts
index cf9c3fd..46d1f1f 100644
--- a/ui/src/controller/track_controller.ts
+++ b/ui/src/controller/track_controller.ts
@@ -35,7 +35,8 @@
 // TrackController is a base class overridden by track implementations (e.g.,
 // sched slices, nestable slices, counters).
 export abstract class TrackController<
-    Config, Data extends TrackData = TrackData> extends Controller<'main'> {
+    Config extends TrackConfig, Data extends TrackData = TrackData> extends
+    Controller<'main'> {
   readonly trackId: string;
   readonly engine: Engine;
   private data?: TrackData;
diff --git a/ui/src/controller/track_decider.ts b/ui/src/controller/track_decider.ts
index c0fdd2c..241e248 100644
--- a/ui/src/controller/track_decider.ts
+++ b/ui/src/controller/track_decider.ts
@@ -63,13 +63,6 @@
 import {PROCESS_SUMMARY_TRACK} from '../tracks/process_summary';
 import {THREAD_STATE_TRACK_KIND} from '../tracks/thread_state';
 
-const NULL_TRACKS_FLAG = featureFlags.register({
-  id: 'nullTracks',
-  name: 'Null tracks',
-  description: 'Display some empty tracks.',
-  defaultValue: false,
-});
-
 const TRACKS_V2_FLAG = featureFlags.register({
   id: 'tracksV2.1',
   name: 'Tracks V2',
@@ -198,26 +191,6 @@
     return 'Unknown';
   }
 
-  addNullTracks(): void {
-    this.tracksToAdd.push({
-      engineId: this.engineId,
-      kind: NULL_TRACK_KIND,
-      trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
-      name: `Null track foo`,
-      trackGroup: SCROLLING_TRACK_GROUP,
-      config: {},
-    });
-
-    this.tracksToAdd.push({
-      engineId: this.engineId,
-      kind: NULL_TRACK_KIND,
-      trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
-      name: `Null track bar`,
-      trackGroup: SCROLLING_TRACK_GROUP,
-      config: {},
-    });
-  }
-
   async addCpuSchedulingTracks(): Promise<void> {
     const cpus = await this.engine.getCpus();
     for (const cpu of cpus) {
@@ -339,7 +312,7 @@
     for (; it.valid(); it.next()) {
       const kind = ASYNC_SLICE_TRACK_KIND;
       const rawName = it.name === null ? undefined : it.name;
-      const rawParentName = it.parentName === null ? undefined : it.name;
+      const rawParentName = it.parentName === null ? undefined : it.parentName;
       const name = TrackDecider.getTrackName({name: rawName, kind});
       const rawTrackIds = it.trackIds;
       const trackIds = rawTrackIds.split(',').map((v) => Number(v));
@@ -1762,13 +1735,9 @@
   }
 
   async decideTracks(): Promise<DeferredAction[]> {
-    // Add first the global tracks that don't require per-process track groups.
-    if (NULL_TRACKS_FLAG.get()) {
-      await this.addNullTracks();
-    }
-
     await this.defineMaxLayoutDepthSqlFunction();
 
+    // Add first the global tracks that don't require per-process track groups.
     await this.addCpuSchedulingTracks();
     await this.addFtraceTrack(
         this.engine.getProxy('TrackDecider::addFtraceTrack'));
diff --git a/ui/src/frontend/analytics.ts b/ui/src/frontend/analytics.ts
index e49ca11..3fe2e94 100644
--- a/ui/src/frontend/analytics.ts
+++ b/ui/src/frontend/analytics.ts
@@ -13,9 +13,9 @@
 // limitations under the License.
 
 import {getCurrentChannel} from '../common/channels';
-import {globals} from '../frontend/globals';
 import * as version from '../gen/perfetto_version';
 
+import {globals} from './globals';
 import {Router} from './router';
 
 type TraceCategories = 'Trace Actions'|'Record Trace'|'User Actions';
diff --git a/ui/src/frontend/bottom_tab.ts b/ui/src/frontend/bottom_tab.ts
index 0aa3c7e..4e4d822 100644
--- a/ui/src/frontend/bottom_tab.ts
+++ b/ui/src/frontend/bottom_tab.ts
@@ -119,7 +119,9 @@
   abstract viewTab(): void|m.Children;
 
   createPanelVnode(): m.Vnode<any, any> {
-    return m(BottomTabAdapter, {key: this.uuid, panel: this});
+    return m(
+        BottomTabAdapter,
+        {key: this.uuid, panel: this} as BottomTabAdapterAttrs);
   }
 }
 
diff --git a/ui/src/frontend/index.ts b/ui/src/frontend/index.ts
index e58a03b..baebced 100644
--- a/ui/src/frontend/index.ts
+++ b/ui/src/frontend/index.ts
@@ -12,6 +12,9 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+// Need to turn off Long
+import '../common/query_result';
+
 import {Patch, produce} from 'immer';
 import * as m from 'mithril';
 
diff --git a/ui/src/frontend/rate_limiters.ts b/ui/src/frontend/rate_limiters.ts
index ae212d4..babf3f4 100644
--- a/ui/src/frontend/rate_limiters.ts
+++ b/ui/src/frontend/rate_limiters.ts
@@ -20,7 +20,7 @@
       return;
     }
     inProgess = true;
-    window.setTimeout(() => {
+    setTimeout(() => {
       f();
       inProgess = false;
     }, ms);
@@ -30,12 +30,12 @@
 // Returns a wrapper around |f| which waits for a |ms|ms pause in calls
 // before calling |f|.
 export function debounce(f: Function, ms: number): Function {
-  let timerId: undefined|number;
+  let timerId: undefined|ReturnType<typeof setTimeout>;
   return () => {
     if (timerId) {
-      window.clearTimeout(timerId);
+      clearTimeout(timerId);
     }
-    timerId = window.setTimeout(() => {
+    timerId = setTimeout(() => {
       f();
       timerId = undefined;
     }, ms);
diff --git a/ui/src/frontend/track_group_panel.ts b/ui/src/frontend/track_group_panel.ts
index 07a7a2f..114bd23 100644
--- a/ui/src/frontend/track_group_panel.ts
+++ b/ui/src/frontend/track_group_panel.ts
@@ -245,18 +245,8 @@
           size.height,
           `#344596`);
     }
+
     if (globals.state.currentSelection !== null) {
-      if (globals.state.currentSelection.kind === 'NOTE') {
-        const note = globals.state.notes[globals.state.currentSelection.id];
-        if (note.noteType === 'DEFAULT') {
-          drawVerticalLineAtTime(
-              ctx,
-              localState.timeScale,
-              note.timestamp,
-              size.height,
-              note.color);
-        }
-      }
       if (globals.state.currentSelection.kind === 'SLICE' &&
           globals.sliceDetails.wakeupTs !== undefined) {
         drawVerticalLineAtTime(
@@ -287,6 +277,9 @@
             size.height,
             transparentNoteColor,
             1);
+      } else if (note.noteType === 'DEFAULT') {
+        drawVerticalLineAtTime(
+            ctx, localState.timeScale, note.timestamp, size.height, note.color);
       }
     }
   }
diff --git a/ui/src/frontend/track_panel.ts b/ui/src/frontend/track_panel.ts
index 0aecc27..109549e 100644
--- a/ui/src/frontend/track_panel.ts
+++ b/ui/src/frontend/track_panel.ts
@@ -399,19 +399,8 @@
           size.height,
           `#344596`);
     }
-    if (globals.state.currentSelection !== null) {
-      if (globals.state.currentSelection.kind === 'NOTE') {
-        const note = globals.state.notes[globals.state.currentSelection.id];
-        if (note.noteType === 'DEFAULT') {
-          drawVerticalLineAtTime(
-              ctx,
-              localState.timeScale,
-              note.timestamp,
-              size.height,
-              note.color);
-        }
-      }
 
+    if (globals.state.currentSelection !== null) {
       if (globals.state.currentSelection.kind === 'SLICE' &&
           globals.sliceDetails.wakeupTs !== undefined) {
         drawVerticalLineAtTime(
@@ -442,6 +431,9 @@
             size.height,
             transparentNoteColor,
             1);
+      } else if (note.noteType === 'DEFAULT') {
+        drawVerticalLineAtTime(
+            ctx, localState.timeScale, note.timestamp, size.height, note.color);
       }
     }
   }
diff --git a/ui/src/frontend/widgets/multiselect.ts b/ui/src/frontend/widgets/multiselect.ts
index 84c788b..d9bb0a1 100644
--- a/ui/src/frontend/widgets/multiselect.ts
+++ b/ui/src/frontend/widgets/multiselect.ts
@@ -125,7 +125,8 @@
                         this.searchText === '' ? 'Selected' :
                                                  `Selected (Filtered)`),
                       m(Button, {
-                        label: 'Clear All',
+                        label: this.searchText === '' ? 'Clear All' :
+                                                        'Clear Filtered',
                         icon: DESELECT,
                         minimal: true,
                         onclick: () => {
@@ -148,9 +149,11 @@
                   m('span',
                     this.searchText === '' ? 'Options' : `Options (Filtered)`),
                   m(Button, {
-                    label: 'Select All',
+                    label: this.searchText === '' ? 'Select All' :
+                                                    'Select Filtered',
                     icon: SELECT_ALL,
                     minimal: true,
+                    compact: true,
                     onclick: () => {
                       const diffs = options.filter(({checked}) => !checked)
                                         .map(({id}) => ({id, checked: true}));
@@ -160,9 +163,11 @@
                     disabled: allChecked,
                   }),
                   m(Button, {
-                    label: 'Select None',
+                    label: this.searchText === '' ? 'Clear All' :
+                                                    'Clear Filtered',
                     icon: DESELECT,
                     minimal: true,
+                    compact: true,
                     onclick: () => {
                       const diffs = options.filter(({checked}) => checked)
                                         .map(({id}) => ({id, checked: false}));
@@ -188,7 +193,7 @@
             globals.rafScheduler.scheduleFullRedraw();
           },
           value: this.searchText,
-          placeholder: 'Search...',
+          placeholder: 'Filter options...',
           extraClasses: 'pf-search-box',
         }),
         this.renderClearButton(),
diff --git a/ui/src/frontend/widgets/switch.ts b/ui/src/frontend/widgets/switch.ts
new file mode 100644
index 0000000..94a6b27
--- /dev/null
+++ b/ui/src/frontend/widgets/switch.ts
@@ -0,0 +1,51 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as m from 'mithril';
+import {classNames} from '../classnames';
+
+export interface SwitchAttrs {
+  // Optional text to show to the right of the switch.
+  // If omitted, no text will be shown.
+  label?: string;
+  // Whether the switch is checked or not.
+  // If omitted, the switch will be uncontrolled.
+  checked?: boolean;
+  // Make the switch appear greyed out block any interaction with it.
+  // No events will be fired when interacting with it.
+  // Defaults to false.
+  disabled?: boolean;
+  // Remaining attributes forwarded to the underlying HTML <label>.
+  [htmlAttrs: string]: any;
+}
+
+export class Switch implements m.ClassComponent<SwitchAttrs> {
+  view({attrs}: m.CVnode<SwitchAttrs>) {
+    const {label, checked, disabled = false, ...htmlAttrs} = attrs;
+
+    const classes = classNames(
+        disabled && 'pf-disabled',
+    );
+
+    // The default checkbox is removed and an entirely new one created inside
+    // the span element in CSS.
+    return m(
+        'label.pf-switch',
+        {class: classes, ...htmlAttrs},
+        m('input[type=checkbox]', {disabled, checked}),
+        m('span'),
+        label,
+    );
+  }
+}
diff --git a/ui/src/frontend/widgets_page.ts b/ui/src/frontend/widgets_page.ts
index 1e58405..9b3028a 100644
--- a/ui/src/frontend/widgets_page.ts
+++ b/ui/src/frontend/widgets_page.ts
@@ -31,6 +31,7 @@
 import {Portal} from './widgets/portal';
 import {Select} from './widgets/select';
 import {Spinner} from './widgets/spinner';
+import {Switch} from './widgets/switch';
 import {TextInput} from './widgets/text_input';
 import {Tree, TreeLayout, TreeNode} from './widgets/tree';
 
@@ -272,6 +273,15 @@
             disabled: false,
           },
         }),
+        m('h2', 'Switch'),
+        m(WidgetShowcase, {
+          renderWidget: ({label, ...rest}: any) =>
+              m(Switch, {label: label ? 'Switch' : undefined, ...rest}),
+          initialOpts: {
+            label: true,
+            disabled: false,
+          },
+        }),
         m('h2', 'Text Input'),
         m(WidgetShowcase, {
           renderWidget: ({placeholder, ...rest}) => m(TextInput, {
@@ -403,7 +413,7 @@
           initialOpts: {
             icon: true,
             showNumSelected: true,
-            repeatCheckedItemsAtTop: true,
+            repeatCheckedItemsAtTop: false,
           },
         }),
         m('h2', 'PopupMenu'),
diff --git a/ui/src/test/perfetto_ui_test_helper.ts b/ui/src/test/perfetto_ui_test_helper.ts
index 97c9bd4..9657b58 100644
--- a/ui/src/test/perfetto_ui_test_helper.ts
+++ b/ui/src/test/perfetto_ui_test_helper.ts
@@ -19,8 +19,6 @@
 import {PNG} from 'pngjs';
 import * as puppeteer from 'puppeteer';
 
-console.log(PNG);
-
 // These constants have been hand selected by comparing the diffs of screenshots
 // between Linux on Mac. Unfortunately font-rendering is platform-specific.
 // Even though we force the same antialiasing and hinting settings, some minimal
@@ -49,7 +47,7 @@
     const hasPendingRedraws =
         await (
             await page.evaluateHandle('globals.rafScheduler.hasPendingRedraws'))
-            .jsonValue<number>();
+            .jsonValue();
 
     if (isShowingAnim || isShowingMsg || hasPendingRedraws) {
       consecutiveIdleTicks = 0;