merged
authorwenzelm
Thu, 10 Mar 2022 12:34:02 +0100
changeset 75260 5a15a2ceafdf
parent 75244 f70b1a2c2783 (current diff)
parent 75259 fd44e4559adb (diff)
child 75261 ed83c58c612a
merged
--- a/.hgignore	Wed Mar 09 16:21:58 2022 +0000
+++ b/.hgignore	Thu Mar 10 12:34:02 2022 +0100
@@ -6,6 +6,7 @@
 *.marks
 *.orig
 *.rej
+*.vsix
 .DS_Store
 .swp
 
@@ -16,6 +17,6 @@
 ^heaps/
 ^browser_info/
 ^doc/.*\.pdf
-^src/Tools/VSCode/out/
+^src/Tools/VSCode/extension/out/
 ^src/Tools/VSCode/extension/node_modules/
 ^Admin/jenkins/ci-extras/target/
--- a/etc/build.props	Wed Mar 09 16:21:58 2022 +0000
+++ b/etc/build.props	Thu Mar 10 12:34:02 2022 +0100
@@ -30,7 +30,6 @@
   src/Pure/Admin/build_status.scala \
   src/Pure/Admin/build_vampire.scala \
   src/Pure/Admin/build_verit.scala \
-  src/Pure/Admin/build_vscodium.scala \
   src/Pure/Admin/build_zipperposition.scala \
   src/Pure/Admin/check_sources.scala \
   src/Pure/Admin/ci_profile.scala \
@@ -212,7 +211,8 @@
   src/Tools/Graphview/popups.scala \
   src/Tools/Graphview/shapes.scala \
   src/Tools/Graphview/tree_panel.scala \
-  src/Tools/VSCode/src/build_vscode.scala \
+  src/Tools/VSCode/src/build_vscode_extension.scala \
+  src/Tools/VSCode/src/build_vscodium.scala \
   src/Tools/VSCode/src/channel.scala \
   src/Tools/VSCode/src/dynamic_output.scala \
   src/Tools/VSCode/src/language_server.scala \
--- a/lib/Tools/vscode	Wed Mar 09 16:21:58 2022 +0000
+++ b/lib/Tools/vscode	Thu Mar 10 12:34:02 2022 +0100
@@ -2,12 +2,11 @@
 #
 # Author: Makarius
 #
-# DESCRIPTION: run Isabelle/VSCode using local VSCodium installation
+# DESCRIPTION: run Isabelle/VSCode (requires "vscodium-X.YY.Z" component)
 
-export ISABELLE_VSCODE_SYMBOLS="$(platform_path "$ISABELLE_VSCODE_WORKSPACE/symbols.json")"
+isabelle vscode_setup || exit "$?"
 
-DIR="$(isabelle vscode_setup -C)" || exit "$?"
-exec "$DIR/bin/codium" \
+exec "$ISABELLE_VSCODIUM_HOME/bin/codium" \
   --locale en-US \
   --user-data-dir "$(platform_path "$ISABELLE_VSCODE_SETTINGS"/user-data)" \
   --extensions-dir "$(platform_path "$ISABELLE_VSCODE_SETTINGS"/extensions)" \
--- a/src/Pure/Admin/build_vscodium.scala	Wed Mar 09 16:21:58 2022 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,403 +0,0 @@
-/*  Title:      Pure/Admin/build_vscodium.scala
-    Author:     Makarius
-
-Build component for VSCodium (cross-compiled from sources for all platforms).
-*/
-
-package isabelle
-
-
-import java.util.{Map => JMap}
-import java.security.MessageDigest
-import java.util.Base64
-
-
-object Build_VSCodium
-{
-  /* global parameters */
-
-  lazy val version: String = Isabelle_System.getenv_strict("ISABELLE_VSCODE_VERSION")
-  val vscodium_repository = "https://github.com/VSCodium/vscodium.git"
-  val vscodium_download = "https://github.com/VSCodium/vscodium/releases/download"
-
-  def vscodium_exe(dir: Path): Path = dir + Path.explode("bin/codium")
-
-
-  /* platform info */
-
-  sealed case class Platform_Info(
-    platform: Platform.Family.Value,
-    download_template: String,
-    build_name: String,
-    env: List[String])
-  {
-    def is_linux: Boolean = platform == Platform.Family.linux
-
-    def download_name: String = "VSCodium-" + download_template.replace("{VERSION}", version)
-    def download_zip: Boolean = download_name.endsWith(".zip")
-
-    def download(dir: Path, progress: Progress = new Progress): Unit =
-    {
-      if (download_zip) Isabelle_System.require_command("unzip", test = "-h")
-
-      Isabelle_System.with_tmp_file("download")(download_file =>
-      {
-        Isabelle_System.download_file(vscodium_download + "/" + version + "/" + download_name,
-          download_file, progress = progress)
-
-        progress.echo("Extract ...")
-        if (download_zip) {
-          Isabelle_System.bash("unzip -x " + File.bash_path(download_file), cwd = dir.file).check
-        }
-        else {
-          Isabelle_System.gnutar("-xzf " + File.bash_path(download_file), dir = dir).check
-        }
-      })
-    }
-
-    def get_vscodium_repository(vscodium_dir: Path, progress: Progress = new Progress): Unit =
-    {
-      progress.echo("Getting VSCodium repository ...")
-      Isabelle_System.bash(
-        List(
-          "set -e",
-          "git clone -n " + Bash.string(vscodium_repository) + " .",
-          "git checkout -q " + Bash.string(version)
-        ).mkString("\n"), cwd = vscodium_dir.file).check
-
-      progress.echo("Getting VSCode repository ...")
-      Isabelle_System.bash(environment + "\n" + "./get_repo.sh", cwd = vscodium_dir.file).check
-    }
-
-    def platform_dir(dir: Path): Path =
-    {
-      val platform_name =
-        if (platform == Platform.Family.windows) Platform.Family.native(platform)
-        else Platform.Family.standard(platform)
-      dir + Path.explode(platform_name)
-    }
-
-    def build_dir(dir: Path): Path = dir + Path.explode(build_name)
-
-    def environment: String =
-      (("MS_TAG=" + Bash.string(version)) :: "SHOULD_BUILD=yes" :: "VSCODE_ARCH=x64" :: env)
-        .map(s => "export " + s + "\n").mkString
-
-    def resources_dir(dir: Path): Path =
-    {
-      val resources =
-        if (platform == Platform.Family.macos) "VSCodium.app/Contents/Resources"
-        else "resources"
-      dir + Path.explode(resources)
-    }
-
-    def patch_sources(base_dir: Path): String =
-    {
-      val dir = base_dir + Path.explode("vscode")
-      Isabelle_System.with_copy_dir(dir, dir.orig) {
-        for (name <- Seq("build/lib/electron.js", "build/lib/electron.ts")) {
-          File.change(dir + Path.explode(name), strict = true) {
-            _.replace("""'resources/darwin/' + icon + '.icns'""",
-              """'resources/darwin/' + icon.toLowerCase() + '.icns'""")
-          }
-        }
-        Isabelle_System.make_patch(base_dir, dir.base.orig, dir.base)
-      }
-    }
-
-    def patch_resources(base_dir: Path): String =
-    {
-      val dir = resources_dir(base_dir)
-      Isabelle_System.with_copy_dir(dir, dir.orig) {
-        HTML.init_fonts(dir + Path.explode("app/out/vs/base/browser/ui"))
-
-        val workbench_css = dir + Path.explode("app/out/vs/workbench/workbench.desktop.main.css")
-        val checksum1 = file_checksum(workbench_css)
-        File.append(workbench_css, "\n\n" + HTML.fonts_css_dir(prefix = "../base/browser/ui"))
-        val checksum2 = file_checksum(workbench_css)
-
-        val file_name = workbench_css.file_name
-        File.change_lines(dir + Path.explode("app/product.json")) { _.map(line =>
-          if (line.containsSlice(file_name) && line.contains(checksum1)) {
-            line.replace(checksum1, checksum2)
-          }
-          else line)
-        }
-
-        Isabelle_System.make_patch(dir.dir, dir.orig.base, dir.base)
-      }
-    }
-
-    def node_binaries(dir: Path, progress: Progress): Unit =
-    {
-      Isabelle_System.with_tmp_dir("download")(download_dir =>
-      {
-        download(download_dir, progress = progress)
-        for (name <- Seq("app/node_modules.asar", "app/node_modules.asar.unpacked")) {
-          val rel_path = resources_dir(Path.current) + Path.explode(name)
-          Isabelle_System.rm_tree(dir + rel_path)
-          Isabelle_System.copy_dir(download_dir + rel_path, dir + rel_path)
-        }
-      })
-    }
-
-    def setup_executables(dir: Path): Unit =
-    {
-      val exe = vscodium_exe(dir)
-      Isabelle_System.make_directory(exe.dir)
-
-      platform match {
-        case Platform.Family.macos =>
-          File.write(exe, macos_exe)
-          File.set_executable(exe, true)
-        case Platform.Family.windows =>
-          val files1 = File.find_files(exe.dir.file)
-          val files2 = File.find_files(dir.file, pred = file =>
-            {
-              val name = file.getName
-              name.endsWith(".dll") || name.endsWith(".exe") || name.endsWith(".node")
-            })
-          for (file <- files1 ::: files2) File.set_executable(File.path(file), true)
-          Isabelle_System.bash("chmod -R o-w " + File.bash_path(dir)).check
-        case _ =>
-      }
-    }
-  }
-
-  // see https://github.com/microsoft/vscode/blob/main/build/gulpfile.vscode.js
-  // function computeChecksum(filename)
-  private def file_checksum(path: Path): String =
-  {
-    val digest = MessageDigest.getInstance("MD5")
-    digest.update(Bytes.read(path).array)
-    Bytes(Base64.getEncoder.encode(digest.digest()))
-      .text.replaceAll("=", "")
-  }
-
-  private val platform_infos: Map[Platform.Family.Value, Platform_Info] =
-    Iterator(
-      Platform_Info(Platform.Family.linux, "linux-x64-{VERSION}.tar.gz", "VSCode-linux-x64",
-        List("OS_NAME=linux", "SKIP_LINUX_PACKAGES=True")),
-      Platform_Info(Platform.Family.linux_arm, "linux-arm64-{VERSION}.tar.gz", "VSCode-linux-arm64",
-        List("OS_NAME=linux", "SKIP_LINUX_PACKAGES=True", "VSCODE_ARCH=arm64")),
-      Platform_Info(Platform.Family.macos, "darwin-x64-{VERSION}.zip", "VSCode-darwin-x64",
-        List("OS_NAME=osx")),
-      Platform_Info(Platform.Family.windows, "win32-x64-{VERSION}.zip", "VSCode-win32-x64",
-        List("OS_NAME=windows",
-          "SHOULD_BUILD_ZIP=no",
-          "SHOULD_BUILD_EXE_SYS=no",
-          "SHOULD_BUILD_EXE_USR=no",
-          "SHOULD_BUILD_MSI=no",
-          "SHOULD_BUILD_MSI_NOUP=no")))
-      .map(info => info.platform -> info).toMap
-
-  def the_platform_info(platform: Platform.Family.Value): Platform_Info =
-    platform_infos.getOrElse(platform, error("No platform info for " + quote(platform.toString)))
-
-  def linux_platform_info: Platform_Info =
-    the_platform_info(Platform.Family.linux)
-
-
-  /* check system */
-
-  def check_system(platforms: List[Platform.Family.Value]): Unit =
-  {
-    if (Platform.family != Platform.Family.linux) error("Not a Linux/x86_64 system")
-
-    Isabelle_System.require_command("git")
-    Isabelle_System.require_command("node")
-    Isabelle_System.require_command("yarn")
-    Isabelle_System.require_command("jq")
-
-    if (platforms.contains(Platform.Family.windows)) {
-      Isabelle_System.require_command("wine")
-    }
-
-    if (platforms.exists(platform => the_platform_info(platform).download_zip)) {
-      Isabelle_System.require_command("unzip", test = "-h")
-    }
-  }
-
-
-  /* original repository clones and patches */
-
-  def vscodium_patch(verbose: Boolean = false, progress: Progress = new Progress): String =
-  {
-    val platform_info = linux_platform_info
-    check_system(List(platform_info.platform))
-
-    Isabelle_System.with_tmp_dir("vscodium")(vscodium_dir =>
-    {
-      platform_info.get_vscodium_repository(vscodium_dir, progress = progress)
-      val vscode_dir = vscodium_dir + Path.basic("vscode")
-      progress.echo("Prepare VSCodium ...")
-      Isabelle_System.with_copy_dir(vscode_dir, vscode_dir.orig) {
-        progress.bash(
-          List(
-            "set -e",
-            platform_info.environment,
-            "./prepare_vscode.sh",
-            // enforce binary diff of code.xpm
-            "cp vscode/resources/linux/code.png vscode/resources/linux/rpm/code.xpm"
-          ).mkString("\n"), cwd = vscodium_dir.file, echo = verbose).check
-        Isabelle_System.make_patch(vscodium_dir, vscode_dir.orig.base, vscode_dir.base,
-          diff_options = "--exclude=.git --exclude=node_modules")
-      }
-    })
-  }
-
-
-  /* build vscodium */
-
-  def default_platforms: List[Platform.Family.Value] = Platform.Family.list
-
-  def macos_exe: String =
-"""#!/usr/bin/env bash
-
-unset CDPATH
-VSCODE_PATH="$(cd "$(dirname "$0")"/../VSCodium.app/Contents; pwd)"
-
-ELECTRON="$VSCODE_PATH/MacOS/Electron"
-CLI="$VSCODE_PATH/Resources/app/out/cli.js"
-ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" --ms-enable-electron-run-as-node "$@"
-exit $?
-"""
-
-  def build_vscodium(
-    target_dir: Path = Path.current,
-    platforms: List[Platform.Family.Value] = default_platforms,
-    verbose: Boolean = false,
-    progress: Progress = new Progress): Unit =
-  {
-    check_system(platforms)
-
-
-    /* component */
-
-    val component_name = "vscodium-" + version
-    val component_dir = Isabelle_System.new_directory(target_dir + Path.basic(component_name))
-    progress.echo("Component " + component_dir)
-
-
-    /* patches */
-
-    progress.echo("Building patches:")
-
-    val patches_dir = Isabelle_System.new_directory(component_dir + Path.basic("patches"))
-
-    def write_patch(name: String, patch: String): Unit =
-      File.write(patches_dir + Path.explode(name).patch, patch)
-
-    write_patch("01-vscodium", vscodium_patch(verbose = verbose, progress = progress))
-
-
-    /* build */
-
-    for (platform <- platforms) yield {
-      val platform_info = the_platform_info(platform)
-
-      Isabelle_System.with_tmp_dir("vscodium")(vscodium_dir =>
-      {
-        progress.echo("Building " + platform + ":")
-
-        platform_info.get_vscodium_repository(vscodium_dir, progress = progress)
-
-        val sources_patch = platform_info.patch_sources(vscodium_dir)
-        if (platform_info.is_linux) write_patch("02-isabelle_sources", sources_patch)
-
-        progress.echo("Build VSCodium ...")
-        progress.bash(platform_info.environment + "\n" + "./build.sh",
-          cwd = vscodium_dir.file, echo = verbose).check
-
-        if (platform_info.is_linux) {
-          Isabelle_System.copy_file(vscodium_dir + Path.explode("LICENSE"), component_dir)
-        }
-
-        val platform_dir = platform_info.platform_dir(component_dir)
-        Isabelle_System.copy_dir(platform_info.build_dir(vscodium_dir), platform_dir)
-        platform_info.node_binaries(platform_dir, progress)
-
-        val resources_patch = platform_info.patch_resources(platform_dir)
-        if (platform_info.is_linux) write_patch("03-isabelle_resources", resources_patch)
-
-        platform_info.setup_executables(platform_dir)
-      })
-    }
-
-    Isabelle_System.bash("gzip *.patch", cwd = patches_dir.file).check
-
-
-    /* settings */
-
-    val etc_dir = Isabelle_System.make_directory(component_dir + Path.explode("etc"))
-    File.write(etc_dir + Path.basic("settings"),
-      """# -*- shell-script -*- :mode=shellscript:
-
-ISABELLE_VSCODIUM_HOME="$COMPONENT/${ISABELLE_WINDOWS_PLATFORM64:-$ISABELLE_PLATFORM64}"
-
-case "$ISABELLE_PLATFORM_FAMILY" in
-  linux)
-    ISABELLE_ELECTRON="$ISABELLE_VSCODIUM_HOME/codium"
-    ;;
-  macos)
-    ISABELLE_ELECTRON="$ISABELLE_VSCODIUM_HOME/VSCodium.app/Contents/MacOS/Electron"
-    ;;
-  windows)
-    ISABELLE_ELECTRON="$ISABELLE_VSCODIUM_HOME/VSCodium.exe"
-    ;;
-esac
-""")
-
-
-    /* README */
-
-    File.write(component_dir + Path.basic("README"),
-      "This is VSCodium " + version + " from " + vscodium_repository +
-"""
-
-It has been built from sources using "isabelle build_vscodium". This applies
-a few changes required for Isabelle/VSCode, see "patches" directory for a
-formal record.
-
-
-        Makarius
-        """ + Date.Format.date(Date.now()) + "\n")
-  }
-
-
-  /* Isabelle tool wrapper */
-
-  val isabelle_tool =
-    Isabelle_Tool("build_vscodium", "build component for VSCodium",
-      Scala_Project.here, args =>
-    {
-      var target_dir = Path.current
-      var platforms = default_platforms
-      var verbose = false
-
-      val getopts = Getopts("""
-Usage: vscode_setup [OPTIONS]
-
-  Options are:
-    -D DIR       target directory (default ".")
-    -p NAMES     platform families (default: """ + quote(platforms.mkString(",")) + """)
-    -v           verbose
-
-  Build VSCodium from sources and turn it into an Isabelle component.
-
-  The build platform needs to be Linux with nodejs/yarn, jq, and wine
-  for targeting Windows.
-""",
-        "D:" -> (arg => target_dir = Path.explode(arg)),
-        "p:" -> (arg => platforms = Library.space_explode(',', arg).map(Platform.Family.parse)),
-        "v" -> (_ => verbose = true))
-
-      val more_args = getopts(args)
-      if (more_args.nonEmpty) getopts.usage()
-
-      val progress = new Console_Progress()
-
-      build_vscodium(target_dir = target_dir, platforms = platforms,
-        verbose = verbose, progress = progress)
-    })
-}
--- a/src/Pure/General/json.scala	Wed Mar 09 16:21:58 2022 +0000
+++ b/src/Pure/General/json.scala	Thu Mar 10 12:34:02 2022 +0100
@@ -172,6 +172,8 @@
       try { Some(parse(s, strict = false)) }
       catch { case ERROR(_) => None }
 
