Provide offline version of foxglove

This may be useful at events and in places with bad internet, and also
lets me pull in https://github.com/foxglove/studio/pull/5323 a few hours
early.

Change-Id: I584dda8fe7903a9a8d2876fa3a0ea318fa319180
Signed-off-by: James Kuszmaul <jabukuszmaul+collab@gmail.com>
diff --git a/WORKSPACE b/WORKSPACE
index aa92b7e..d6a50c7 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1345,3 +1345,23 @@
     strip_prefix = "schemas-7a3e077b88142ac46bb4e2616f83dc029b45352e/schemas/flatbuffer",
     url = "https://github.com/foxglove/schemas/archive/7a3e077b88142ac46bb4e2616f83dc029b45352e.tar.gz",
 )
+
+# This contains the *compiled* foxglove studio. This can be reproduced by:
+# 1. Cloning https://github.com/foxglove/studio
+# 2. Building the code (yarn web:build:prod)
+# 3. tar'ing the web/.webpack folder
+# These files can be hosted locally to provide an offline foxglove server.
+# Foxglove may be served on any port and may be nested at a subpath
+# (e.g., at hostname:8000/foxglove behind a proxy).
+http_archive(
+    name = "foxglove_studio",
+    build_file_content = """
+filegroup(
+    name = "foxglove_studio",
+    srcs = glob(["**"]),
+    visibility = ["//visibility:public"],
+)""",
+    sha256 = "629b150e4c71679e1ac30b8a2dfa558a04bbcca7ad0edd61bd6878d3b243edb6",
+    url =
+        "https://www.frc971.org/Build-Dependencies/foxglove-d6b00825.tar.gz",
+)
diff --git a/aos/network/BUILD b/aos/network/BUILD
index 4794838..f05a75e 100644
--- a/aos/network/BUILD
+++ b/aos/network/BUILD
@@ -482,6 +482,7 @@
         exclude = ["www/**/*"],
     ),
     target_compatible_with = ["@platforms//os:linux"],
+    visibility = ["//visibility:public"],
 )
 
 cc_binary(
diff --git a/frc971/analysis/BUILD b/frc971/analysis/BUILD
index b50e84e..c1ae252 100644
--- a/frc971/analysis/BUILD
+++ b/frc971/analysis/BUILD
@@ -187,3 +187,15 @@
         "//frc971/input:joystick_state_fbs",
     ],
 )
+
+cc_binary(
+    name = "local_foxglove",
+    srcs = ["local_foxglove.cc"],
+    data = ["@foxglove_studio"],
+    deps = [
+        "//aos:init",
+        "//aos/network:gen_embedded",
+        "//aos/seasocks:seasocks_logger",
+        "//third_party/seasocks",
+    ],
+)
diff --git a/frc971/analysis/local_foxglove.cc b/frc971/analysis/local_foxglove.cc
new file mode 100644
index 0000000..33e5a8b
--- /dev/null
+++ b/frc971/analysis/local_foxglove.cc
@@ -0,0 +1,18 @@
+#include "aos/init.h"
+#include "aos/seasocks/seasocks_logger.h"
+#include "glog/logging.h"
+#include "internal/Embedded.h"
+#include "seasocks/Server.h"
+
+DEFINE_string(data_path, "external/foxglove_studio",
+              "Path to foxglove studio files to serve.");
+DEFINE_uint32(port, 8000, "Port to serve files at.");
+
+int main(int argc, char *argv[]) {
+  aos::InitGoogle(&argc, &argv);
+  // Magic for seasocks.
+  findEmbeddedContent("");
+  ::seasocks::Server server(std::make_shared<aos::seasocks::SeasocksLogger>(
+      ::seasocks::Logger::Level::Info));
+  server.serve(FLAGS_data_path.c_str(), FLAGS_port);
+}