Scouting: Add ability to scout offline

Signed-off-by: Filip Kujawa <filip.j.kujawa@gmail.com>
Change-Id: I0e0c0be033824c05b6c239d38eb79d95745fceec
diff --git a/scouting/www/defs.bzl b/scouting/www/defs.bzl
index 828f30a..e7fb44a 100644
--- a/scouting/www/defs.bzl
+++ b/scouting/www/defs.bzl
@@ -27,6 +27,7 @@
         ),
         "pictures": attr.label_list(
             mandatory = True,
+            allow_files = True,
         ),
         "replace_prefixes": attr.string_dict(
             mandatory = True,
@@ -34,3 +35,45 @@
     },
     toolchains = ["@aspect_bazel_lib//lib:copy_to_directory_toolchain_type"],
 )
+
+def _assemble_service_worker_files_impl(ctx):
+    args = ctx.actions.args()
+    args.add_all(ctx.attr._package.files, before_each = "--input_dir", expand_directories = False)
+    args.add_all(ctx.outputs.outs, before_each = "--output")
+    args.add_all(ctx.attr.outs_as_strings, before_each = "--relative_output")
+    ctx.actions.run(
+        inputs = ctx.attr._package.files,
+        outputs = ctx.outputs.outs,
+        executable = ctx.executable._tool,
+        arguments = [args],
+        mnemonic = "AssembleAngularServiceWorker",
+    )
+
+_assemble_service_worker_files = rule(
+    implementation = _assemble_service_worker_files_impl,
+    attrs = {
+        "outs": attr.output_list(
+            allow_empty = False,
+            mandatory = True,
+        ),
+        "outs_as_strings": attr.string_list(
+            allow_empty = False,
+            mandatory = True,
+        ),
+        "_package": attr.label(
+            default = "//:node_modules/@angular/service-worker",
+        ),
+        "_tool": attr.label(
+            default = "//tools/build_rules/js:assemble_service_worker_files",
+            cfg = "exec",
+            executable = True,
+        ),
+    },
+)
+
+def assemble_service_worker_files(outs, **kwargs):
+    _assemble_service_worker_files(
+        outs = outs,
+        outs_as_strings = outs,
+        **kwargs
+    )