+    def apply_lines(json: List[T]): S = json.map(apply).mkString("[", ",\n", "]")
+
     def apply(json: T): S =
     {
       val result = new StringBuilder
--- a/src/Pure/General/symbol.scala	Wed Mar 09 16:21:58 2022 +0000
+++ b/src/Pure/General/symbol.scala	Thu Mar 10 12:34:02 2022 +0100
@@ -375,12 +375,12 @@
 
   object Symbols
   {
-    def load(): Symbols =
+    def load(static: Boolean = false): Symbols =
     {
-      val contents =
-        for (path <- Path.split(Isabelle_System.getenv("ISABELLE_SYMBOLS")) if path.is_file)
-          yield File.read(path)
-      make(cat_lines(contents))
+      val paths =
+        if (static) List(Path.explode("~~/etc/symbols"))
+        else Path.split(Isabelle_System.getenv("ISABELLE_SYMBOLS"))
+      make(cat_lines(for (path <- paths if path.is_file) yield File.read(path)))
     }
 
     def make(symbols_spec: String): Symbols =
--- a/src/Pure/System/isabelle_tool.scala	Wed Mar 09 16:21:58 2022 +0000
+++ b/src/Pure/System/isabelle_tool.scala	Thu Mar 10 12:34:02 2022 +0100
@@ -231,9 +231,10 @@
   Build_Status.isabelle_tool,
   Build_Vampire.isabelle_tool,
   Build_VeriT.isabelle_tool,
-  Build_VSCodium.isabelle_tool,
   Build_Zipperposition.isabelle_tool,
   Check_Sources.isabelle_tool,
   Components.isabelle_tool,
   isabelle.vscode.Build_VSCode.isabelle_tool,
+  isabelle.vscode.Build_VSCodium.isabelle_tool1,
+  isabelle.vscode.Build_VSCodium.isabelle_tool2,
   isabelle.vscode.VSCode_Setup.isabelle_tool)
--- a/src/Tools/VSCode/README.md	Wed Mar 09 16:21:58 2022 +0000
+++ b/src/Tools/VSCode/README.md	Thu Mar 10 12:34:02 2022 +0100
@@ -1,6 +1,6 @@
 # Isabelle/VSCode development #
 
-## System setup ##
+## System requirements ##
 
 * install default node.js (e.g. via Ubuntu package)
 
@@ -10,16 +10,16 @@
     sudo npm install -g n
     sudo n stable
 
-* install vsce:
+* install add-on tools:
 
-    sudo npm install -g vsce
+    sudo npm install -g yarn vsce
 
 
 ## Edit and debug ##
 
 * Shell commands within $ISABELLE_HOME directory:
 
-    isabelle build_vscode -U
+    isabelle build_vscode_extension -U
     isabelle vscode src/Tools/VSCode/extension
 
 * VSCode commands:
@@ -29,4 +29,4 @@
 
 ## Build and install ##
 
-    isabelle build_vscode -I
+    isabelle build_vscode_extension -I
--- a/src/Tools/VSCode/etc/settings	Wed Mar 09 16:21:58 2022 +0000
+++ b/src/Tools/VSCode/etc/settings	Thu Mar 10 12:34:02 2022 +0100
@@ -3,4 +3,3 @@
 ISABELLE_VSCODE_VERSION="1.65.0"
 ISABELLE_VSCODE_HOME="$ISABELLE_HOME/src/Tools/VSCode"
 ISABELLE_VSCODE_SETTINGS="$ISABELLE_HOME_USER/vscode"
-ISABELLE_VSCODE_WORKSPACE="$ISABELLE_VSCODE_SETTINGS/workspace"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Tools/VSCode/extension/.yarnrc	Thu Mar 10 12:34:02 2022 +0100
@@ -0,0 +1,1 @@
+--ignore-engines true
\ No newline at end of file
--- a/src/Tools/VSCode/extension/package-lock.json	Wed Mar 09 16:21:58 2022 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1758 +0,0 @@
-{
-    "name": "isabelle",
-    "version": "2.0.0",
-    "lockfileVersion": 2,
-    "requires": true,
-    "packages": {
-        "": {
-            "name": "isabelle",
-            "version": "2.0.0",
-            "license": "MIT",
-            "dependencies": {
-                "vscode-languageclient": "~7.0.0",
-                "vscode-languageserver-types": "~3.16.0"
-            },
-            "devDependencies": {
-                "@types/mocha": "^9.1.0",
-                "@types/node": "^17.0.19",
-                "@types/vscode": "1.65.0",
-                "mocha": "^9.2.1",
-                "typescript": "^4.5.5"
-            },
-            "engines": {
-                "vscode": "1.65.0"
-            }
-        },
-        "node_modules/@types/mocha": {
-            "version": "9.1.0",
-            "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz",
-            "integrity": "sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==",
-            "dev": true
-        },
-        "node_modules/@types/node": {
-            "version": "17.0.21",
-            "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
-            "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==",
-            "dev": true
-        },
-        "node_modules/@types/vscode": {
-            "version": "1.65.0",
-            "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.65.0.tgz",
-            "integrity": "sha512-wQhExnh2nEzpjDMSKhUvnNmz3ucpd3E+R7wJkOhBNK3No6fG3VUdmVmMOKD0A8NDZDDDiQcLNxe3oGmX5SjJ5w==",
-            "dev": true
-        },
-        "node_modules/@ungap/promise-all-settled": {
-            "version": "1.1.2",
-            "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
-            "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
-            "dev": true
-        },
-        "node_modules/ansi-colors": {
-            "version": "4.1.1",
-            "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
-            "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
-            "dev": true,
-            "engines": {
-                "node": ">=6"
-            }
-        },
-        "node_modules/ansi-regex": {
-            "version": "5.0.1",
-            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-            "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-            "dev": true,
-            "engines": {
-                "node": ">=8"
-            }
-        },
-        "node_modules/ansi-styles": {
-            "version": "4.3.0",
-            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-            "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-            "dev": true,
-            "dependencies": {
-                "color-convert": "^2.0.1"
-            },
-            "engines": {
-                "node": ">=8"
-            },
-            "funding": {
-                "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-            }
-        },
-        "node_modules/anymatch": {
-            "version": "3.1.2",
-            "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
-            "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
-            "dev": true,
-            "dependencies": {
-                "normalize-path": "^3.0.0",
-                "picomatch": "^2.0.4"
-            },
-            "engines": {
-                "node": ">= 8"
-            }
-        },
-        "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/balanced-match": {
-            "version": "1.0.2",
-            "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-            "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
-        },
-        "node_modules/binary-extensions": {
-            "version": "2.2.0",
-            "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
-            "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
-            "dev": true,
-            "engines": {
-                "node": ">=8"
-            }
-        },
-        "node_modules/brace-expansion": {
-            "version": "1.1.11",
-            "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-            "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-            "dependencies": {
-                "balanced-match": "^1.0.0",
-                "concat-map": "0.0.1"
-            }
-        },
-        "node_modules/braces": {
-            "version": "3.0.2",
-            "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-            "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
-            "dev": true,
-            "dependencies": {
-                "fill-range": "^7.0.1"
-            },
-            "engines": {
-                "node": ">=8"
-            }
-        },
-        "node_modules/browser-stdout": {
-            "version": "1.3.1",
-            "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
-            "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
-            "dev": true
-        },
-        "node_modules/camelcase": {
-            "version": "6.3.0",
-            "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
-            "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
-            "dev": true,
-            "engines": {
-                "node": ">=10"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
-            }
-        },
-        "node_modules/chalk": {
-            "version": "4.1.2",
-            "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-            "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-            "dev": true,
-            "dependencies": {
-                "ansi-styles": "^4.1.0",
-                "supports-color": "^7.1.0"
-            },
-            "engines": {
-                "node": ">=10"
-            },
-            "funding": {
-                "url": "https://github.com/chalk/chalk?sponsor=1"
-            }
-        },
-        "node_modules/chalk/node_modules/supports-color": {
-            "version": "7.2.0",
-            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-            "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-            "dev": true,
-            "dependencies": {
-                "has-flag": "^4.0.0"
-            },
-            "engines": {
-                "node": ">=8"
-            }
-        },
-        "node_modules/chokidar": {
-            "version": "3.5.3",
-            "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
-            "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
-            "dev": true,
-            "funding": [
-                {
-                    "type": "individual",
-                    "url": "https://paulmillr.com/funding/"
-                }
-            ],
-            "dependencies": {
-                "anymatch": "~3.1.2",
-                "braces": "~3.0.2",
-                "glob-parent": "~5.1.2",
-                "is-binary-path": "~2.1.0",
-                "is-glob": "~4.0.1",
-                "normalize-path": "~3.0.0",
-                "readdirp": "~3.6.0"
-            },
-            "engines": {
-                "node": ">= 8.10.0"
-            },
-            "optionalDependencies": {
-                "fsevents": "~2.3.2"
-            }
-        },
-        "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==",
-            "dev": true,
-            "dependencies": {
-                "string-width": "^4.2.0",
-                "strip-ansi": "^6.0.0",
-                "wrap-ansi": "^7.0.0"
-            }
-        },
-        "node_modules/color-convert": {
-            "version": "2.0.1",
-            "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-            "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-            "dev": true,
-            "dependencies": {
-                "color-name": "~1.1.4"
-            },
-            "engines": {
-                "node": ">=7.0.0"
-            }
-        },
-        "node_modules/color-name": {
-            "version": "1.1.4",
-            "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-            "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-            "dev": true
-        },
-        "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="
-        },
-        "node_modules/debug": {
-            "version": "4.3.3",
-            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
-            "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
-            "dev": true,
-            "dependencies": {
-                "ms": "2.1.2"
-            },
-            "engines": {
-                "node": ">=6.0"
-            },
-            "peerDependenciesMeta": {
-                "supports-color": {
-                    "optional": true
-                }
-            }
-        },
-        "node_modules/debug/node_modules/ms": {
-            "version": "2.1.2",
-            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-            "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-            "dev": true
-        },
-        "node_modules/decamelize": {
-            "version": "4.0.0",
-            "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
-            "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
-            "dev": true,
-            "engines": {
-                "node": ">=10"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
-            }
-        },
-        "node_modules/diff": {
-            "version": "5.0.0",
-            "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
-            "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
-            "dev": true,
-            "engines": {
-                "node": ">=0.3.1"
-            }
-        },
-        "node_modules/emoji-regex": {
-            "version": "8.0.0",
-            "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-            "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-            "dev": true
-        },
-        "node_modules/escalade": {
-            "version": "3.1.1",
-            "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-            "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
-            "dev": true,
-            "engines": {
-                "node": ">=6"
-            }
-        },
-        "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/fill-range": {
-            "version": "7.0.1",
-            "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-            "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
-            "dev": true,
-            "dependencies": {
-                "to-regex-range": "^5.0.1"
-            },
-            "engines": {
-                "node": ">=8"
-            }
-        },
-        "node_modules/find-up": {
-            "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": "^6.0.0",
-                "path-exists": "^4.0.0"
-            },
-            "engines": {
-                "node": ">=10"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
-            }
-        },
-        "node_modules/flat": {
-            "version": "5.0.2",
-            "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
-            "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
-            "dev": true,
-            "bin": {
-                "flat": "cli.js"
-            }
-        },
-        "node_modules/fs.realpath": {
-            "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-            "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
-            "dev": true
-        },
-        "node_modules/fsevents": {
-            "version": "2.3.2",
-            "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
-            "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
-            "dev": true,
-            "hasInstallScript": true,
-            "optional": true,
-            "os": [
-                "darwin"
-            ],
-            "engines": {
-                "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-            }
-        },
-        "node_modules/get-caller-file": {
-            "version": "2.0.5",
-            "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
-            "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
-            "dev": true,
-            "engines": {
-                "node": "6.* || 8.* || >= 10.*"
-            }
-        },
-        "node_modules/glob": {
-            "version": "7.2.0",
-            "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
-            "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
-            "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/glob-parent": {
-            "version": "5.1.2",
-            "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-            "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-            "dev": true,
-            "dependencies": {
-                "is-glob": "^4.0.1"
-            },
-            "engines": {
-                "node": ">= 6"
-            }
-        },
-        "node_modules/growl": {
-            "version": "1.10.5",
-            "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
-            "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
-            "dev": true,
-            "engines": {
-                "node": ">=4.x"
-            }
-        },
-        "node_modules/has-flag": {
-            "version": "4.0.0",
-            "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-            "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-            "dev": true,
-            "engines": {
-                "node": ">=8"
-            }
-        },
-        "node_modules/he": {
-            "version": "1.2.0",
-            "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
-            "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
-            "dev": true,
-            "bin": {
-                "he": "bin/he"
-            }
-        },
-        "node_modules/inflight": {
-            "version": "1.0.6",
-            "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-            "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
-            "dev": true,
-            "dependencies": {
-                "once": "^1.3.0",
-                "wrappy": "1"
-            }
-        },
-        "node_modules/inherits": {
-            "version": "2.0.4",
-            "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-            "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-            "dev": true
-        },
-        "node_modules/is-binary-path": {
-            "version": "2.1.0",
-            "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
-            "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
-            "dev": true,
-            "dependencies": {
-                "binary-extensions": "^2.0.0"
-            },
-            "engines": {
-                "node": ">=8"
-            }
-        },
-        "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=",
-            "dev": true,
-            "engines": {
-                "node": ">=0.10.0"
-            }
-        },
-        "node_modules/is-fullwidth-code-point": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
-            "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-            "dev": true,
-            "engines": {
-                "node": ">=8"
-            }
-        },
-        "node_modules/is-glob": {
-            "version": "4.0.3",
-            "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
-            "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
-            "dev": true,
-            "dependencies": {
-                "is-extglob": "^2.1.1"
-            },
-            "engines": {
-                "node": ">=0.10.0"
-            }
-        },
-        "node_modules/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,
-            "engines": {
-                "node": ">=0.12.0"
-            }
-        },
-        "node_modules/is-plain-obj": {
-            "version": "2.1.0",
-            "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
-            "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
-            "dev": true,
-            "engines": {
-                "node": ">=8"
-            }
-        },
-        "node_modules/is-unicode-supported": {
-            "version": "0.1.0",
-            "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
-            "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
-            "dev": true,
-            "engines": {
-                "node": ">=10"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
-            }
-        },
-        "node_modules/isexe": {
-            "version": "2.0.0",
-            "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-            "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-            "dev": true
-        },
-        "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/locate-path": {
-            "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": "^5.0.0"
-            },
-            "engines": {
-                "node": ">=10"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
-            }
-        },
-        "node_modules/log-symbols": {
-            "version": "4.1.0",
-            "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
-            "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
-            "dev": true,
-            "dependencies": {
-                "chalk": "^4.1.0",
-                "is-unicode-supported": "^0.1.0"
-            },
-            "engines": {
-                "node": ">=10"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
-            }
-        },
-        "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==",
-            "dependencies": {
-                "yallist": "^4.0.0"
-            },
-            "engines": {
-                "node": ">=10"
-            }
-        },
-        "node_modules/minimatch": {
-            "version": "3.0.4",
-            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-            "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-            "dependencies": {
-                "brace-expansion": "^1.1.7"
-            },
-            "engines": {
-                "node": "*"
-            }
-        },
-        "node_modules/mocha": {
-            "version": "9.2.1",
-            "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.1.tgz",
-            "integrity": "sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ==",
-            "dev": true,
-            "dependencies": {
-                "@ungap/promise-all-settled": "1.1.2",
-                "ansi-colors": "4.1.1",
-                "browser-stdout": "1.3.1",
-                "chokidar": "3.5.3",
-                "debug": "4.3.3",
-                "diff": "5.0.0",
-                "escape-string-regexp": "4.0.0",
-                "find-up": "5.0.0",
-                "glob": "7.2.0",
-                "growl": "1.10.5",
-                "he": "1.2.0",
-                "js-yaml": "4.1.0",
-                "log-symbols": "4.1.0",
-                "minimatch": "3.0.4",
-                "ms": "2.1.3",
-                "nanoid": "3.2.0",
-                "serialize-javascript": "6.0.0",
-                "strip-json-comments": "3.1.1",
-                "supports-color": "8.1.1",
-                "which": "2.0.2",
-                "workerpool": "6.2.0",
-                "yargs": "16.2.0",
-                "yargs-parser": "20.2.4",
-                "yargs-unparser": "2.0.0"
-            },
-            "bin": {
-                "_mocha": "bin/_mocha",
-                "mocha": "bin/mocha"
-            },
-            "engines": {
-                "node": ">= 12.0.0"
-            },
-            "funding": {
-                "type": "opencollective",
-                "url": "https://opencollective.com/mochajs"
-            }
-        },
-        "node_modules/ms": {
-            "version": "2.1.3",
-            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-            "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-            "dev": true
-        },
-        "node_modules/nanoid": {
-            "version": "3.2.0",
-            "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
-            "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
-            "dev": true,
-            "bin": {
-                "nanoid": "bin/nanoid.cjs"
-            },
-            "engines": {
-                "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-            }
-        },
-        "node_modules/normalize-path": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
-            "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
-            "dev": true,
-            "engines": {
-                "node": ">=0.10.0"
-            }
-        },
-        "node_modules/once": {
-            "version": "1.4.0",
-            "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-            "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
-            "dev": true,
-            "dependencies": {
-                "wrappy": "1"
-            }
-        },
-        "node_modules/p-limit": {
-            "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": {
-                "yocto-queue": "^0.1.0"
-            },
-            "engines": {
-                "node": ">=10"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
-            }
-        },
-        "node_modules/p-locate": {
-            "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": "^3.0.2"
-            },
-            "engines": {
-                "node": ">=10"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
-            }
-        },
-        "node_modules/path-exists": {
-            "version": "4.0.0",
-            "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
-            "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
-            "dev": true,
-            "engines": {
-                "node": ">=8"
-            }
-        },
-        "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=",
-            "dev": true,
-            "engines": {
-                "node": ">=0.10.0"
-            }
-        },
-        "node_modules/picomatch": {
-            "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"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/jonschlinkert"
-            }
-        },
-        "node_modules/randombytes": {
-            "version": "2.1.0",
-            "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
-            "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
-            "dev": true,
-            "dependencies": {
-                "safe-buffer": "^5.1.0"
-            }
-        },
-        "node_modules/readdirp": {
-            "version": "3.6.0",
-            "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
-            "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
-            "dev": true,
-            "dependencies": {
-                "picomatch": "^2.2.1"
-            },
-            "engines": {
-                "node": ">=8.10.0"
-            }
-        },
-        "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=",
-            "dev": true,
-            "engines": {
-                "node": ">=0.10.0"
-            }
-        },
-        "node_modules/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==",
-            "dev": true,
-            "funding": [
-                {
-                    "type": "github",
-                    "url": "https://github.com/sponsors/feross"
-                },
-                {
-                    "type": "patreon",
-                    "url": "https://www.patreon.com/feross"
-                },
-                {
-                    "type": "consulting",
-                    "url": "https://feross.org/support"
-                }
-            ]
-        },
-        "node_modules/semver": {
-            "version": "7.3.5",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-            "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
-            "dependencies": {
-                "lru-cache": "^6.0.0"
-            },
-            "bin": {
-                "semver": "bin/semver.js"
-            },
-            "engines": {
-                "node": ">=10"
-            }
-        },
-        "node_modules/serialize-javascript": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
-            "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
-            "dev": true,
-            "dependencies": {
-                "randombytes": "^2.1.0"
-            }
-        },
-        "node_modules/string-width": {
-            "version": "4.2.3",
-            "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-            "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
-            "dev": true,
-            "dependencies": {
-                "emoji-regex": "^8.0.0",
-                "is-fullwidth-code-point": "^3.0.0",
-                "strip-ansi": "^6.0.1"
-            },
-            "engines": {
-                "node": ">=8"
-            }
-        },
-        "node_modules/strip-ansi": {
-            "version": "6.0.1",
-            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-            "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-            "dev": true,
-            "dependencies": {
-                "ansi-regex": "^5.0.1"
-            },
-            "engines": {
-                "node": ">=8"
-            }
-        },
-        "node_modules/strip-json-comments": {
-            "version": "3.1.1",
-            "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
-            "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
-            "dev": true,
-            "engines": {
-                "node": ">=8"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
-            }
-        },
-        "node_modules/supports-color": {
-            "version": "8.1.1",
-            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
-            "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
-            "dev": true,
-            "dependencies": {
-                "has-flag": "^4.0.0"
-            },
-            "engines": {
-                "node": ">=10"
-            },
-            "funding": {
-                "url": "https://github.com/chalk/supports-color?sponsor=1"
-            }
-        },
-        "node_modules/to-regex-range": {
-            "version": "5.0.1",
-            "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-            "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-            "dev": true,
-            "dependencies": {
-                "is-number": "^7.0.0"
-            },
-            "engines": {
-                "node": ">=8.0"
-            }
-        },
-        "node_modules/typescript": {
-            "version": "4.6.2",
-            "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
-            "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
-            "dev": true,
-            "bin": {
-                "tsc": "bin/tsc",
-                "tsserver": "bin/tsserver"
-            },
-            "engines": {
-                "node": ">=4.2.0"
-            }
-        },
-        "node_modules/vscode-jsonrpc": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
-            "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==",
-            "engines": {
-                "node": ">=8.0.0 || >=10.0.0"
-            }
-        },
-        "node_modules/vscode-languageclient": {
-            "version": "7.0.0",
-            "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz",
-            "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==",
-            "dependencies": {
-                "minimatch": "^3.0.4",
-                "semver": "^7.3.4",
-                "vscode-languageserver-protocol": "3.16.0"
-            },
-            "engines": {
-                "vscode": "^1.52.0"
-            }
-        },
-        "node_modules/vscode-languageserver-protocol": {
-            "version": "3.16.0",
-            "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz",
-            "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==",
-            "dependencies": {
-                "vscode-jsonrpc": "6.0.0",
-                "vscode-languageserver-types": "3.16.0"
-            }
-        },
-        "node_modules/vscode-languageserver-types": {
-            "version": "3.16.0",
-            "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
-            "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA=="
-        },
-        "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/workerpool": {
-            "version": "6.2.0",
-            "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
-            "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
-            "dev": true
-        },
-        "node_modules/wrap-ansi": {
-            "version": "7.0.0",
-            "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
-            "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
-            "dev": true,
-            "dependencies": {
-                "ansi-styles": "^4.0.0",
-                "string-width": "^4.1.0",
-                "strip-ansi": "^6.0.0"
-            },
-            "engines": {
-                "node": ">=10"
-            },
-            "funding": {
-                "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
-            }
-        },
-        "node_modules/wrappy": {
-            "version": "1.0.2",
-            "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-            "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-            "dev": true
-        },
-        "node_modules/y18n": {
-            "version": "5.0.8",
-            "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
-            "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
-            "dev": true,
-            "engines": {
-                "node": ">=10"
-            }
-        },
-        "node_modules/yallist": {
-            "version": "4.0.0",
-            "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
-        },
-        "node_modules/yargs": {
-            "version": "16.2.0",
-            "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
-            "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
-            "dev": true,
-            "dependencies": {
-                "cliui": "^7.0.2",
-                "escalade": "^3.1.1",
-                "get-caller-file": "^2.0.5",
-                "require-directory": "^2.1.1",
-                "string-width": "^4.2.0",
-                "y18n": "^5.0.5",
-                "yargs-parser": "^20.2.2"
-            },
-            "engines": {
-                "node": ">=10"
-            }
-        },
-        "node_modules/yargs-parser": {
-            "version": "20.2.4",
-            "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
-            "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
-            "dev": true,
-            "engines": {
-                "node": ">=10"
-            }
-        },
-        "node_modules/yargs-unparser": {
-            "version": "2.0.0",
-            "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
-            "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
-            "dev": true,
-            "dependencies": {
-                "camelcase": "^6.0.0",
-                "decamelize": "^4.0.0",
-                "flat": "^5.0.2",
-                "is-plain-obj": "^2.1.0"
-            },
-            "engines": {
-                "node": ">=10"
-            }
-        },
-        "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"
-            }
-        }
-    },
-    "dependencies": {
-        "@types/mocha": {
-            "version": "9.1.0",
-            "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz",
-            "integrity": "sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==",
-            "dev": true
-        },
-        "@types/node": {
-            "version": "17.0.21",
-            "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
-            "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==",
-            "dev": true
-        },
-        "@types/vscode": {
-            "version": "1.65.0",
-            "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.65.0.tgz",
-            "integrity": "sha512-wQhExnh2nEzpjDMSKhUvnNmz3ucpd3E+R7wJkOhBNK3No6fG3VUdmVmMOKD0A8NDZDDDiQcLNxe3oGmX5SjJ5w==",
-            "dev": true
-        },
-        "@ungap/promise-all-settled": {
-            "version": "1.1.2",
-            "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
-            "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
-            "dev": true
-        },
-        "ansi-colors": {
-            "version": "4.1.1",
-            "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
-            "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
-            "dev": true
-        },
-        "ansi-regex": {
-            "version": "5.0.1",
-            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-            "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-            "dev": true
-        },
-        "ansi-styles": {
-            "version": "4.3.0",
-            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-            "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-            "dev": true,
-            "requires": {
-                "color-convert": "^2.0.1"
-            }
-        },
-        "anymatch": {
-            "version": "3.1.2",
-            "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
-            "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
-            "dev": true,
-            "requires": {
-                "normalize-path": "^3.0.0",
-                "picomatch": "^2.0.4"
-            }
-        },
-        "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
-        },
-        "balanced-match": {
-            "version": "1.0.2",
-            "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-            "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
-        },
-        "binary-extensions": {
-            "version": "2.2.0",
-            "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
-            "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
-            "dev": true
-        },
-        "brace-expansion": {
-            "version": "1.1.11",
-            "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-            "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-            "requires": {
-                "balanced-match": "^1.0.0",
-                "concat-map": "0.0.1"
-            }
-        },
-        "braces": {
-            "version": "3.0.2",
-            "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-            "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
-            "dev": true,
-            "requires": {
-                "fill-range": "^7.0.1"
-            }
-        },
-        "browser-stdout": {
-            "version": "1.3.1",
-            "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
-            "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
-            "dev": true
-        },
-        "camelcase": {
-            "version": "6.3.0",
-            "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
-            "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
-            "dev": true
-        },
-        "chalk": {
-            "version": "4.1.2",
-            "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-            "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-            "dev": true,
-            "requires": {
-                "ansi-styles": "^4.1.0",
-                "supports-color": "^7.1.0"
-            },
-            "dependencies": {
-                "supports-color": {
-                    "version": "7.2.0",
-                    "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-                    "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-                    "dev": true,
-                    "requires": {
-                        "has-flag": "^4.0.0"
-                    }
-                }
-            }
-        },
-        "chokidar": {
-            "version": "3.5.3",
-            "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
-            "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
-            "dev": true,
-            "requires": {
-                "anymatch": "~3.1.2",
-                "braces": "~3.0.2",
-                "fsevents": "~2.3.2",
-                "glob-parent": "~5.1.2",
-                "is-binary-path": "~2.1.0",
-                "is-glob": "~4.0.1",
-                "normalize-path": "~3.0.0",
-                "readdirp": "~3.6.0"
-            }
-        },
-        "cliui": {
-            "version": "7.0.4",
-            "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-            "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
-            "dev": true,
-            "requires": {
-                "string-width": "^4.2.0",
-                "strip-ansi": "^6.0.0",
-                "wrap-ansi": "^7.0.0"
-            }
-        },
-        "color-convert": {
-            "version": "2.0.1",
-            "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-            "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-            "dev": true,
-            "requires": {
-                "color-name": "~1.1.4"
-            }
-        },
-        "color-name": {
-            "version": "1.1.4",
-            "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-            "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-            "dev": true
-        },
-        "concat-map": {
-            "version": "0.0.1",
-            "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-            "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
-        },
-        "debug": {
-            "version": "4.3.3",
-            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
-            "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
-            "dev": true,
-            "requires": {
-                "ms": "2.1.2"
-            },
-            "dependencies": {
-                "ms": {
-                    "version": "2.1.2",
-                    "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-                    "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-                    "dev": true
-                }
-            }
-        },
-        "decamelize": {
-            "version": "4.0.0",
-            "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
-            "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
-            "dev": true
-        },
-        "diff": {
-            "version": "5.0.0",
-            "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
-            "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
-            "dev": true
-        },
-        "emoji-regex": {
-            "version": "8.0.0",
-            "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-            "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-            "dev": true
-        },
-        "escalade": {
-            "version": "3.1.1",
-            "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-            "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
-            "dev": true
-        },
-        "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
-        },
-        "fill-range": {
-            "version": "7.0.1",
-            "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-            "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
-            "dev": true,
-            "requires": {
-                "to-regex-range": "^5.0.1"
-            }
-        },
-        "find-up": {
-            "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": "^6.0.0",
-                "path-exists": "^4.0.0"
-            }
-        },
-        "flat": {
-            "version": "5.0.2",
-            "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
-            "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
-            "dev": true
-        },
-        "fs.realpath": {
-            "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-            "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
-            "dev": true
-        },
-        "fsevents": {
-            "version": "2.3.2",
-            "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
-            "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
-            "dev": true,
-            "optional": true
-        },
-        "get-caller-file": {
-            "version": "2.0.5",
-            "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
-            "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
-            "dev": true
-        },
-        "glob": {
-            "version": "7.2.0",
-            "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
-            "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
-            "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"
-            }
-        },
-        "glob-parent": {
-            "version": "5.1.2",
-            "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-            "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-            "dev": true,
-            "requires": {
-                "is-glob": "^4.0.1"
-            }
-        },
-        "growl": {
-            "version": "1.10.5",
-            "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
-            "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
-            "dev": true
-        },
-        "has-flag": {
-            "version": "4.0.0",
-            "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-            "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-            "dev": true
-        },
-        "he": {
-            "version": "1.2.0",
-            "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
-            "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
-            "dev": true
-        },
-        "inflight": {
-            "version": "1.0.6",
-            "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-            "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
-            "dev": true,
-            "requires": {
-                "once": "^1.3.0",
-                "wrappy": "1"
-            }
-        },
-        "inherits": {
-            "version": "2.0.4",
-            "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-            "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-            "dev": true
-        },
-        "is-binary-path": {
-            "version": "2.1.0",
-            "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
-            "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
-            "dev": true,
-            "requires": {
-                "binary-extensions": "^2.0.0"
-            }
-        },
-        "is-extglob": {
-            "version": "2.1.1",
-            "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-            "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
-            "dev": true
-        },
-        "is-fullwidth-code-point": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
-            "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-            "dev": true
-        },
-        "is-glob": {
-            "version": "4.0.3",
-            "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
-            "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
-            "dev": true,
-            "requires": {
-                "is-extglob": "^2.1.1"
-            }
-        },
-        "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-plain-obj": {
-            "version": "2.1.0",
-            "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
-            "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
-            "dev": true
-        },
-        "is-unicode-supported": {
-            "version": "0.1.0",
-            "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
-            "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
-            "dev": true
-        },
-        "isexe": {
-            "version": "2.0.0",
-            "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-            "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-            "dev": true
-        },
-        "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"
-            }
-        },
-        "locate-path": {
-            "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": "^5.0.0"
-            }
-        },
-        "log-symbols": {
-            "version": "4.1.0",
-            "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
-            "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
-            "dev": true,
-            "requires": {
-                "chalk": "^4.1.0",
-                "is-unicode-supported": "^0.1.0"
-            }
-        },
-        "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==",
-            "requires": {
-                "yallist": "^4.0.0"
-            }
-        },
-        "minimatch": {
-            "version": "3.0.4",
-            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-            "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-            "requires": {
-                "brace-expansion": "^1.1.7"
-            }
-        },
-        "mocha": {
-            "version": "9.2.1",
-            "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.1.tgz",
-            "integrity": "sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ==",
-            "dev": true,
-            "requires": {
-                "@ungap/promise-all-settled": "1.1.2",
-                "ansi-colors": "4.1.1",
-                "browser-stdout": "1.3.1",
-                "chokidar": "3.5.3",
-                "debug": "4.3.3",
-                "diff": "5.0.0",
-                "escape-string-regexp": "4.0.0",
-                "find-up": "5.0.0",
-                "glob": "7.2.0",
-                "growl": "1.10.5",
-                "he": "1.2.0",
-                "js-yaml": "4.1.0",
-                "log-symbols": "4.1.0",
-                "minimatch": "3.0.4",
-                "ms": "2.1.3",
-                "nanoid": "3.2.0",
-                "serialize-javascript": "6.0.0",
-                "strip-json-comments": "3.1.1",
-                "supports-color": "8.1.1",
-                "which": "2.0.2",
-                "workerpool": "6.2.0",
-                "yargs": "16.2.0",
-                "yargs-parser": "20.2.4",
-                "yargs-unparser": "2.0.0"
-            }
-        },
-        "ms": {
-            "version": "2.1.3",
-            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-            "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-            "dev": true
-        },
-        "nanoid": {
-            "version": "3.2.0",
-            "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
-            "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
-            "dev": true
-        },
-        "normalize-path": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
-            "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
-            "dev": true
-        },
-        "once": {
-            "version": "1.4.0",
-            "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-            "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
-            "dev": true,
-            "requires": {
-                "wrappy": "1"
-            }
-        },
-        "p-limit": {
-            "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": {
-                "yocto-queue": "^0.1.0"
-            }
-        },
-        "p-locate": {
-            "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": "^3.0.2"
-            }
-        },
-        "path-exists": {
-            "version": "4.0.0",
-            "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
-            "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
-            "dev": true
-        },
-        "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=",
-            "dev": true
-        },
-        "picomatch": {
-            "version": "2.3.1",
-            "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-            "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-            "dev": true
-        },
-        "randombytes": {
-            "version": "2.1.0",
-            "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
-            "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
-            "dev": true,
-            "requires": {
-                "safe-buffer": "^5.1.0"
-            }
-        },
-        "readdirp": {
-            "version": "3.6.0",
-            "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
-            "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
-            "dev": true,
-            "requires": {
-                "picomatch": "^2.2.1"
-            }
-        },
-        "require-directory": {
-            "version": "2.1.1",
-            "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-            "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
-            "dev": true
-        },
-        "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==",
-            "dev": true
-        },
-        "semver": {
-            "version": "7.3.5",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-            "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
-            "requires": {
-                "lru-cache": "^6.0.0"
-            }
-        },
-        "serialize-javascript": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
-            "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
-            "dev": true,
-            "requires": {
-                "randombytes": "^2.1.0"
-            }
-        },
-        "string-width": {
-            "version": "4.2.3",
-            "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-            "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
-            "dev": true,
-            "requires": {
-                "emoji-regex": "^8.0.0",
-                "is-fullwidth-code-point": "^3.0.0",
-                "strip-ansi": "^6.0.1"
-            }
-        },
-        "strip-ansi": {
-            "version": "6.0.1",
-            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-            "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-            "dev": true,
-            "requires": {
-                "ansi-regex": "^5.0.1"
-            }
-        },
-        "strip-json-comments": {
-            "version": "3.1.1",
-            "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
-            "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
-            "dev": true
-        },
-        "supports-color": {
-            "version": "8.1.1",
-            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
-            "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
-            "dev": true,
-            "requires": {
-                "has-flag": "^4.0.0"
-            }
-        },
-        "to-regex-range": {
-            "version": "5.0.1",
-            "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-            "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-            "dev": true,
-            "requires": {
-                "is-number": "^7.0.0"
-            }
-        },
-        "typescript": {
-            "version": "4.6.2",
-            "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
-            "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
-            "dev": true
-        },
-        "vscode-jsonrpc": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
-            "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg=="
-        },
-        "vscode-languageclient": {
-            "version": "7.0.0",
-            "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz",
-            "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==",
-            "requires": {
-                "minimatch": "^3.0.4",
-                "semver": "^7.3.4",
-                "vscode-languageserver-protocol": "3.16.0"
-            }
-        },
-        "vscode-languageserver-protocol": {
-            "version": "3.16.0",
-            "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz",
-            "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==",
-            "requires": {
-                "vscode-jsonrpc": "6.0.0",
-                "vscode-languageserver-types": "3.16.0"
-            }
-        },
-        "vscode-languageserver-types": {
-            "version": "3.16.0",
-            "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
-            "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA=="
-        },
-        "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"
-            }
-        },
-        "workerpool": {
-            "version": "6.2.0",
-            "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
-            "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
-            "dev": true
-        },
-        "wrap-ansi": {
-            "version": "7.0.0",
-            "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
-            "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
-            "dev": true,
-            "requires": {
-                "ansi-styles": "^4.0.0",
-                "string-width": "^4.1.0",
-                "strip-ansi": "^6.0.0"
-            }
-        },
-        "wrappy": {
-            "version": "1.0.2",
-            "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-            "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-            "dev": true
-        },
-        "y18n": {
-            "version": "5.0.8",
-            "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
-            "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
-            "dev": true
-        },
-        "yallist": {
-            "version": "4.0.0",
-            "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
-        },
-        "yargs": {
-            "version": "16.2.0",
-            "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
-            "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
-            "dev": true,
-            "requires": {
-                "cliui": "^7.0.2",
-                "escalade": "^3.1.1",
-                "get-caller-file": "^2.0.5",
-                "require-directory": "^2.1.1",
-                "string-width": "^4.2.0",
-                "y18n": "^5.0.5",
-                "yargs-parser": "^20.2.2"
-            }
-        },
-        "yargs-parser": {
-            "version": "20.2.4",
-            "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
-            "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
-            "dev": true
-        },
-        "yargs-unparser": {
-            "version": "2.0.0",
-            "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
-            "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
-            "dev": true,
-            "requires": {
-                "camelcase": "^6.0.0",
-                "decamelize": "^4.0.0",
-                "flat": "^5.0.2",
-                "is-plain-obj": "^2.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
-        }
-    }
-}
--- a/src/Tools/VSCode/extension/package.json	Wed Mar 09 16:21:58 2022 +0000
+++ b/src/Tools/VSCode/extension/package.json	Thu Mar 10 12:34:02 2022 +0100
@@ -311,7 +311,7 @@
         }
     },
     "scripts": {
-        "vscode:prepublish": "npm run compile",
+        "vscode:prepublish": "yarn run compile",
         "compile": "tsc -p ./",
         "watch": "tsc -watch -p ./"
     },
--- a/src/Tools/VSCode/extension/src/file.ts	Wed Mar 09 16:21:58 2022 +0000
+++ b/src/Tools/VSCode/extension/src/file.ts	Thu Mar 10 12:34:02 2022 +0100
@@ -6,7 +6,8 @@
 'use strict';
 
 import * as path from 'path'
-import * as fs from 'fs/promises'
+import { readFile } from 'fs/promises'
+import { readFileSync } from 'fs'
 import { Buffer } from 'buffer'
 import * as platform from './platform'
 import * as library from './library'
@@ -135,7 +136,7 @@
 
 export async function read_bytes(path: string): Promise<Buffer>
 {
-    return fs.readFile(platform_path(path))
+    return readFile(platform_path(path))
 }
 
 export async function read(path: string): Promise<string>
@@ -147,3 +148,18 @@
 {
     return read(path).then(JSON.parse) as Promise<T>
 }
+
+export function read_bytes_sync(path: string): Buffer
+{
+  return readFileSync(platform_path(path))
+}
+
+export function read_sync(path: string): string
+{
+    return read_bytes_sync(path).toString()
+}
+
+export function read_json_sync<T>(path: string): T
+{
+    return JSON.parse(read_sync(path))
+}
--- a/src/Tools/VSCode/extension/src/isabelle_encoding.ts	Wed Mar 09 16:21:58 2022 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*  Author:     Makarius
-
-UTF-8-Isabelle symbol encoding: minimal dependencies, for use inside VSCode.
-*/
-
-'use strict';
-
-import * as fs from 'fs'
-import { TextEncoder, TextDecoder } from 'util'
-
-
-/* defined symbols */
-
-export interface Symbol_Entry
-{
-  symbol: string,
-  name: string,
-  code: number,
-  abbrevs: string[]
-}
-
-const symbols_file = process.env["ISABELLE_VSCODE_SYMBOLS"]
-
-export const symbols: [Symbol_Entry] =
-  symbols_file ? JSON.parse(fs.readFileSync(symbols_file).toString()) : []
-
-export const symbols_decode: Map<string, string> =
-  new Map(symbols.map((s: Symbol_Entry) => [s.symbol, String.fromCharCode(s.code)]))
-
-export const symbols_encode: Map<string, string> =
-  new Map(symbols.map((s: Symbol_Entry) => [String.fromCharCode(s.code), s.symbol]))
-
-
-/* encoding */
-
-export const UTF8_Isabelle = 'utf8-isabelle'
-
-export interface Options {
-  stripBOM?: boolean;
-  addBOM?: boolean;
-  defaultEncoding?: string;
-}
-
-export interface EncoderStream {
-  write(str: string): Uint8Array
-  end(): Uint8Array | undefined
-}
-
-export interface DecoderStream {
-  write(buf: Uint8Array): string
-  end(): string | undefined
-}
-
-export function getEncoder(encoding: string, options?: Options): EncoderStream
-{
-  const utf8_encoder = new TextEncoder
-  return null
-}
-
-export function getDecoder(encoding: string, options?: Options): DecoderStream
-{
-  const utf8_decoder = new TextDecoder
-  return null
-}
--- a/src/Tools/VSCode/extension/src/symbol.ts	Wed Mar 09 16:21:58 2022 +0000
+++ b/src/Tools/VSCode/extension/src/symbol.ts	Thu Mar 10 12:34:02 2022 +0100
@@ -10,7 +10,7 @@
 'use strict';
 
 import * as file from './file'
-import * as isabelle_encoding from './isabelle_encoding'
+import * as library from './library'
 
 
 /* ASCII characters */
@@ -45,14 +45,19 @@
 
 /* defined symbols */
 
-export type Entry = isabelle_encoding.Symbol_Entry
+export interface Entry {
+  symbol: string;
+  name: string;
+  abbrevs: string[];
+  code?: number;
+}
 
 export class Symbols
 {
-  entries: [Entry]
+  entries: Entry[]
   private entries_map: Map<Symbol, Entry>
 
-  constructor(entries: [Entry])
+  constructor(entries: Entry[])
   {
     this.entries = entries
     this.entries_map = new Map<Symbol, Entry>()
@@ -72,4 +77,14 @@
   }
 }
 
-export const symbols: Symbols = new Symbols(isabelle_encoding.symbols)
+function load_symbols(): Entry[]
+{
+  const vscodium_home = library.getenv("ISABELLE_VSCODIUM_HOME")
+  if (vscodium_home) {
+    const path = vscodium_home + "/resources/app/out/vs/base/browser/ui/fonts/symbols.json"
+    return file.read_json_sync(file.platform_path(path))
+  }
+  else { return [] }
+}
+
+export const symbols: Symbols = new Symbols(load_symbols())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Tools/VSCode/extension/yarn.lock	Thu Mar 10 12:34:02 2022 +0100
@@ -0,0 +1,610 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@types/mocha@^9.1.0":
+  version "9.1.0"
+  resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.0.tgz#baf17ab2cca3fcce2d322ebc30454bff487efad5"
+  integrity sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==
+
+"@types/node@^17.0.19":
+  version "17.0.21"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.21.tgz#864b987c0c68d07b4345845c3e63b75edd143644"
+  integrity sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==
+
+"@types/vscode@1.65.0":
+  version "1.65.0"
+  resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.65.0.tgz#042dd8d93c32ac62cb826cd0fa12376069d1f448"
+  integrity sha512-wQhExnh2nEzpjDMSKhUvnNmz3ucpd3E+R7wJkOhBNK3No6fG3VUdmVmMOKD0A8NDZDDDiQcLNxe3oGmX5SjJ5w==
+
+"@ungap/promise-all-settled@1.1.2":
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
+  integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==
+
+ansi-colors@4.1.1:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
+  integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
+
+ansi-regex@^5.0.1:
+  version "5.0.1"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
+  integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+
+ansi-styles@^4.0.0, ansi-styles@^4.1.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
+  integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
+  dependencies:
+    color-convert "^2.0.1"
+
+anymatch@~3.1.2:
+  version "3.1.2"
+  resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
+  integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
+  dependencies:
+    normalize-path "^3.0.0"
+    picomatch "^2.0.4"
+
+argparse@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
+  integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
+
+balanced-match@^1.0.0:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
+  integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
+
+binary-extensions@^2.0.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
+  integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
+
+brace-expansion@^1.1.7:
+  version "1.1.11"
+  resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
+  integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
+  dependencies:
+    balanced-match "^1.0.0"
+    concat-map "0.0.1"
+
+braces@~3.0.2:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
+  integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
+  dependencies:
+    fill-range "^7.0.1"
+
+browser-stdout@1.3.1:
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
+  integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
+
+camelcase@^6.0.0:
+  version "6.3.0"
+  resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
+  integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
+
+chalk@^4.1.0:
+  version "4.1.2"
+  resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
+  integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
+  dependencies:
+    ansi-styles "^4.1.0"
+    supports-color "^7.1.0"
+
+chokidar@3.5.3:
+  version "3.5.3"
+  resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
+  integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
+  dependencies:
+    anymatch "~3.1.2"
+    braces "~3.0.2"
+    glob-parent "~5.1.2"
+    is-binary-path "~2.1.0"
+    is-glob "~4.0.1"
+    normalize-path "~3.0.0"
+    readdirp "~3.6.0"
+  optionalDependencies:
+    fsevents "~2.3.2"
+
+cliui@^7.0.2:
+  version "7.0.4"
+  resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
+  integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
+  dependencies:
+    string-width "^4.2.0"
+    strip-ansi "^6.0.0"
+    wrap-ansi "^7.0.0"
+
+color-convert@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
+  integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
+  dependencies:
+    color-name "~1.1.4"
+
+color-name@~1.1.4:
+  version "1.1.4"
+  resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
+  integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+
+concat-map@0.0.1:
+  version "0.0.1"
+  resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+  integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
+
+debug@4.3.3:
+  version "4.3.3"
+  resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
+  integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
+  dependencies:
+    ms "2.1.2"
+
+decamelize@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837"
+  integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==
+
+diff@5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b"
+  integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==
+
+emoji-regex@^8.0.0:
+  version "8.0.0"
+  resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
+  integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
+
+escalade@^3.1.1:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
+  integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
+
+escape-string-regexp@4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
+  integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
+
+fill-range@^7.0.1:
+  version "7.0.1"
+  resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
+  integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
+  dependencies:
+    to-regex-range "^5.0.1"
+
+find-up@5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
+  integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
+  dependencies:
+    locate-path "^6.0.0"
+    path-exists "^4.0.0"
+
+flat@^5.0.2:
+  version "5.0.2"
+  resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241"
+  integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
+
+fs.realpath@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+  integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
+
+fsevents@~2.3.2:
+  version "2.3.2"
+  resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
+  integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
+
+get-caller-file@^2.0.5:
+  version "2.0.5"
+  resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
+  integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
+
+glob-parent@~5.1.2:
+  version "5.1.2"
+  resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
+  integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
+  dependencies:
+    is-glob "^4.0.1"
+
+glob@7.2.0:
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
+  integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
+  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"
+
+growl@1.10.5:
+  version "1.10.5"
+  resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
+  integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
+
+has-flag@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
+  integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
+
+he@1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
+  integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
+
+inflight@^1.0.4:
+  version "1.0.6"
+  resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+  integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
+  dependencies:
+    once "^1.3.0"
+    wrappy "1"
+
+inherits@2:
+  version "2.0.4"
+  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
+  integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+
+is-binary-path@~2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
+  integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
+  dependencies:
+    binary-extensions "^2.0.0"
+
+is-extglob@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
+  integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
+
+is-fullwidth-code-point@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
+  integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
+
+is-glob@^4.0.1, is-glob@~4.0.1:
+  version "4.0.3"
+  resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
+  integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
+  dependencies:
+    is-extglob "^2.1.1"
+
+is-number@^7.0.0:
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
+  integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+
+is-plain-obj@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
+  integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
+
+is-unicode-supported@^0.1.0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
+  integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
+
+isexe@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+  integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
+
+js-yaml@4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
+  integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
+  dependencies:
+    argparse "^2.0.1"
+
+locate-path@^6.0.0:
+  version "6.0.0"
+  resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
+  integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
+  dependencies:
+    p-locate "^5.0.0"
+
+log-symbols@4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
+  integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
+  dependencies:
+    chalk "^4.1.0"
+    is-unicode-supported "^0.1.0"
+
+lru-cache@^6.0.0:
+  version "6.0.0"
+  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
+  integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
+  dependencies:
+    yallist "^4.0.0"
+
+minimatch@3.0.4:
+  version "3.0.4"
+  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
+  integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
+  dependencies:
+    brace-expansion "^1.1.7"
+
+minimatch@^3.0.4:
+  version "3.1.2"
+  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
+  integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
+  dependencies:
+    brace-expansion "^1.1.7"
+
+mocha@^9.2.1:
+  version "9.2.1"
+  resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.1.tgz#a1abb675aa9a8490798503af57e8782a78f1338e"
+  integrity sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ==
+  dependencies:
+    "@ungap/promise-all-settled" "1.1.2"
+    ansi-colors "4.1.1"
+    browser-stdout "1.3.1"
+    chokidar "3.5.3"
+    debug "4.3.3"
+    diff "5.0.0"
+    escape-string-regexp "4.0.0"
+    find-up "5.0.0"
+    glob "7.2.0"
+    growl "1.10.5"
+    he "1.2.0"
+    js-yaml "4.1.0"
+    log-symbols "4.1.0"
+    minimatch "3.0.4"
+    ms "2.1.3"
+    nanoid "3.2.0"
+    serialize-javascript "6.0.0"
+    strip-json-comments "3.1.1"
+    supports-color "8.1.1"
+    which "2.0.2"
+    workerpool "6.2.0"
+    yargs "16.2.0"
+    yargs-parser "20.2.4"
+    yargs-unparser "2.0.0"
+
+ms@2.1.2:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
+  integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
+
+ms@2.1.3:
+  version "2.1.3"
+  resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
+  integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+
+nanoid@3.2.0:
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
+  integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==
+
+normalize-path@^3.0.0, normalize-path@~3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
+  integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
+
+once@^1.3.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+  integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
+  dependencies:
+    wrappy "1"
+
+p-limit@^3.0.2:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
+  integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
+  dependencies:
+    yocto-queue "^0.1.0"
+
+p-locate@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
+  integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
+  dependencies:
+    p-limit "^3.0.2"
+
+path-exists@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
+  integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
+
+path-is-absolute@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+  integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
+
+picomatch@^2.0.4, picomatch@^2.2.1:
+  version "2.3.1"
+  resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
+  integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
+
+randombytes@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
+  integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
+  dependencies:
+    safe-buffer "^5.1.0"
+
+readdirp@~3.6.0:
+  version "3.6.0"
+  resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
+  integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
+  dependencies:
+    picomatch "^2.2.1"
+
+require-directory@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
+  integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
+
+safe-buffer@^5.1.0:
+  version "5.2.1"
+  resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
+  integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
+
+semver@^7.3.4:
+  version "7.3.5"
+  resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
+  integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
+  dependencies:
+    lru-cache "^6.0.0"
+
+serialize-javascript@6.0.0:
+  version "6.0.0"
+  resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8"
+  integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==
+  dependencies:
+    randombytes "^2.1.0"
+
+string-width@^4.1.0, string-width@^4.2.0:
+  version "4.2.3"
+  resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+  integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+  dependencies:
+    emoji-regex "^8.0.0"
+    is-fullwidth-code-point "^3.0.0"
+    strip-ansi "^6.0.1"
+
+strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+  version "6.0.1"
+  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+  integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+  dependencies:
+    ansi-regex "^5.0.1"
+
+strip-json-comments@3.1.1:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
+  integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
+
+supports-color@8.1.1:
+  version "8.1.1"
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
+  integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
+  dependencies:
+    has-flag "^4.0.0"
+
+supports-color@^7.1.0:
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
+  integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
+  dependencies:
+    has-flag "^4.0.0"
+
+to-regex-range@^5.0.1:
+  version "5.0.1"
+  resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
+  integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
+  dependencies:
+    is-number "^7.0.0"
+
+typescript@^4.5.5:
+  version "4.6.2"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.2.tgz#fe12d2727b708f4eef40f51598b3398baa9611d4"
+  integrity sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==
+
+vscode-jsonrpc@6.0.0:
+  version "6.0.0"
+  resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz#108bdb09b4400705176b957ceca9e0880e9b6d4e"
+  integrity sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==
+
+vscode-languageclient@~7.0.0:
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz#b505c22c21ffcf96e167799757fca07a6bad0fb2"
+  integrity sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==
+  dependencies:
+    minimatch "^3.0.4"
+    semver "^7.3.4"
+    vscode-languageserver-protocol "3.16.0"
+
+vscode-languageserver-protocol@3.16.0:
+  version "3.16.0"
+  resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz#34135b61a9091db972188a07d337406a3cdbe821"
+  integrity sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==
+  dependencies:
+    vscode-jsonrpc "6.0.0"
+    vscode-languageserver-types "3.16.0"
+
+vscode-languageserver-types@3.16.0, vscode-languageserver-types@~3.16.0:
+  version "3.16.0"
+  resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz#ecf393fc121ec6974b2da3efb3155644c514e247"
+  integrity sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==
+
+which@2.0.2:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
+  integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
+  dependencies:
+    isexe "^2.0.0"
+
+workerpool@6.2.0:
+  version "6.2.0"
+  resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b"
+  integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==
+
+wrap-ansi@^7.0.0:
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
+  integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
+  dependencies:
+    ansi-styles "^4.0.0"
+    string-width "^4.1.0"
+    strip-ansi "^6.0.0"
+
+wrappy@1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+  integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
+
+y18n@^5.0.5:
+  version "5.0.8"
+  resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
+  integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
+
+yallist@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
+  integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
+
+yargs-parser@20.2.4:
+  version "20.2.4"
+  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"
+  integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==
+
+yargs-parser@^20.2.2:
+  version "20.2.9"
+  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
+  integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
+
+yargs-unparser@2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb"
+  integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==
+  dependencies:
+    camelcase "^6.0.0"
+    decamelize "^4.0.0"
+    flat "^5.0.2"
+    is-plain-obj "^2.1.0"
+
+yargs@16.2.0:
+  version "16.2.0"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
+  integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
+  dependencies:
+    cliui "^7.0.2"
+    escalade "^3.1.1"
+    get-caller-file "^2.0.5"
+    require-directory "^2.1.1"
+    string-width "^4.2.0"
+    y18n "^5.0.5"
+    yargs-parser "^20.2.2"
+
+yocto-queue@^0.1.0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
+  integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Tools/VSCode/patches/isabelle_encoding.patch	Thu Mar 10 12:34:02 2022 +0100
@@ -0,0 +1,54 @@
+diff --git a/src/vs/workbench/services/textfile/common/encoding.ts b/src/vs/workbench/services/textfile/common/encoding.ts
+--- a/src/vs/workbench/services/textfile/common/encoding.ts
++++ b/src/vs/workbench/services/textfile/common/encoding.ts
+@@ -6,6 +6,7 @@
+ import { Readable, ReadableStream, newWriteableStream, listenStream } from 'vs/base/common/stream';
+ import { VSBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer';
+ import { IDisposable } from 'vs/base/common/lifecycle';
++import * as isabelle_encoding from './isabelle_encoding';
+ 
+ export const UTF8 = 'utf8';
+ export const UTF8_with_bom = 'utf8bom';
+@@ -78,7 +79,9 @@ class DecoderStream implements IDecoderStream {
+ 	 */
+ 	static async create(encoding: string): Promise<DecoderStream> {
+ 		let decoder: IDecoderStream | undefined = undefined;
+-		if (encoding !== UTF8) {
++		if (encoding === isabelle_encoding.ENCODING) {
++			decoder = isabelle_encoding.getDecoder();
++		} else if (encoding !== UTF8) {
+ 			const iconv = await import('@vscode/iconv-lite-umd');
+ 			decoder = iconv.getDecoder(toNodeEncoding(encoding));
+ 		} else {
+@@ -212,7 +215,9 @@ export function toDecodeStream(source: VSBufferReadableStream, options: IDecodeS
+ 
+ export async function toEncodeReadable(readable: Readable<string>, encoding: string, options?: { addBOM?: boolean }): Promise<VSBufferReadable> {
+ 	const iconv = await import('@vscode/iconv-lite-umd');
+-	const encoder = iconv.getEncoder(toNodeEncoding(encoding), options);
++	const encoder =
++		encoding === isabelle_encoding.ENCODING ?
++			isabelle_encoding.getEncoder() : iconv.getEncoder(toNodeEncoding(encoding), options);
+ 
+ 	let bytesWritten = false;
+ 	let done = false;
+@@ -262,7 +267,7 @@ export async function toEncodeReadable(readable: Readable<string>, encoding: str
+ export async function encodingExists(encoding: string): Promise<boolean> {
+ 	const iconv = await import('@vscode/iconv-lite-umd');
+ 
+-	return iconv.encodingExists(toNodeEncoding(encoding));
++	return encoding === isabelle_encoding.ENCODING || iconv.encodingExists(toNodeEncoding(encoding));
+ }
+ 
+ export function toNodeEncoding(enc: string | null): string {
+@@ -479,6 +484,11 @@ export function detectEncodingFromBuffer({ buffer, bytesRead }: IReadResult, aut
+ }
+ 
+ export const SUPPORTED_ENCODINGS: { [encoding: string]: { labelLong: string; labelShort: string; order: number; encodeOnly?: boolean; alias?: string } } = {
++	utf8isabelle: {
++		labelLong: isabelle_encoding.LABEL,
++		labelShort: isabelle_encoding.LABEL,
++		order: 0,
++	},
+ 	utf8: {
+ 		labelLong: 'UTF-8',
+ 		labelShort: 'UTF-8',
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Tools/VSCode/patches/isabelle_encoding.ts	Thu Mar 10 12:34:02 2022 +0100
@@ -0,0 +1,68 @@
+/*  Author:     Makarius
+
+UTF-8-Isabelle symbol encoding: for use inside VSCode.
+*/
+
+'use strict';
+
+
+/* defined symbols */
+
+export interface Symbol_Code {
+  symbol: string;
+  code: number;
+}
+
+export const static_symbols: Symbol_Code[] = [/*symbols*/];
+
+export const symbols_decode: Map<string, string> =
+  new Map(static_symbols.map((s: Symbol_Code) => [s.symbol, String.fromCharCode(s.code)]));
+
+export const symbols_encode: Map<string, string> =
+  new Map(static_symbols.map((s: Symbol_Code) => [String.fromCharCode(s.code), s.symbol]));
+
+
+/* encoding */
+
+export const ENCODING = 'utf8isabelle';
+export const LABEL = 'UTF-8-Isabelle';
+
+export interface Options {
+  stripBOM?: boolean;
+  addBOM?: boolean;
+  defaultEncoding?: string;
+}
+
+export interface IEncoderStream {
+  write(input: string): Uint8Array;
+  end(): Uint8Array | undefined;
+}
+
+export interface IDecoderStream {
+  write(input: Uint8Array): string;
+  end(): string | undefined;
+}
+
+export function getEncoder(): IEncoderStream {
+  const utf8_encoder = new TextEncoder();
+  return {
+    write(input: string): Uint8Array {
+      return utf8_encoder.encode(input);
+    },
+    end(): Uint8Array | undefined {
+      return utf8_encoder.encode();
+    }
+  };
+}
+
+export function getDecoder(): IDecoderStream {
+  const utf8TextDecoder = new TextDecoder();
+  return {
+    write(input: Uint8Array): string {
+      return utf8TextDecoder.decode(input, { stream: true });
+    },
+    end(): string | undefined {
+      return utf8TextDecoder.decode();
+    }
+  };
+}
--- a/src/Tools/VSCode/src/build_vscode.scala	Wed Mar 09 16:21:58 2022 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*  Title:      Tools/VSCode/src/build_vscode.scala
-    Author:     Makarius
-
-Build VSCode configuration and extension module for Isabelle.
-*/
-
-package isabelle.vscode
-
-
-import isabelle._
-
-
-object Build_VSCode
-{
-  val extension_dir = Path.explode("$ISABELLE_VSCODE_HOME/extension")
-
-
-  /* grammar */
-
-  def build_grammar(options: Options, progress: Progress = new Progress): Unit =
-  {
-    val logic = TextMate_Grammar.default_logic
-    val keywords = Sessions.base_info(options, logic).check.base.overall_syntax.keywords
-
-    val output_path = extension_dir + Path.explode(TextMate_Grammar.default_output(logic))
-    progress.echo(output_path.expand.implode)
-    File.write_backup(output_path, TextMate_Grammar.generate(keywords))
-  }
-
-
-  /* extension */
-
-  def uninstall_extension(progress: Progress = new Progress): Unit =
-    progress.bash("isabelle vscode --uninstall-extension Isabelle.isabelle").check
-
-  def install_extension(vsix_path: Path, progress: Progress = new Progress): Unit =
-    progress.bash("isabelle vscode --install-extension " +
-      File.bash_platform_path(vsix_path))
-
-  def build_extension(progress: Progress = new Progress): Path =
-  {
-    val output_path = extension_dir + Path.explode("out")
-    Isabelle_System.rm_tree(output_path)
-    Isabelle_System.make_directory(output_path)
-    progress.echo(output_path.expand.implode)
-
-    val result =
-      progress.bash("npm install && npm update --dev && vsce package",
-        cwd = extension_dir.file, echo = true).check
-
-    val Pattern = """.*Packaged:.*(isabelle-.*\.vsix).*""".r
-    result.out_lines.collectFirst(
-      { case Pattern(vsix_name) => extension_dir + Path.basic(vsix_name) })
-      .getOrElse(error("Failed to guess resulting .vsix file name"))
-  }
-
-
-  /* Isabelle tool wrapper */
-
-  val isabelle_tool =
-    Isabelle_Tool("build_vscode", "build Isabelle/VSCode extension module",
-      Scala_Project.here, args =>
-    {
-      var install = false
-      var uninstall = false
-
-      val getopts = Getopts("""
-Usage: isabelle build_vscode
-
-  Options are:
-    -I           install resulting extension
-    -U           uninstall extension (no build)
-
-Build Isabelle/VSCode extension module in directory
-""" + extension_dir.expand + """
-
-This requires node.js/npm and the vsce build tool.
-""",
-        "I" -> (_ => install = true),
-        "U" -> (_ => uninstall = true))
-
-      val more_args = getopts(args)
-      if (more_args.nonEmpty) getopts.usage()
-
-      val options = Options.init()
-      val progress = new Console_Progress()
-
-      if (uninstall) {
-        uninstall_extension(progress = progress)
-      }
-      else {
-        build_grammar(options, progress = progress)
-        val path = build_extension(progress = progress)
-        if (install) install_extension(path, progress = progress)
-      }
-    })
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Tools/VSCode/src/build_vscode_extension.scala	Thu Mar 10 12:34:02 2022 +0100
@@ -0,0 +1,98 @@
+/*  Title:      Tools/VSCode/src/build_vscode_extension.scala
+    Author:     Makarius
+
+Build the Isabelle/VSCode extension.
+*/
+
+package isabelle.vscode
+
+
+import isabelle._
+
+
+object Build_VSCode
+{
+  val extension_dir = Path.explode("$ISABELLE_VSCODE_HOME/extension")
+
+
+  /* grammar */
+
+  def build_grammar(options: Options, progress: Progress = new Progress): Unit =
+  {
+    val logic = TextMate_Grammar.default_logic
+    val keywords = Sessions.base_info(options, logic).check.base.overall_syntax.keywords
+
+    val output_path = extension_dir + Path.explode(TextMate_Grammar.default_output(logic))
+    progress.echo(output_path.expand.implode)
+    File.write_backup(output_path, TextMate_Grammar.generate(keywords))
+  }
+
+
+  /* extension */
+
+  def uninstall_extension(progress: Progress = new Progress): Unit =
+    progress.bash("isabelle vscode --uninstall-extension Isabelle.isabelle").check
+
+  def install_extension(vsix_path: Path, progress: Progress = new Progress): Unit =
+    progress.bash("isabelle vscode --install-extension " +
+      File.bash_platform_path(vsix_path))
+
+  def build_extension(progress: Progress = new Progress): Path =
+  {
+    Isabelle_System.require_command("node")
+    Isabelle_System.require_command("yarn")
+    Isabelle_System.require_command("vsce")
+
+    val output_path = extension_dir + Path.explode("out")
+    Isabelle_System.rm_tree(output_path)
+    Isabelle_System.make_directory(output_path)
+    progress.echo(output_path.expand.implode)
+
+    val result =
+      progress.bash("yarn && vsce package", cwd = extension_dir.file, echo = true).check
+
+    val Pattern = """.*Packaged:.*(isabelle-.*\.vsix).*""".r
+    result.out_lines.collectFirst(
+      { case Pattern(vsix_name) => extension_dir + Path.basic(vsix_name) })
+      .getOrElse(error("Failed to guess resulting .vsix file name"))
+  }
+
+
+  /* Isabelle tool wrapper */
+
+  val isabelle_tool =
+    Isabelle_Tool("build_vscode_extension", "build Isabelle/VSCode extension module",
+      Scala_Project.here, args =>
+    {
+      var install = false
+      var uninstall = false
+
+      val getopts = Getopts("""
+Usage: isabelle build_vscode_extension
+
+  Options are:
+    -I           install resulting extension
+    -U           uninstall extension (no build)
+
+Build Isabelle/VSCode extension module in directory
+""" + extension_dir.expand + """
+""",
+        "I" -> (_ => install = true),
+        "U" -> (_ => uninstall = true))
+
+      val more_args = getopts(args)
+      if (more_args.nonEmpty) getopts.usage()
+
+      val options = Options.init()
+      val progress = new Console_Progress()
+
+      if (uninstall) {
+        uninstall_extension(progress = progress)
+      }
+      else {
+        build_grammar(options, progress = progress)
+        val path = build_extension(progress = progress)
+        if (install) install_extension(path, progress = progress)
+      }
+    })
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Tools/VSCode/src/build_vscodium.scala	Thu Mar 10 12:34:02 2022 +0100
@@ -0,0 +1,487 @@
+/*  Title:      Tools/VSCode/src/build_vscodium.scala
+    Author:     Makarius
+
+Build the Isabelle system component for VSCodium: cross-compilation for all
+platforms.
+*/
+
+package isabelle.vscode
+
+
+import isabelle._
+
+import java.security.MessageDigest
+import java.util.Base64
+
+
+object Build_VSCodium
+{
+  /* global parameters */
+
+  lazy val version: String = Isabelle_System.getenv_strict("ISABELLE_VSCODE_VERSION")
+  val vscodium_repository = "https://github.com/VSCodium/vscodium.git"
+  val vscodium_download = "https://github.com/VSCodium/vscodium/releases/download"
+
+  def vscodium_exe(dir: Path): Path = dir + Path.explode("bin/codium")
+
+
+  /* Isabelle symbols (static subset only) */
+
+  def make_symbols(): File.Content =
+  {
+    val symbols = Symbol.Symbols.load(static = true)
+    val symbols_js =
+      JSON.Format.apply_lines(
+        for (entry <- symbols.entries) yield
+          JSON.Object(
+            "symbol" -> entry.symbol,
+            "name" -> entry.name,
+            "abbrevs" -> entry.abbrevs) ++
+          JSON.optional("code", entry.code))
+
+    File.Content(Path.explode("symbols.json"), symbols_js)
+  }
+
+  def make_isabelle_encoding(header: String): File.Content =
+  {
+    val symbols = Symbol.Symbols.load(static = true)
+    val symbols_js =
+      JSON.Format.apply_lines(
+        for (entry <- symbols.entries; code <- entry.code)
+          yield JSON.Object("symbol" -> entry.symbol, "code" -> code))
+
+    val path = Path.explode("isabelle_encoding.ts")
+    val body =
+      File.read(Path.explode("$ISABELLE_VSCODE_HOME/patches") + path)
+        .replace("[/*symbols*/]", symbols_js)
+    File.Content(path, header + "\n" + body)
+  }
+
+
+  /* platform info */
+
+  sealed case class Platform_Info(
+    platform: Platform.Family.Value,
+    download_template: String,
+    build_name: String,
+    env: List[String])
+  {
+    def is_linux: Boolean = platform == Platform.Family.linux
+
+    def download_name: String = "VSCodium-" + download_template.replace("{VERSION}", version)
+    def download_zip: Boolean = download_name.endsWith(".zip")
+
+    def download(dir: Path, progress: Progress = new Progress): Unit =
+    {
+      if (download_zip) Isabelle_System.require_command("unzip", test = "-h")
+
+      Isabelle_System.with_tmp_file("download")(download_file =>
+      {
+        Isabelle_System.download_file(vscodium_download + "/" + version + "/" + download_name,
+          download_file, progress = progress)
+
+        progress.echo("Extract ...")
+        if (download_zip) {
+          Isabelle_System.bash("unzip -x " + File.bash_path(download_file), cwd = dir.file).check
+        }
+        else {
+          Isabelle_System.gnutar("-xzf " + File.bash_path(download_file), dir = dir).check
+        }
+      })
+    }
+
+    def get_vscodium_repository(vscodium_dir: Path, progress: Progress = new Progress): Unit =
+    {
+      progress.echo("Getting VSCodium repository ...")
+      Isabelle_System.bash(
+        List(
+          "set -e",
+          "git clone -n " + Bash.string(vscodium_repository) + " .",
+          "git checkout -q " + Bash.string(version)
+        ).mkString("\n"), cwd = vscodium_dir.file).check
+
+      progress.echo("Getting VSCode repository ...")
+      Isabelle_System.bash(environment + "\n" + "./get_repo.sh", cwd = vscodium_dir.file).check
+    }
+
+    def platform_dir(dir: Path): Path =
+    {
+      val platform_name =
+        if (platform == Platform.Family.windows) Platform.Family.native(platform)
+        else Platform.Family.standard(platform)
+      dir + Path.explode(platform_name)
+    }
+
+    def build_dir(dir: Path): Path = dir + Path.explode(build_name)
+
+    def environment: String =
+      (("MS_TAG=" + Bash.string(version)) :: "SHOULD_BUILD=yes" :: "VSCODE_ARCH=x64" :: env)
+        .map(s => "export " + s + "\n").mkString
+
+    def patch_sources(base_dir: Path): String =
+    {
+      val dir = base_dir + Path.explode("vscode")
+      Isabelle_System.with_copy_dir(dir, dir.orig) {
+        // macos icns
+        for (name <- Seq("build/lib/electron.js", "build/lib/electron.ts")) {
+          File.change(dir + Path.explode(name), strict = true) {
+            _.replace("""'resources/darwin/' + icon + '.icns'""",
+              """'resources/darwin/' + icon.toLowerCase() + '.icns'""")
+          }
+        }
+
+        // isabelle_encoding.ts
+        {
+          val common_dir = dir + Path.explode("src/vs/workbench/services/textfile/common")
+          val header =
+            split_lines(File.read(common_dir + Path.explode("encoding.ts")))
+              .takeWhile(_.trim.nonEmpty)
+          make_isabelle_encoding(cat_lines(header)).write(common_dir)
+        }
+
+        // explicit patches
+        {
+          val patches_dir = Path.explode("$ISABELLE_VSCODE_HOME/patches")
+          for (name <- Seq("isabelle_encoding")) {
+            val path = patches_dir + Path.basic(name).patch
+            Isabelle_System.bash("patch -p1 < " + File.bash_path(path), cwd = dir.file).check
+          }
+        }
+
+        Isabelle_System.make_patch(base_dir, dir.base.orig, dir.base)
+      }
+    }
+
+    def patch_resources(base_dir: Path): String =
+    {
+      val dir = base_dir + Path.explode("resources")
+      Isabelle_System.with_copy_dir(dir, dir.orig) {
+        val fonts_dir = dir + Path.explode("app/out/vs/base/browser/ui/fonts")
+        HTML.init_fonts(fonts_dir.dir)
+        make_symbols().write(fonts_dir)
+
+        val workbench_css = dir + Path.explode("app/out/vs/workbench/workbench.desktop.main.css")
+        val checksum1 = file_checksum(workbench_css)
+        File.append(workbench_css, "\n\n" + HTML.fonts_css_dir(prefix = "../base/browser/ui"))
+        val checksum2 = file_checksum(workbench_css)
+
+        val file_name = workbench_css.file_name
+        File.change_lines(dir + Path.explode("app/product.json")) { _.map(line =>
+          if (line.containsSlice(file_name) && line.contains(checksum1)) {
+            line.replace(checksum1, checksum2)
+          }
+          else line)
+        }
+
+        Isabelle_System.make_patch(dir.dir, dir.orig.base, dir.base)
+      }
+    }
+
+    def init_resources(base_dir: Path): Path =
+    {
+      val resources_dir = base_dir + Path.explode("resources")
+      if (platform == Platform.Family.macos) {
+        Isabelle_System.symlink(Path.explode("VSCodium.app/Contents/Resources"), resources_dir)
+      }
+      resources_dir
+    }
+
+    def node_binaries(target_dir: Path, progress: Progress): Unit =
+    {
+      Isabelle_System.with_tmp_dir("download")(download_dir =>
+      {
+        download(download_dir, progress = progress)
+        val dir1 = init_resources(download_dir)
+        val dir2 = init_resources(target_dir)
+        for (name <- Seq("app/node_modules.asar", "app/node_modules.asar.unpacked")) {
+          val path = Path.explode(name)
+          Isabelle_System.rm_tree(dir2 + path)
+          Isabelle_System.copy_dir(dir1 + path, dir2 + path)
+        }
+      })
+    }
+
+    def setup_executables(dir: Path): Unit =
+    {
+      val exe = vscodium_exe(dir)
+      Isabelle_System.make_directory(exe.dir)
+
+      platform match {
+        case Platform.Family.macos =>
+          File.write(exe, macos_exe)
+          File.set_executable(exe, true)
+        case Platform.Family.windows =>
+          val files1 = File.find_files(exe.dir.file)
+          val files2 = File.find_files(dir.file, pred = file =>
+            {
+              val name = file.getName
+              name.endsWith(".dll") || name.endsWith(".exe") || name.endsWith(".node")
+            })
+          for (file <- files1 ::: files2) File.set_executable(File.path(file), true)
+          Isabelle_System.bash("chmod -R o-w " + File.bash_path(dir)).check
+        case _ =>
+      }
+    }
+  }
+
+
+  // see https://github.com/microsoft/vscode/blob/main/build/gulpfile.vscode.js
+  // function computeChecksum(filename)
+  private def file_checksum(path: Path): String =
+  {
+    val digest = MessageDigest.getInstance("MD5")
+    digest.update(Bytes.read(path).array)
+    Bytes(Base64.getEncoder.encode(digest.digest()))
+      .text.replaceAll("=", "")
+  }
+
+  private val platform_infos: Map[Platform.Family.Value, Platform_Info] =
+    Iterator(
+      Platform_Info(Platform.Family.linux, "linux-x64-{VERSION}.tar.gz", "VSCode-linux-x64",
+        List("OS_NAME=linux", "SKIP_LINUX_PACKAGES=True")),
+      Platform_Info(Platform.Family.linux_arm, "linux-arm64-{VERSION}.tar.gz", "VSCode-linux-arm64",
+        List("OS_NAME=linux", "SKIP_LINUX_PACKAGES=True", "VSCODE_ARCH=arm64")),
+      Platform_Info(Platform.Family.macos, "darwin-x64-{VERSION}.zip", "VSCode-darwin-x64",
+        List("OS_NAME=osx")),
+      Platform_Info(Platform.Family.windows, "win32-x64-{VERSION}.zip", "VSCode-win32-x64",
+        List("OS_NAME=windows",
+          "SHOULD_BUILD_ZIP=no",
+          "SHOULD_BUILD_EXE_SYS=no",
+          "SHOULD_BUILD_EXE_USR=no",
+          "SHOULD_BUILD_MSI=no",
+          "SHOULD_BUILD_MSI_NOUP=no")))
+      .map(info => info.platform -> info).toMap
+
+  def the_platform_info(platform: Platform.Family.Value): Platform_Info =
+    platform_infos.getOrElse(platform, error("No platform info for " + quote(platform.toString)))
+
+  def linux_platform_info: Platform_Info =
+    the_platform_info(Platform.Family.linux)
+
+
+  /* check system */
+
+  def check_system(platforms: List[Platform.Family.Value]): Unit =
+  {
+    if (Platform.family != Platform.Family.linux) error("Not a Linux/x86_64 system")
+
+    Isabelle_System.require_command("git")
+    Isabelle_System.require_command("node")
+    Isabelle_System.require_command("yarn")
+    Isabelle_System.require_command("jq")
+
+    if (platforms.contains(Platform.Family.windows)) {
+      Isabelle_System.require_command("wine")
+    }
+
+    if (platforms.exists(platform => the_platform_info(platform).download_zip)) {
+      Isabelle_System.require_command("unzip", test = "-h")
+    }
+  }
+
+
+  /* original repository clones and patches */
+
+  def vscodium_patch(verbose: Boolean = false, progress: Progress = new Progress): String =
+  {
+    val platform_info = linux_platform_info
+    check_system(List(platform_info.platform))
+
+    Isabelle_System.with_tmp_dir("vscodium")(vscodium_dir =>
+    {
+      platform_info.get_vscodium_repository(vscodium_dir, progress = progress)
+      val vscode_dir = vscodium_dir + Path.basic("vscode")
+      progress.echo("Prepare ...")
+      Isabelle_System.with_copy_dir(vscode_dir, vscode_dir.orig) {
+        progress.bash(
+          List(
+            "set -e",
+            platform_info.environment,
+            "./prepare_vscode.sh",
+            // enforce binary diff of code.xpm
+            "cp vscode/resources/linux/code.png vscode/resources/linux/rpm/code.xpm"
+          ).mkString("\n"), cwd = vscodium_dir.file, echo = verbose).check
+        Isabelle_System.make_patch(vscodium_dir, vscode_dir.orig.base, vscode_dir.base,
+          diff_options = "--exclude=.git --exclude=node_modules")
+      }
+    })
+  }
+
+
+  /* build vscodium */
+
+  def default_platforms: List[Platform.Family.Value] = Platform.Family.list
+
+  def macos_exe: String =
+"""#!/usr/bin/env bash
+
+unset CDPATH
+VSCODE_PATH="$(cd "$(dirname "$0")"/../VSCodium.app/Contents; pwd)"
+
+ELECTRON="$VSCODE_PATH/MacOS/Electron"
+CLI="$VSCODE_PATH/Resources/app/out/cli.js"
+ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" --ms-enable-electron-run-as-node "$@"
+exit $?
+"""
+
+  def build_vscodium(
+    target_dir: Path = Path.current,
+    platforms: List[Platform.Family.Value] = default_platforms,
+    verbose: Boolean = false,
+    progress: Progress = new Progress): Unit =
+  {
+    check_system(platforms)
+
+
+    /* component */
+
+    val component_name = "vscodium-" + version
+    val component_dir = Isabelle_System.new_directory(target_dir + Path.basic(component_name))
+    progress.echo("Component " + component_dir)
+
+
+    /* patches */
+
+    progress.echo("\n* Building patches:")
+
+    val patches_dir = Isabelle_System.new_directory(component_dir + Path.basic("patches"))
+
+    def write_patch(name: String, patch: String): Unit =
+      File.write(patches_dir + Path.explode(name).patch, patch)
+
+    write_patch("01-vscodium", vscodium_patch(verbose = verbose, progress = progress))
+
+
+    /* build */
+
+    for (platform <- platforms) yield {
+      val platform_info = the_platform_info(platform)
+
+      Isabelle_System.with_tmp_dir("vscodium")(vscodium_dir =>
+      {
+        progress.echo("\n* Building " + platform + ":")
+
+        platform_info.get_vscodium_repository(vscodium_dir, progress = progress)
+
+        val sources_patch = platform_info.patch_sources(vscodium_dir)
+        if (platform_info.is_linux) write_patch("02-isabelle_sources", sources_patch)
+
+        progress.echo("Build ...")
+        progress.bash(platform_info.environment + "\n" + "./build.sh",
+          cwd = vscodium_dir.file, echo = verbose).check
+
+        if (platform_info.is_linux) {
+          Isabelle_System.copy_file(vscodium_dir + Path.explode("LICENSE"), component_dir)
+        }
+
+        val platform_dir = platform_info.platform_dir(component_dir)
+        Isabelle_System.copy_dir(platform_info.build_dir(vscodium_dir), platform_dir)
+        platform_info.node_binaries(platform_dir, progress)
+
+        val resources_patch = platform_info.patch_resources(platform_dir)
+        if (platform_info.is_linux) write_patch("03-isabelle_resources", resources_patch)
+
+        platform_info.setup_executables(platform_dir)
+      })
+    }
+
+    Isabelle_System.bash("gzip *.patch", cwd = patches_dir.file).check
+
+
+    /* settings */
+
+    val etc_dir = Isabelle_System.make_directory(component_dir + Path.explode("etc"))
+    File.write(etc_dir + Path.basic("settings"),
+      """# -*- shell-script -*- :mode=shellscript:
+
+ISABELLE_VSCODIUM_HOME="$COMPONENT/${ISABELLE_WINDOWS_PLATFORM64:-$ISABELLE_PLATFORM64}"
+
+case "$ISABELLE_PLATFORM_FAMILY" in
+  linux)
+    ISABELLE_ELECTRON="$ISABELLE_VSCODIUM_HOME/codium"
+    ;;
+  macos)
+    ISABELLE_ELECTRON="$ISABELLE_VSCODIUM_HOME/VSCodium.app/Contents/MacOS/Electron"
+    ;;
+  windows)
+    ISABELLE_ELECTRON="$ISABELLE_VSCODIUM_HOME/VSCodium.exe"
+    ;;
+esac
+""")
+
+
+    /* README */
+
+    File.write(component_dir + Path.basic("README"),
+      "This is VSCodium " + version + " from " + vscodium_repository +
+"""
+
+It has been built from sources using "isabelle build_vscodium". This applies
+a few changes required for Isabelle/VSCode, see "patches" directory for a
+formal record.
+
+
+        Makarius
+        """ + Date.Format.date(Date.now()) + "\n")
+  }
+
+
+  /* Isabelle tool wrappers */
+
+  val isabelle_tool1 =
+    Isabelle_Tool("build_vscodium", "build component for VSCodium",
+      Scala_Project.here, args =>
+    {
+      var target_dir = Path.current
+      var platforms = default_platforms
+      var verbose = false
+
+      val getopts = Getopts("""
+Usage: build_vscodium [OPTIONS]
+
+  Options are:
+    -D DIR       target directory (default ".")
+    -p NAMES     platform families (default: """ + quote(platforms.mkString(",")) + """)
+    -v           verbose
+
+  Build VSCodium from sources and turn it into an Isabelle component.
+
+  The build platform needs to be Linux with nodejs/yarn, jq, and wine
+  for targeting Windows.
+""",
+        "D:" -> (arg => target_dir = Path.explode(arg)),
+        "p:" -> (arg => platforms = Library.space_explode(',', arg).map(Platform.Family.parse)),
+        "v" -> (_ => verbose = true))
+
+      val more_args = getopts(args)
+      if (more_args.nonEmpty) getopts.usage()
+
+      val progress = new Console_Progress()
+
+      build_vscodium(target_dir = target_dir, platforms = platforms,
+        verbose = verbose, progress = progress)
+    })
+
+  val isabelle_tool2 =
+    Isabelle_Tool("vscode_patch", "patch VSCode source tree",
+      Scala_Project.here, args =>
+    {
+      var base_dir = Path.current
+
+      val getopts = Getopts("""
+Usage: vscode_patch [OPTIONS]
+
+  Options are:
+    -D DIR       base directory (default ".")
+
+  Patch original VSCode source tree for use with Isabelle/VSCode.
+""",
+        "D:" -> (arg => base_dir = Path.explode(arg)))
+
+      val more_args = getopts(args)
+      if (more_args.nonEmpty) getopts.usage()
+
+      val platform_info = the_platform_info(Platform.family)
+      platform_info.patch_sources(base_dir)
+    })
+}
--- a/src/Tools/VSCode/src/vscode_setup.scala	Wed Mar 09 16:21:58 2022 +0000
+++ b/src/Tools/VSCode/src/vscode_setup.scala	Thu Mar 10 12:34:02 2022 +0100
@@ -1,7 +1,7 @@
 /*  Title:      Tools/VSCode/src/vscode_setup.scala
     Author:     Makarius
 
-Setup VSCode from VSCodium distribution.
+Provide user configuration for Isabelle/VSCode.
 */
 
 package isabelle.vscode
@@ -9,90 +9,13 @@
 
 import isabelle._
 
-import java.security.MessageDigest
-import java.util.Base64
-
 
 object VSCode_Setup
 {
-  /* global resources */
-
-  def vscode_home: Path = Path.variable("ISABELLE_VSCODE_HOME")
-  def vscode_settings: Path = Path.variable("ISABELLE_VSCODE_SETTINGS")
-  def vscode_settings_user: Path = vscode_settings + Path.explode("user-data/User/settings.json")
-  def vscode_workspace: Path = Path.variable("ISABELLE_VSCODE_WORKSPACE")
-  def version: String = Build_VSCodium.version
-
-  def vscodium_home: Path = Path.variable("ISABELLE_VSCODIUM_HOME")
-  def vscodium_home_ok(): Boolean =
-    try { vscodium_home.is_dir }
-    catch { case ERROR(_) => false }
-
-  def vscode_installation(info: Build_VSCodium.Platform_Info): (Boolean, Path) =
-  {
-    val install_dir =
-      info.platform_dir(vscode_settings + Path.basic("installation") + Path.basic(version))
-    val install_ok = Build_VSCodium.vscodium_exe(install_dir).is_file
-    (install_ok, install_dir)
-  }
-
-
-  /* patch resources */
-
-  // see https://github.com/microsoft/vscode/blob/main/build/gulpfile.vscode.js
-  // function computeChecksum(filename)
-
-  def file_checksum(path: Path): String =
-  {
-    val digest = MessageDigest.getInstance("MD5")
-    digest.update(Bytes.read(path).array)
-    Bytes(Base64.getEncoder.encode(digest.digest()))
-      .text.replaceAll("=", "")
-  }
-
-  def patch_resources(dir: Path): Unit =
-  {
-    HTML.init_fonts(dir + Path.explode("app/out/vs/base/browser/ui"))
-
-    val workbench_css = dir + Path.explode("app/out/vs/workbench/workbench.desktop.main.css")
-    val checksum1 = file_checksum(workbench_css)
-    File.append(workbench_css, "\n\n" + HTML.fonts_css_dir(prefix = "../base/browser/ui"))
-    val checksum2 = file_checksum(workbench_css)
-
-    val file_name = workbench_css.file_name
-    File.change_lines(dir + Path.explode("app/product.json")) { _.map(line =>
-      if (line.containsSlice(file_name) && line.contains(checksum1)) {
-        line.replace(checksum1, checksum2)
-      }
-      else line)
-    }
-  }
-
-
-  /* workspace */
-
-  def init_workspace(dir: Path): Unit =
-  {
-    Isabelle_System.make_directory(dir)
-    Isabelle_System.chmod("700", dir)
-
-    File.change(dir + Path.explode("symbols.json"), init = true) { _ =>
-      JSON.Format(
-        for (entry <- Symbol.symbols.entries; code <- entry.code)
-          yield JSON.Object(
-            "symbol" -> entry.symbol,
-            "name" -> entry.name,
-            "code" -> code,
-            "abbrevs" -> entry.abbrevs
-          )
-      )
-    }
-  }
-
-
   /* vscode setup */
 
-  def default_platform: Platform.Family.Value = Platform.family
+  def vscode_settings_user: Path =
+    Path.explode("$ISABELLE_VSCODE_SETTINGS/user-data/User/settings.json")
 
   private val init_settings = """  {
     "editor.fontFamily": "'Isabelle DejaVu Sans Mono'",
@@ -108,89 +31,36 @@
   }
 """
 
-  def vscode_setup(
-    check: Boolean = false,
-    platform: Platform.Family.Value = default_platform,
-    quiet: Boolean = false,
-    fresh: Boolean = false,
-    progress: Progress = new Progress): Unit =
+  def vscode_setup(): Unit =
   {
-    val platform_info = Build_VSCodium.the_platform_info(platform)
-    val (install_ok, install_dir) = vscode_installation(platform_info)
+    if (Isabelle_System.getenv("ISABELLE_VSCODIUM_HOME").isEmpty) {
+      error("""Missing $ISABELLE_VSCODIUM_HOME: proper vscodium-X.YY.Z component required""")
+    }
 
     if (!vscode_settings_user.is_file) {
       Isabelle_System.make_directory(vscode_settings_user.dir)
       File.write(vscode_settings_user, init_settings)
     }
-
-    if (check) {
-      if (vscodium_home_ok()) {
-        init_workspace(vscode_workspace)
-        progress.echo(vscodium_home.expand.implode)
-      }
-      else if (install_ok) {
-        init_workspace(vscode_workspace)
-        progress.echo(install_dir.expand.implode)
-      }
-      else {
-        error("Bad Isabelle/VSCode installation: " + install_dir.expand +
-          "\n(use \"isabelle vscode_setup\" for download and installation)")
-      }
-    }
-    else {
-      if (install_ok) {
-        progress.echo_warning("Isabelle/VSCode installation already present: " + install_dir.expand)
-      }
-      if (!install_ok || fresh) {
-        Isabelle_System.make_directory(install_dir)
-        platform_info.download(install_dir, progress = if (quiet) new Progress else progress)
-        platform_info.patch_resources(install_dir)
-        platform_info.setup_executables(install_dir)
-      }
-    }
   }
 
 
   /* Isabelle tool wrapper */
 
   val isabelle_tool =
-    Isabelle_Tool("vscode_setup", "setup VSCode from VSCodium distribution",
+    Isabelle_Tool("vscode_setup", "provide user configuration for Isabelle/VSCode",
       Scala_Project.here, args =>
     {
-      var check = false
-      var fresh = false
-      var platforms = List(default_platform)
-      var quiet = false
-
       val getopts = Getopts("""
-Usage: vscode_setup [OPTIONS]
+Usage: vscode_setup
 
-  Options are:
-    -C           check and print installation directory
-    -f           force fresh installation
-    -p NAMES     platform families: comma-separated names
-                 (""" + commas_quote(Platform.Family.list.map(_.toString)) + """, default: """ +
-        quote(default_platform.toString) + """)
-    -q           quiet mode
-
-  Maintain local installation of VSCode, see also https://vscodium.com
-
-  Option -C checks the existing installation (without download), and
-  prints its directory location.
+  Provide user configuration for Isabelle/VSCode.
 
   The following initial settings are provided for a fresh installation:
-""" + init_settings,
-        "C" -> (_ => check = true),
-        "f" -> (_ => fresh = true),
-        "p:" -> (arg => platforms = Library.space_explode(',', arg).map(Platform.Family.parse)),
-        "q" -> (_ => quiet = true))
+""" + init_settings)
 
       val more_args = getopts(args)
       if (more_args.nonEmpty) getopts.usage()
 
-      val progress = new Console_Progress()
-      for (platform <- platforms) {
-        vscode_setup(check = check, platform = platform, quiet = quiet, fresh = fresh, progress = progress)
-      }
+      vscode_setup()
     })
 }