From 3c01dede8b98cc78c2351210b2c62bf894991672 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Mon, 28 Feb 2022 18:07:14 -0800 Subject: [PATCH] remove DottyIDE --- .github/workflows/ci.yaml | 4 +- .gitignore | 20 - build.sbt | 1 - .../languageserver/DottyLanguageServer.scala | 3 +- .../src/dotty/tools/languageserver/Main.scala | 32 - project/Build.scala | 90 +- project/DottyIDEPlugin.scala | 501 ---- project/Process.scala | 48 + vscode-dotty/.vscodeignore | 11 - vscode-dotty/README.md | 23 - vscode-dotty/images/dotty-logo.png | Bin 35676 -> 0 bytes vscode-dotty/package-lock.json | 2448 ----------------- vscode-dotty/package.json | 138 - vscode-dotty/src/compat.ts | 46 - vscode-dotty/src/extension.ts | 371 --- vscode-dotty/src/features.ts | 105 - vscode-dotty/src/passthrough-server.ts | 49 - vscode-dotty/src/protocol.ts | 68 - vscode-dotty/src/sbt-server.ts | 129 - vscode-dotty/src/tasty-decompiler.ts | 211 -- vscode-dotty/src/tracer.ts | 391 --- vscode-dotty/src/tracing-consent.ts | 34 - vscode-dotty/src/worksheet.ts | 385 --- vscode-dotty/test/extension.test.ts | 21 - vscode-dotty/test/index.ts | 22 - vscode-dotty/tsconfig.json | 17 - 26 files changed, 53 insertions(+), 5115 deletions(-) delete mode 100644 project/DottyIDEPlugin.scala create mode 100644 project/Process.scala delete mode 100644 vscode-dotty/.vscodeignore delete mode 100644 vscode-dotty/README.md delete mode 100644 vscode-dotty/images/dotty-logo.png delete mode 100644 vscode-dotty/package-lock.json delete mode 100644 vscode-dotty/package.json delete mode 100644 vscode-dotty/src/compat.ts delete mode 100644 vscode-dotty/src/extension.ts delete mode 100644 vscode-dotty/src/features.ts delete mode 100644 vscode-dotty/src/passthrough-server.ts delete mode 100644 vscode-dotty/src/protocol.ts delete mode 100644 vscode-dotty/src/sbt-server.ts delete mode 100644 vscode-dotty/src/tasty-decompiler.ts delete mode 100644 vscode-dotty/src/tracer.ts delete mode 100644 vscode-dotty/src/tracing-consent.ts delete mode 100644 vscode-dotty/src/worksheet.ts delete mode 100644 vscode-dotty/test/extension.test.ts delete mode 100644 vscode-dotty/test/index.ts delete mode 100644 vscode-dotty/tsconfig.json diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d9da3baee124..97c73c29e94a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -111,7 +111,7 @@ jobs: - name: Cmd Tests run: | - ./project/scripts/sbt ";dist/pack; scala3-bootstrapped/compile; scala3-bootstrapped/test;sjsSandbox/run;sjsSandbox/test;sjsJUnitTests/test;sjsCompilerTests/test ;sbt-test/scripted scala2-compat/* ;configureIDE ;stdlib-bootstrapped/test:run ;stdlib-bootstrapped-tasty-tests/test; scala3-compiler-bootstrapped/scala3CompilerCoursierTest:test" + ./project/scripts/sbt ";dist/pack; scala3-bootstrapped/compile; scala3-bootstrapped/test;sjsSandbox/run;sjsSandbox/test;sjsJUnitTests/test;sjsCompilerTests/test ;sbt-test/scripted scala2-compat/* ;stdlib-bootstrapped/test:run ;stdlib-bootstrapped-tasty-tests/test; scala3-compiler-bootstrapped/scala3CompilerCoursierTest:test" ./project/scripts/cmdTests ./project/scripts/bootstrappedOnlyCmdTests @@ -447,7 +447,7 @@ jobs: - name: Test run: | - ./project/scripts/sbt ";dist/pack ;scala3-bootstrapped/compile ;scala3-bootstrapped/test;sjsSandbox/run;sjsSandbox/test;sjsJUnitTests/test;sjsCompilerTests/test ;sbt-test/scripted scala2-compat/* ;configureIDE ;stdlib-bootstrapped/test:run ;stdlib-bootstrapped-tasty-tests/test" + ./project/scripts/sbt ";dist/pack ;scala3-bootstrapped/compile ;scala3-bootstrapped/test;sjsSandbox/run;sjsSandbox/test;sjsJUnitTests/test;sjsCompilerTests/test ;sbt-test/scripted scala2-compat/* ;stdlib-bootstrapped/test:run ;stdlib-bootstrapped-tasty-tests/test" ./project/scripts/cmdTests ./project/scripts/bootstrappedOnlyCmdTests diff --git a/.gitignore b/.gitignore index e182b7114a07..4df303452a3f 100644 --- a/.gitignore +++ b/.gitignore @@ -30,22 +30,6 @@ node_modules .metals/ metals.sbt -# Scala-IDE specific -.scala_dependencies -.cache -.cache-main -.cache-tests -.classpath -.project -.settings -classes/ -*/bin/ - -# Dotty IDE -/.dotty-ide-dev-port -/.dotty-ide-artifact -/.dotty-ide.json - # idea .idea .idea_modules @@ -79,10 +63,6 @@ compiler/test/debug/Gen.jar compiler/before-pickling.txt compiler/after-pickling.txt bench/compile.txt -*.dotty-ide-version - -# The vscode app for testing -vscode-dotty/.vscode-test community-build/scala3-bootstrapped.version community-build/sbt-dotty-sbt diff --git a/build.sbt b/build.sbt index 3ec2958324be..bae6deafd8cc 100644 --- a/build.sbt +++ b/build.sbt @@ -33,7 +33,6 @@ val sjsJUnitTests = Build.sjsJUnitTests val sjsCompilerTests = Build.sjsCompilerTests val `sbt-test` = Build.`sbt-test` -val `vscode-dotty` = Build.`vscode-dotty` inThisBuild(Build.thisBuildSettings) inScope(Global)(Build.globalSettings) diff --git a/language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala b/language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala index 3f7c58b022d6..3ba0dfd047d5 100644 --- a/language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala +++ b/language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala @@ -54,7 +54,6 @@ class DottyLanguageServer extends LanguageServer import lsp4j.jsonrpc.messages.{Either => JEither} import lsp4j._ - private[this] var rootUri: String = _ private[this] var myClient: DottyClient = _ @@ -646,7 +645,7 @@ class DottyLanguageServer extends LanguageServer } object DottyLanguageServer { - /** Configuration file normally generated by the DottyIDEPlugin */ + final val IDE_CONFIG_FILE = ".dotty-ide.json" final val RENAME_OVERRIDDEN_QUESTION = "Do you want to rename the base member, or only this member?" diff --git a/language-server/src/dotty/tools/languageserver/Main.scala b/language-server/src/dotty/tools/languageserver/Main.scala index 5d90efa4c23f..7f269eecde6d 100644 --- a/language-server/src/dotty/tools/languageserver/Main.scala +++ b/language-server/src/dotty/tools/languageserver/Main.scala @@ -13,16 +13,6 @@ import org.eclipse.lsp4j.launch._ import org.eclipse.lsp4j.jsonrpc.Launcher /** Run the Dotty Language Server. - * - * This is designed to be started from an editor supporting the Language Server - * Protocol, the easiest way to fetch and run this is to use `coursier`: - * - * coursier launch $artifact -M dotty.tools.languageserver.Main -- -stdio - * - * Where $artifact comes from the `.dotty-ide-artifact` file in the current project, this file - * can be created by the DottyIDEPlugin by running `sbt configureIDE`. - * - * See vscode-dotty/ for an example integration of the Dotty Language Server into Visual Studio Code. */ object Main { def main(args: Array[String]): Unit = { @@ -34,28 +24,6 @@ object Main { scala.Console.withOut(scala.Console.err) { startServer(serverIn, serverOut) } - case "-client_command" :: clientCommand => - val serverSocket = new ServerSocket(0) - Runtime.getRuntime().addShutdownHook(new Thread( - new Runnable { - def run: Unit = { - serverSocket.close() - } - })); - - println("Starting client: " + clientCommand) - val clientPB = new java.lang.ProcessBuilder(clientCommand: _*) - clientPB.environment.put("DLS_DEV_MODE", "1") - - val pw = new PrintWriter("../.dotty-ide-dev-port") - pw.write(serverSocket.getLocalPort.toString) - pw.close() - - clientPB.inheritIO().start() - - val clientSocket = serverSocket.accept() - - startServer(clientSocket.getInputStream, clientSocket.getOutputStream) case _ => Console.err.println("Invalid arguments: expected \"-stdio\" or \"-client_command ...\"") System.exit(1) diff --git a/project/Build.scala b/project/Build.scala index 65de7af82a48..7c6f5e5953a5 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1,6 +1,7 @@ import java.io.File import java.nio.file._ +import Process._ import Modes._ import ScaladocGeneration._ import com.jsuereth.sbtpgp.PgpKeys @@ -16,8 +17,6 @@ import xerial.sbt.pack.PackPlugin import xerial.sbt.pack.PackPlugin.autoImport._ import xerial.sbt.Sonatype.autoImport._ import com.typesafe.tools.mima.plugin.MimaPlugin.autoImport._ -import dotty.tools.sbtplugin.DottyIDEPlugin.{installCodeExtension, prepareCommand, runProcess} -import dotty.tools.sbtplugin.DottyIDEPlugin.autoImport._ import org.scalajs.sbtplugin.ScalaJSPlugin import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._ import sbtbuildinfo.BuildInfoPlugin @@ -52,10 +51,6 @@ object DottyJSPlugin extends AutoPlugin { // Typecheck the Scala.js IR found on the classpath scalaJSLinkerConfig ~= (_.withCheckIR(true)), - - // Exclude all these projects from `configureIDE/launchIDE` since they - // take time to compile, print a bunch of warnings, and are rarely edited. - excludeFromIDE := true ) } @@ -154,9 +149,6 @@ object Build { // Compiles the documentation and static site val genDocs = inputKey[Unit]("run scaladoc to generate static documentation site") - // Only available in vscode-dotty - val unpublish = taskKey[Unit]("Unpublish a package") - // Settings used to configure the test language server val ideTestsCompilerVersion = taskKey[String]("Compiler version to use in IDE tests") val ideTestsCompilerArguments = taskKey[Seq[String]]("Compiler arguments to use in IDE tests") @@ -183,11 +175,6 @@ object Build { (Compile / compile / javacOptions) ++= Seq("-Xlint:unchecked", "-Xlint:deprecation"), - // Override `runCode` from DottyIDEPlugin to use the language-server and - // vscode extension from the source repository of dotty instead of a - // published version. - runCode := (`scala3-language-server` / run).toTask("").value, - // Avoid various sbt craziness involving classloaders and parallelism run / fork := true, Test / fork := true, @@ -285,7 +272,6 @@ object Build { crossPaths := false, // Do not depend on the Scala library autoScalaLibrary := false, - excludeFromIDE := true, disableDocSetting ) @@ -315,7 +301,6 @@ object Build { version := dottyNonBootstrappedVersion, scalaVersion := referenceVersion, - excludeFromIDE := true, disableDocSetting ) @@ -1033,23 +1018,6 @@ object Build { // Work around https://github.com/eclipse/lsp4j/issues/295 dependencyOverrides += "org.eclipse.xtend" % "org.eclipse.xtend.lib" % "2.16.0", javaOptions := (`scala3-compiler-bootstrapped` / javaOptions).value, - - run := Def.inputTaskDyn { - val inputArgs = spaceDelimited("").parsed - - val mainClass = "dotty.tools.languageserver.Main" - val extensionPath = (`vscode-dotty` / baseDirectory).value.getAbsolutePath - - val codeArgs = - s"--extensionDevelopmentPath=$extensionPath" +: - (if (inputArgs.isEmpty) List((baseDirectory.value / "..").getAbsolutePath) else inputArgs) - - val clientCommand = prepareCommand(codeCommand.value ++ codeArgs) - - val allArgs = "-client_command" +: clientCommand - - runTask(Runtime, mainClass, allArgs: _*) - }.dependsOn((`vscode-dotty` / Compile / compile)).evaluated ). settings( ideTestsCompilerVersion := (`scala3-compiler` / version).value, @@ -1456,60 +1424,6 @@ object Build { ).evaluated ) - lazy val `vscode-dotty` = project.in(file("vscode-dotty")). - settings(commonSettings). - settings( - version := "0.1.17-snapshot", // Keep in sync with package.json - autoScalaLibrary := false, - publishArtifact := false, - bspEnabled := false, - (Compile / resourceGenerators) += Def.task { - // Resources that will be copied when bootstrapping a new project - val buildSbtFile = baseDirectory.value / "out" / "build.sbt" - IO.write(buildSbtFile, - s"""scalaVersion := "$publishedDottyVersion"""") - val dottyPluginSbtFile = baseDirectory.value / "out" / "scala3-plugin.sbt" - IO.write(dottyPluginSbtFile, - s"""addSbtPlugin("$dottyOrganization" % "sbt-dotty" % "$sbtDottyVersion")""") - Seq(buildSbtFile, dottyPluginSbtFile) - }, - Compile / compile := Def.task { - val workingDir = baseDirectory.value - val coursier = workingDir / "out" / "coursier" - val packageJson = workingDir / "package.json" - if (!coursier.exists || packageJson.lastModified > coursier.lastModified) - runProcess(Seq("npm", "install"), wait = true, directory = Some(workingDir)) - val tsc = workingDir / "node_modules" / ".bin" / "tsc" - runProcess(Seq(tsc.getAbsolutePath, "--pretty", "--project", workingDir.getAbsolutePath), wait = true) - - // vscode-dotty depends on scala-lang.scala for syntax highlighting, - // this is not automatically installed when starting the extension in development mode - // (--extensionDevelopmentPath=...) - installCodeExtension(codeCommand.value, "scala-lang.scala") - - sbt.internal.inc.Analysis.Empty - }.dependsOn((Compile / managedResources)).value, - sbt.Keys.`package`:= { - runProcess(Seq("vsce", "package"), wait = true, directory = Some(baseDirectory.value)) - - baseDirectory.value / s"dotty-${version.value}.vsix" - }, - unpublish := { - runProcess(Seq("vsce", "unpublish"), wait = true, directory = Some(baseDirectory.value)) - }, - publish := { - runProcess(Seq("vsce", "publish"), wait = true, directory = Some(baseDirectory.value)) - }, - run := Def.inputTask { - val inputArgs = spaceDelimited("").parsed - val codeArgs = if (inputArgs.isEmpty) List((baseDirectory.value / "..").getAbsolutePath) else inputArgs - val extensionPath = baseDirectory.value.getAbsolutePath - val processArgs = List(s"--extensionDevelopmentPath=$extensionPath") ++ codeArgs - - runProcess(codeCommand.value ++ processArgs, wait = true) - }.dependsOn((Compile / compile)).evaluated - ) - lazy val `sbt-community-build` = project.in(file("sbt-community-build")). enablePlugins(SbtPlugin). settings(commonSettings). @@ -1902,4 +1816,4 @@ object ScaladocConfigs { .add(ApiSubdirectory(true)) .withTargets(roots) } -} \ No newline at end of file +} diff --git a/project/DottyIDEPlugin.scala b/project/DottyIDEPlugin.scala deleted file mode 100644 index f455692a2672..000000000000 --- a/project/DottyIDEPlugin.scala +++ /dev/null @@ -1,501 +0,0 @@ -package dotty.tools.sbtplugin - -import sbt._ -import sbt.Def.Initialize -import sbt.Keys._ -import java.io._ -import java.lang.ProcessBuilder -import java.lang.ProcessBuilder.Redirect -import scala.collection.mutable -import scala.util.Properties.{ isWin, isMac } - -import dotty.tools.languageserver.config.ProjectConfig - -import com.fasterxml.jackson.databind.ObjectMapper -import scala.collection.mutable.ListBuffer - -object DottyIDEPlugin extends AutoPlugin { - object autoImport { - val excludeFromIDE = settingKey[Boolean]("If true, do not import this project or configuration in the Dotty IDE") - - val codeCommand = taskKey[Seq[String]]("Command to start VSCode") - val runCode = taskKey[Unit]("Start VSCode, usually called from launchIDE") - val launchIDE = taskKey[Unit]("Configure and run VSCode on this project") - } - - import autoImport._ - - // Adapted from scala-reflect - private def distinctBy[A, B](xs: Seq[A])(f: A => B): Seq[A] = { - val buf = new mutable.ListBuffer[A] - val seen = mutable.Set[B]() - xs foreach { x => - val y = f(x) - if (!seen(y)) { - buf += x - seen += y - } - } - buf.toList - } - - private def isDottyVersion(version: String) = - version.startsWith("0.") || version.startsWith("3.") - - - /** Return a new state derived from `state` such that scalaVersion returns `newScalaVersion` in all - * projects in `projRefs` (`state` is returned if no setting needed to be updated). - */ - private def updateScalaVersion(state: State, projRefs: Seq[ProjectRef], newScalaVersion: String): State = { - val extracted = Project.extract(state) - val settings = extracted.structure.data - - if (projRefs.forall(projRef => (projRef / scalaVersion).get(settings).get == newScalaVersion)) - state - else { - def matchingSetting(setting: Setting[_]) = - setting.key.key == scalaVersion.key && - setting.key.scope.project.fold(ref => projRefs.contains(ref), ifZero = true, ifThis = true) - - val newSettings = extracted.session.mergeSettings.collect { - case setting if matchingSetting(setting) => - setting.key.scope / scalaVersion := newScalaVersion - } - val newSession = extracted.session.appendRaw(newSettings) - BuiltinCommands.reapply(newSession, extracted.structure, state) - } - } - - /** Setup to run in all dotty projects. - * Return a triplet of: - * (1) A version of dotty - * (2) A list of dotty projects - * (3) A state where `scalaVersion` is set to (1) in all projects in (2) - */ - private def dottySetup(state: State): (String, Seq[ProjectRef], State) = { - val structure = Project.structure(state) - val settings = structure.data - - // FIXME: this function uses `sorted` to order versions but this is incorrect, - // we need an Ordering for version numbers, like the one in Coursier. - - val (dottyVersions, dottyProjRefs) = - structure.allProjectRefs.flatMap { projRef => - if ((projRef / excludeFromIDE).get(settings) == Some(true)) - None - else { - val version = (projRef / scalaVersion).get(settings).get - if (isDottyVersion(version)) - Some((version, projRef)) - else - (projRef / crossScalaVersions).get(settings).get.filter(isDottyVersion).sorted.lastOption match { - case Some(v) => - Some((v, projRef)) - case _ => - None - } - } - }.unzip - - if (dottyVersions.isEmpty) - throw new MessageOnlyException("No Dotty project detected") - else { - val dottyVersion = dottyVersions.sorted.last - val dottyState = updateScalaVersion(state, dottyProjRefs, dottyVersion) - (dottyVersion, dottyProjRefs, dottyState) - } - } - - /** Run `task` in state `state` */ - private def runTask[T](task: Task[T], state: State): T = { - val extracted = Project.extract(state) - val structure = extracted.structure - val (_, result) = - EvaluateTask.withStreams(structure, state) { streams => - EvaluateTask.runTask(task, state, streams, structure.index.triggers, - EvaluateTask.extractedTaskConfig(extracted, structure, state))( - EvaluateTask.nodeView(state, streams, Nil) - ) - } - result match { - case Value(v) => - v - case Inc(i) => - throw i - } - } - - /** Run task `key` in all configurations in all projects in `projRefs`, using state `state`, - * configurations where `excludeFromIDE` is `true` are skipped. */ - private def runInAllIDEConfigurations[T](key: TaskKey[T], projRefs: Seq[ProjectRef], state: State): Seq[T] = { - val structure = Project.structure(state) - val settings = structure.data - val joinedTask = projRefs.flatMap { projRef => - val project = Project.getProjectForReference(projRef, structure).get - project.configurations.flatMap { config => - (projRef / config / excludeFromIDE).get(settings) match { - case Some(true) => - None // skip this configuration - case _ => - (projRef / config / key).get(settings) - } - } - }.join - - runTask(joinedTask, state) - } - - /** Prepare command to be passed to ProcessBuilder */ - def prepareCommand(cmd: Seq[String]): Seq[String] = - if (isWin) Seq("cmd.exe", "/C") ++ cmd - else cmd - - /** Run the command `cmd`. - * - * @param wait If true, wait for the command to return and throw an exception if the exit code is non-zero. - * @param directory If not None, run the command in this directory. - * @param outputCallback If not None, pass the command output to this callback instead of writing it to stdout. - */ - def runProcess(cmd: Seq[String], wait: Boolean = false, directory: Option[File] = None, outputCallback: Option[BufferedReader => Unit] = None): Unit = { - val pb = new ProcessBuilder(prepareCommand(cmd): _*) - - directory match { - case Some(dir) => - pb.directory(dir) - case None => - } - - pb.redirectInput(Redirect.INHERIT) - .redirectError(Redirect.INHERIT) - .redirectOutput( - outputCallback match { - case Some(_) => - Redirect.PIPE - case None => - Redirect.INHERIT - }) - - val process = pb.start() - outputCallback match { - case Some(callback) => - callback(new BufferedReader(new InputStreamReader(process.getInputStream))) - case None => - } - if (wait) { - val exitCode = process.waitFor() - if (exitCode != 0) { - val cmdString = cmd.mkString(" ") - val description = if (directory != null) s""" in directory "$directory"""" else "" - throw new MessageOnlyException(s"""Running command "${cmdString}"${description} failed.""") - } - } - } - - /** Install or upgrade Code extension `name`. - * - * We start by trying to install or upgrade the extension. If this fails we - * check if an existing version of the extension exists. If this also fails - * we throw an exception. This ensures that we're always running the latest - * version of the extension but that we can still work offline. - */ - def installCodeExtension(codeCmd: Seq[String], name: String): Unit = { - try { - runProcess(codeCmd ++ Seq("--force", "--install-extension", name), wait = true) - } catch { - case e: Exception => - var alreadyInstalled: Boolean = false - runProcess(codeCmd ++ Seq("--list-extensions"), wait = true, outputCallback = Some({ br => - alreadyInstalled = br.lines.filter(_ == name).findFirst.isPresent - })) - if (!alreadyInstalled) - throw e - } - } - - private val projectConfig = taskKey[Option[ProjectConfig]]("") - - override def requires: Plugins = plugins.JvmPlugin - override def trigger = allRequirements - - private val artifactFile = new File(".dotty-ide-artifact") - private val configFile = new File(".dotty-ide.json") - - def configureIDE = Command.command("configureIDE") { origState => - val (dottyVersion, projRefs, dottyState) = dottySetup(origState) - val configs0 = runInAllIDEConfigurations(projectConfig, projRefs, dottyState).flatten - - // Drop configurations that do not define their own sources, but just - // inherit their sources from some other configuration. - val configs = distinctBy(configs0)(_.sourceDirectories.deep) - - // Write the version of the Dotty Language Server to use in a file by itself. - // This could be a field in the JSON config file, but that would require all - // IDE plugins to parse JSON. - val dlsVersion = dottyVersion - .replace("-nonbootstrapped", "") // The language server is only published bootstrapped - val dlsBinaryVersion = dlsVersion.split("[\\.-]").toList match { - case "0" :: minor :: _ => s"0.$minor" - case "3" :: minor :: patch :: suffix => - s"3.$minor.$patch" + (suffix match { - case milestone :: _ => s"-$milestone" - case Nil => "" - }) - case _ => throw new RuntimeException( - s"Version $dlsVersion is not a Scala 3 version.") - } - val pwArtifact = new PrintWriter(artifactFile) - try { - if (dottyVersion.startsWith("0.")) - pwArtifact.println(s"ch.epfl.lamp:dotty-language-server_${dlsBinaryVersion}:${dlsVersion}") - else - pwArtifact.println(s"org.scala-lang:scala3-language-server_${dlsBinaryVersion}:${dlsVersion}") - } finally { - pwArtifact.close() - } - - val mapper = new ObjectMapper - mapper.writerWithDefaultPrettyPrinter() - .writeValue(configFile, configs.toArray) - - origState - } - - def compileForIDE = Command.command("compileForIDE") { origState => - val (dottyVersion, projRefs, dottyState) = dottySetup(origState) - runInAllIDEConfigurations(compile, projRefs, dottyState) - - origState - } - - def launchIDE = Command.command("launchIDE") { state0 => - val state1 = try { - Command.process("configureIDE", state0) - } catch { - case i: Incomplete => - if (artifactFile.exists && configFile.exists) { - state0.log.error("IDE configuration failed, launching the IDE using the previous configuration") - state0: State - } else { - state0.log.error("IDE configuration failed and no previous configuration found") - state0.log.error("Please fix the compilation errors then run 'launchIDE' again") - throw i - } - } - Command.process("runCode", state1) - } - - private def makeId(name: String, config: String): String = s"$name/$config" - - private def projectConfigTask(config: Configuration): Initialize[Task[Option[ProjectConfig]]] = Def.taskDyn { - val depClasspath = Attributed.data((config / dependencyClasspath).value) - val projectName = name.value - - // Try to detect if this is a real Scala project or not. This is pretty - // fragile because sbt simply does not keep track of this information. We - // could check if at least one source file ends with ".scala" but that - // doesn't work for empty projects. - val isScalaProject = ( - // Our `dotty-library` project is a Scala project - ( - projectName.startsWith("dotty-library") || - projectName.startsWith("scala3-library") || - depClasspath.exists { d => - val absolutePath = d.getAbsolutePath - absolutePath.contains("dotty-library") || - absolutePath.contains("scala3-library") - } - ) - && depClasspath.exists(_.getAbsolutePath.contains("scala-library")) - ) - - if (!isScalaProject) Def.task { None } - else Def.task { - // Not needed to generate the config, but this guarantees that the - // generated config is usable by an IDE without any extra compilation - // step. - val _ = (config / compile).value - - val project = thisProject.value - val id = makeId(project.id, config.name) - val compilerVersion = (config / scalaVersion).value - val compilerArguments = (config / scalacOptions).value - val sourceDirectories = (config / unmanagedSourceDirectories).value ++ (config / managedSourceDirectories).value - val classDir = (config / classDirectory).value - val extracted = Project.extract(state.value) - val settings = extracted.structure.data - - val dependencies = { - val logger = streams.value.log - // Project dependencies come from classpath deps and also inter-project config deps - // We filter out dependencies that do not compile using Dotty - val classpathProjectDependencies = - project.dependencies.filter { d => - val version = (d.project / scalaVersion).get(settings).get - isDottyVersion(version) - }.map(d => projectDependencyName(d, config, project, logger)) - val configDependencies = - eligibleDepsFromConfig(config).value.map(c => makeId(project.id, c.name)) - - // The distinct here is important to make sure that there are no repeated project deps - (classpathProjectDependencies ++ configDependencies).distinct.toList - } - - // For projects without sources, we need to create it. Otherwise `InteractiveDriver` - // complains that the target directory doesn't exist. - if (!classDir.exists) IO.createDirectory(classDir) - - Some(new ProjectConfig( - id, - compilerVersion, - compilerArguments.toArray, - sourceDirectories.toArray, - depClasspath.toArray, - classDir, - dependencies.toArray - )) - } - } - - override def projectSettings: Seq[Setting[_]] = Seq( - // TODO: It would be better to use Def.derive to define projectConfig in - // every configuration where the keys it depends on exist, however this - // currently breaks aggregated tasks: https://github.com/sbt/sbt/issues/3580 - Compile / projectConfig := projectConfigTask(Compile).value, - Test / projectConfig := projectConfigTask(Test).value - ) - - override def buildSettings: Seq[Setting[_]] = Seq( - commands ++= Seq(configureIDE, compileForIDE, launchIDE), - - excludeFromIDE := false, - - codeCommand := { - Seq("code", "-n") - }, - - runCode := { - try { - installCodeExtension(codeCommand.value, "lampepfl.dotty") - - runProcess(codeCommand.value ++ Seq("."), directory = Some(baseDirectory.value)) - } catch { - case ioex: IOException if ioex.getMessage.startsWith("""Cannot run program "code"""") => - val log = streams.value.log - log.error( - """Could not find Visual Studio Code on your system. - |Follow the instructions at https://dotty.epfl.ch/docs/usage/ide-support.html - |to install it.""".stripMargin) - throw new FeedbackProvidedException { - override def toString = "Could not find Visual Studio Code on your system." - } - } - } - - ) ++ addCommandAlias("launchIDE", ";configureIDE;runCode") - - override def globalSettings: Seq[Setting[_]] = Seq( - excludeLintKeys += excludeFromIDE - ) - - // Ported from Bloop - /** - * Detect the eligible configuration dependencies from a given configuration. - * - * A configuration is eligible if the project defines it and `compile` - * exists for it. Otherwise, the configuration dependency is ignored. - * - * This is required to prevent transitive configurations like `Runtime` from - * generating useless IDE configuration files and possibly incorrect project - * dependencies. For example, if we didn't do this then the dependencies of - * `IntegrationTest` would be `projectName/runtime` and `projectName/compile`, - * whereas the following logic will return only the configuration `Compile` - * so that the use site of this function can create the project dep - * `projectName/compile`. - */ - private def eligibleDepsFromConfig(config: Configuration): Def.Initialize[Task[List[Configuration]]] = { - Def.task { - def depsFromConfig(configuration: Configuration): List[Configuration] = { - configuration.extendsConfigs.toList match { - case config :: Nil if config.extendsConfigs.isEmpty => config :: Nil - case config :: Nil => config :: depsFromConfig(config) - case Nil => Nil - } - } - - val configs = depsFromConfig(config) - val activeProjectConfigs = thisProject.value.configurations.toSet - - val data = settingsData.value - val thisProjectRef = Keys.thisProjectRef.value - - val eligibleConfigs = activeProjectConfigs.filter { c => - val configKey = ConfigKey.configurationToKey(c) - // Consider only configurations where the `compile` key is defined - val eligibleKey = (thisProjectRef / configKey / compile) - eligibleKey.get(data) match { - case Some(t) => - // Sbt seems to return tasks for the extended configurations (looks like a big bug) - t.info.get(taskDefinitionKey) match { - // So we now make sure that the returned config key matches the original one - case Some(taskDef) => taskDef.scope.config.toOption.toList.contains(configKey) - case None => true - } - case None => false - } - } - - configs.filter(c => eligibleConfigs.contains(c)) - } - } - - /** - * Creates a project name from a classpath dependency and its configuration. - * - * This function uses internal sbt utils (`sbt.Classpaths`) to parse configuration - * dependencies like sbt does and extract them. This parsing only supports compile - * and test, any kind of other dependency will be assumed to be test and will be - * reported to the user. - * - * Ref https://www.scala-sbt.org/1.x/docs/Library-Management.html#Configurations. - */ - private def projectDependencyName( - dep: ClasspathDep[ProjectRef], - configuration: Configuration, - project: ResolvedProject, - logger: Logger - ): String = { - val ref = dep.project - dep.configuration match { - case Some(_) => - val mapping = sbt.Classpaths.mapped( - dep.configuration, - List("compile", "test"), - List("compile", "test"), - "compile", - "*->compile" - ) - - mapping(configuration.name) match { - case Nil => - makeId(ref.project, configuration.name) - case List(conf) if Compile.name == conf => - makeId(ref.project, Compile.name) - case List(conf) if Test.name == conf => - makeId(ref.project, Test.name) - case List(conf1, conf2) if Test.name == conf1 && Compile.name == conf2 => - makeId(ref.project, Test.name) - case List(conf1, conf2) if Compile.name == conf1 && Test.name == conf2 => - makeId(ref.project, Test.name) - case unknown => - val msg = - s"Unsupported dependency '${project.id}' -> '${ref.project}:${unknown.mkString(", ")}' is understood as '${ref.project}:test'." - logger.warn(msg) - makeId(ref.project, Test.name) - } - case None => - // If no configuration, default is `Compile` dependency (see scripted tests `cross-compile-test-configuration`) - makeId(ref.project, Compile.name) - } - } - -} diff --git a/project/Process.scala b/project/Process.scala new file mode 100644 index 000000000000..1974221acb9b --- /dev/null +++ b/project/Process.scala @@ -0,0 +1,48 @@ +import java.io.{File, BufferedReader, InputStreamReader} +import scala.util.Properties.isWin +import java.lang.ProcessBuilder.Redirect +import sbt.MessageOnlyException + +object Process { + + /** Prepare command to be passed to ProcessBuilder */ + def prepareCommand(cmd: Seq[String]): Seq[String] = + if (isWin) Seq("cmd.exe", "/C") ++ cmd + else cmd + + def runProcess(cmd: Seq[String], wait: Boolean = false, directory: Option[File] = None, outputCallback: Option[BufferedReader => Unit] = None): Unit = { + val pb = new ProcessBuilder(prepareCommand(cmd): _*) + + directory match { + case Some(dir) => + pb.directory(dir) + case None => + } + + pb.redirectInput(Redirect.INHERIT) + .redirectError(Redirect.INHERIT) + .redirectOutput( + outputCallback match { + case Some(_) => + Redirect.PIPE + case None => + Redirect.INHERIT + }) + + val process = pb.start() + outputCallback match { + case Some(callback) => + callback(new BufferedReader(new InputStreamReader(process.getInputStream))) + case None => + } + if (wait) { + val exitCode = process.waitFor() + if (exitCode != 0) { + val cmdString = cmd.mkString(" ") + val description = if (directory != null) s""" in directory "$directory"""" else "" + throw new MessageOnlyException(s"""Running command "${cmdString}"${description} failed.""") + } + } + } + +} diff --git a/vscode-dotty/.vscodeignore b/vscode-dotty/.vscodeignore deleted file mode 100644 index 90a501fbe5a4..000000000000 --- a/vscode-dotty/.vscodeignore +++ /dev/null @@ -1,11 +0,0 @@ -## This is used to exclude files from "vsce publish" -target/** -.vscode/** -.vscode-test/** -out/test/** -out/.keep -test/** -src/** -**/*.map -.gitignore -tsconfig.json diff --git a/vscode-dotty/README.md b/vscode-dotty/README.md deleted file mode 100644 index 44acc4087418..000000000000 --- a/vscode-dotty/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# IDE support for Dotty, the experimental Scala compiler - -## Prerequisites -To use this in your own Scala project, you must first get it to compile with -Dotty, please follow the instructions at https://github.com/lampepfl/dotty-example-project - -## Starting Visual Studio Code from sbt -First, make sure `code`, the binary for Visual Studio Code, is on your `$PATH`, -this is the case if you can start the IDE by running `code` in a terminal. This -is the default on all systems except Mac where you'll need to follow these -instructions: https://code.visualstudio.com/docs/setup/mac#_command-line - - -If this is the case and your project successfully compiles with dotty, you can -simply use the `launchIDE` command provided by the sbt-dotty plugin: - -```shell -sbt launchIDE -``` - -## More information - -See https://dotty.epfl.ch/docs/usage/ide-support.html diff --git a/vscode-dotty/images/dotty-logo.png b/vscode-dotty/images/dotty-logo.png deleted file mode 100644 index b2fe56c83517910fd7bb0c34db4be948d4efa6f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35676 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

yTk zBG*I?y=p?wfMXd_$YF?6?C0X}aZdX^7Dz80Df*rBAC=9`4>-*93}Pj&(KZf`dZ)g= zQK4a%2AD;hPik24?(1i@XF(=vGpynF$Cv1Hj}8J zh=%*ew_|6dSx?n(&6GhQ=dgWHnT;l6K~%zQU?ML)Ra1Dufi&s9Odmo~npn}U_`aL0 z;HpNFh76C~i^m-0wim8*WGr&m@*}BcGsNGr5x~lyPv?b_!BPXJq+l9R(zhOc1z2G;mV#+0|>-BB$dz zF&M&O;9h58`waN;cCiK;BQ#4>G-oRxaj4Jy=zmFPWfMgIx+Wr`qoHIcX~!Zrlj6Si z9a?0H@w}N>^mtXX`s1SEV(7 zb(+6zI*Ofyu~{N72~3-E^NyO7O-wFvat0JpBGfyK>C?7uYZaSbFkx_v)M+3&g?c1` zdl0qQVsX26?HFgN1pV&Ql6324A`6Vs3b|-c@Fj-F@KVqGx1JBuk!fsjCbSB!ww2_6 zVrEzHkm`CFCRt7BE3nz)3T@@YZiv4q$3HIZQYnIb^myL0aY^}VzC_e6!8MMa^Y>r2 zfqew2(y)j@H+p$P3ePL2!nKat5#90OCjF?ySHGzIrc|3PtLrauxa@JI?>{!Qzm2FpxcA%`6S<6+qt@8ALP|1&H9`*f;wB6o*Q5LR3 zh;>YW4fOPBOZDE-JY{G$HyWZ=7V95)l|gY^iEr^<%XE*Xa5vBAq*lyT``0>p1~6zZ zCqmp$zkNjQ<6V`m(-jE#KNJjWyy7ZTtD)9ybZeIc+ZFuC<7zx;4=`^0&o zZNp_h=%}^+<>}L!@bmntamLAh#;Da|11a3=J*mImzkt#^_lAGh)T?SY_eiPvf9xBs z>7IA=$Za2g#SP@S^Ki#np^}ZVE#_y1MlE%Jw6U-{`27i~6?vStsnT|iHUlqGIfJ#dr>7t70`1+81LXBFgmQ3b43t5M zj=xYaN)!av9535OlrJwWcZ8Z?tNxnC(Gnv{%ejwyqM|S?rECnBOb%$lWZTO*y&-zr zudh1~^J^AqCROEA{#j7MPk;9)UZTCS7})m3g2DVY_`y=BVxvzSb+1!+lXO;6e{g^r z!R%H*$#mb3t7}nVNXFI+2aW$6^RVdzqp|w5^(UKFLIHo(gfRkYcVvJ-V7&9v>Vx}J z;uhHd5V6#tQ=`7Z8>kY2&DHC8Io&|!V{p^ zXj(T)O8Ji86LZ=_2TP%QJa_@|PCVNynx^r?-`%#qFr^En&#v32FpGYJW{Ru9P-yE) zYic$5cL7G$ra%DMV&NMs0;2;rg=X)2eXV#2oj_CrDoU2Ps7${^_!Mr6zK94-1#(4d~; z*oCh2j^4f4&*L{fXVSvn?9w$e=8XD3cho`^h}WyOYq3U$0vw_&?MqganXBl$kJPZ+ zp9z2xeKQsNT?h~UO|hl6ETeL#ThlHl3breh|0EoIm!{s?w?F)9`pJ5DG~>-I@R&Ve z!$KdS>MkcjU*oB?87owP^#q{gvKa@H_w_ z8Rqdwv~t3I)x*~VJ)0R!fXa81XEG>wR>cE?D3N@P{7&1$@2p-j{|CTsZ$aa?;4>O7 zZCr1)=#EPSeiN8Mo*YY(V!K<9?`n@Qc(QC;@MzN zMn4XOFJ<>h^!RQSM!NYB8mQ^q^|H2?qMrs^`A~rzT#78Yl zj7X3X_S44^?4Wf1ZbaX^8tfr;bW&)P9KDoqYE$5BTERjOB1Te{&s16lb4)5kwoJxAWk)3I_mn2e2Ir zc6u#h)#EAZ%E+GK@|r$NoH2z}w z!Je;Gp};lB722xdMxWXnKb%$~5PXKEGVsA*(5e#a4p{S`N<`|zU-Gm2E_aDwbwkDz zZJDqRgz~E5lsg3fsJbD~yBh~Nv?j68NCGuulAN!9B67r@9ozcxg<<=5biS6~lwA=f zi<9&XLDXb&j1joZ7LD3!Le_A+T_EhFoybrGWu`I4xVv~i=4O$DLd~EWO>sbrSuz8OrRpT=*N5q;9f&o*WZgQj*eOV_*hYCUiG1i6ck)4_73MZ zg8Rn8NHb)EtZcZOGfKi&JRBGw_tatINKT#Y|E)!)^NDp4almOqt3Nk)n?-mZO#e-v zUn7aR(_g}pIg1yG+i&3jbG*i|v{fxcu2+~ zqWROM8h&m~emNt1o@i>up|YlD@qiVT4W;mq4?*cHSsghPez6)k(Wjf-!dl?^xqJ>|o%g z55TDPKw$r&|E-l}Qvh`?7d7xXR}X($&C?K@(Toau(1wO>B1BX0C| zKDW-rb|goza=d#=pFi z8fvCrAPHb^Y`$MEOqVesr0O&BuU?rN2C!F)8&spw<-550MZFP*ZcV)!RO~Df*AcQV z715n8ELQTfoEl2cSxA~GW!@!MUc(Pu=KC$-dIu_^gaGi&AwabUD@yZeYhRoQT4F~R^QH{Fd|?I8AgkOAHeLn}y#isiS+ zPNrI%#}gXdXp$uP=~heWdh7f9iT0@7U!r+O5!nz)X<<_Uw~-)Yfz+8EyUk1(jBd7b zS6Z&%!fWG6G74LD^(S<8sxk-es0S#H?jyi{h6^&~#E2vuL^=~fp|wf0NDbu1R?+cZ zK*|dnRlDAXkNeG}S7D=kk%0f{SK%kSkJq(x?l}$xQ!GZ`dJ4(I|0$cl{B=mxJ))C@ z34b}TOrwp%u#8~Sm4|N^6rXIO0we71IttS(*r>n$-o7GbmN;!c`vulub)=_tGBTu1G#!9ogS?d*}gD705C_fed`C z_Y`Bt_17YL-6(v^L+DJsXGm8ko-A~uL$2En0aagtpbLmn4ycAJlszg zJ|rvC%L;=AT6M|E$lpu87W;WEdR>}Q8F*k&C}u31?YNyhRB>NTw^{M%GtI(BVL=Ku z=FnB1)=~iy4}NZI|Fl4*IrJ-zKfrQJif4I6@3~}t1i;*L*S4uotoPBLkDXF)V>`)& zGt+!IA(7_=4tD!BL6741n2m(*0BHy^)~-03tTiJAn7%@5h*4(*g8%tctP{G11TgbW zvEA9Gjy963yTs|$-Cc6DzHK|XO2|oDXAz|wO5yjRb^nxN;J(MyVyEO=u4)343k3jK zdt91}<}QJa<}qZVl-={GA`>kZAce#|^|UGdy~q(DT*qP#E28tibs2h|RFN(b8@(@~ z^j@pn)`xcMJQbbF$jS9z$rk*fh!uUz+Zz&y9)TPhGa|YSl(1ludmiz0o`r4a`)44*e8r8K12iOD;_VjV`MX%{Z&#u(C`^2UHTAKbXF{uK(e+- z^)Lcb#j($Z^=7Q2%&quXR&4Gu3IJSNH!;VciQD`5l2SVFtp@QvV9)@hi1;W!hKfrG zrR$+5eovpi51-g-_{;~xV(t#_2kOjNwz$deH($~BLu3EnSUI5%H$H3ux(an1SG)x@cwPRvMjgR5-$ zb@}*g{rDnPaY%*bxG-upT2%^=0ERrT6!9s0#hDm!C63D)op1fsUz@v6&Vg-&-FcLi zSamaCsU1CHQdO3eKRej`__wq%GWv9Z#FAg|{E-@&*1@}IC7^PUkA{6e;q%cq#Ra+f z2w3v-bfULSsFZq&DW~#%ez0V|2l12I%P|ljt~S>r9|LJf)mKcFUL3@5KhN zYvB}xT0EqR^Cxz4uKTm&a(@SLx2iUhj~cQoRQ2ir=gG*-09oBnkn0TM$hv1$(>np& z;z_K*mK{5IBKw@noB+8b-QkA!P2^6V>2hXoCFdVBP%YO7lLg{9%FC!WaD2+~EdCod z=YOFfZ2S`UBjqZVje%&G%OJKkDYoWcm*)H5DJ)Xm6{H9PHy*lT8bFrk1=90ek@Gi3 z|EWF_6-fL@%)MGl=XnOlgpaR3;`rwm-FnpNBa9EDAJ3gqeoUnHuI>2l@~qg=J>Tgm z*g+As)fqGi#^h7y+%z+qX-LfdZdi2Q&QW2^4Xx^Pds4%UzdjBzh{oLDChh}fzc;7V zNE>9Y1q83}aygsjqzgXkk^{(36IN<83OX;vYWc7Ti);sCt6y>^5t*pgF>E!M0rCRI z`quDl_WTDBGN&?G8zC!orB#~P9ruW`g8JdL)>z=QZ)j@r*wWBL3U1U6CNk)(-)_8HKSkxybuopI&caXuJ7z-I{1MY)Jo%y zkeecWEC29geQ>pQirAEaz`@D_S{uirnTgGxq`e0+%MYhBoO-{uRz8-lw7v(Rp78$c`H4(? z70w)h=5dNh{Wz?2&rm*K3t?d=O;x1uuYUbMF95+6h65~}{Dh7$^nCyJi5^C1ToGU)r@%lzaE(mk>90d3;LCrmFKpDE`pJq8+@Akb zp}}%*pf7^Af&Q8dgcUe*w1a1IbQ2AUF;+e0%MskMg$uCd26NV!_gjkO`L+((uVjriy3QU1mJ?Df6Tl!P2Q-u~>@7MBzR((C zuEB}3L!vSTPbdD(c*Q{qe3#IB=1IwZV&2ix7)l7=wy(*c){hjJ z$oC$T1Zr?PZ=0w%KzFc)c*ncSdJAmT@T0$by&*N>)bMR5RQZ&B=sGWaP_m9nlPb;_ zvH7nxUZ5ZY*dUU-5}KPk{kd|t zH_E&tpm(G;_#cOufs8n+gHiz|R)sBXmFE%OCozOV2&yQ66capG`w<9I=T11@;`y%! za)u5A%AYhzfJ(eA=)ZPQc$U5BHfYx4f`lW4g^8OPx9?&}f|t1h=x6y&f)YULzjMuE zfaeOdhN1sO7zjb{%s;%z_}V?fo+7YfJMas;SVVGmi6j2=C5|FrR)v;hUl6SkF0KPc zd`ir5Dk%p0!poqcFz|gvcX@I9&0T*cMn}P}5Y536x}V%yi$E(6Bh7BY3l z4y#C&bZ*?^g7@kTRH+8ByatA)+wJq@%z6~FBVCg)d|t1T>iw$%8T44 zsnj^Qb0W2ZTvy6^Q8PFfDTj*n8?Ubzg-9+>5*@@A{Hh6p3T*){Ji+@>v}qunHcs*n z^(W-IUR`FEn?c8OH+N>%v+c*_qb9*jb+PQCgfp{ycT5NtzHaW6kp_`2b)f%~Hp)?;=T zT>x=*;S)n$Qcdu}96>*U0YH)czBgw1S~2zSK}vX5i{Wt76(WK=w7*%;2$_FkHzO3T zQPGq}edO1|?R%jd=P~CxO4YPqs2ER}W*9&<2OWX#))HFI2WVG}JGi6#&dDI#z(n*E zo;ksC+UWJy^4kb_9#{tIp48F90{JJJpxdBQBd;?Zm1o!T>)>7<4_8^UgmFjKytJ6e zvF{=KE{Y-KPgb-j02>dGT1ZCE%Ju9_{!!H)u?I-6>I)qI+VXii!4^4wZ^XTatuMeT zzwx-_jdx^YD0Ui=Tx@q_p!h&mYG(4uJB^3DVHW_vEBA0IH_MTEqcArj zP0=zqp_W*M@@3jSgC-*)hl3a3T2sT;aUzVo(A_dTn)$2ml`(FF&hsIBzR;GI#yPTA zB-s4&eWdJ@HMS=}wn=Zjxf)r{5S29nsO*W*(ZRDrw#?nk-LFG;ja_as?v5xd7^S0Zp~P-jtx6h zkh$AuiE=NUKY8UX-j@=I+bxvI5yOTSJH}+xGe{WRrZYeP2CHfw`im9N!l=5M8d4!0j0Zb)?x-Zxj>CMZ) zxFqXMoIn1#3N?4LHupJ`<-;riPv+PdI49~CP)OSVa+4s694v1a?!Hf-`^66 zpFbMe7`|sPmQK{G69UvMKz2;&?SBKUK&jg%5V34C_sc^EV9EhRJm>lq3Ob}E9&rWn zCvjm4n4d0JAlKMWUCyoC5eW+;vAPo<$g;;5R$y*BglW=dxNjo?03rS=RnO$?@i^SJ zEIdnqWcUc~&3Q1R4RQ~gj_Z)L_4;O9L1holEsqh44kjL5gone4RXW{>FNoE?#y(2w z!4A0h0u)KbnhA+aPMq>0951EY<+?@YKlXgp5`Guq#E*caEhVkL<88hCrf&l}+9s#W zB0QZ>lxNBBLp0UWY^dCT^;6r}wc;=TcuX#oWZt9#-e+F`kf^k5;mtbYtcRBX*(aiY zzMng>_&FkU1sc?U<_|S}kWg!!J;OQo+=}%`>WyZHqjhTq5ff(aYWtpSKz0mOp(*(q z_wj;(x9tp34Tx~wCx+fkfIv|l1$on8n=DG?$U$~Z1&0yWJ@(cG`&CL)&5U?5Tn1~~ z_IXu#7}RI1V#AL{K_`NSU7|;ocMTE+kjzWTiW35w8ngCmo0?Y*g&Zi0h?(g50)4;U zZ&1(~!!dbCu=Iou8xvjdn5Z)2?n4{c+V+>1A2=7;9o*JxE|C3AVQl;5Y?eU`BDU@P|Apf|F5lHTl%+t;%f0LYrT$_5v$ z4}VF5y?)p(oG?d3f5Zy~3mtW=A4h%>R^nbY1=|QBb9BdkfjU(GAit9qZ@``ft8{RkO z0X&F~Xs?us6LQc6!O*+ycu`rBq-9YM0#jINj~%4f^}VPRr6rF4ot{|1P!UxKHifo2PCp2Zfmd)y-V4Nq;k2VqBT*{U zOV$qk+r(H@X#x?42G}NmH2@oWS`8eZ9Xy|iH0!vI+&G*o5_JSwl*}~+!GX}ql+o#9 z*j0&Qty4rlQ4^vJfuG^=ghhgS^t*C2(IL!G0z;F;T$1cQ)LBH7@Ff2~t z24|(o641deA*X$VhQ=di6pc3#6MV;psXi$I+x#b98E|Ieqc}jRAx0u&=VJ!SeJ=}? z5tvquH2qtW{AA+U|RSjR7{9R5b zPc=-rXOvpJ95qz2jm!%($rX_@IdBQ20IiK-z^;vyX6XAO$i)sRx!pBmIsnC9M3sa$a$=EgXF%EcXjUo_OL4jZqBg?PSF&EP_}IuZ%|o zF@U}y<*CAHVW`n3=nlx+l*q+2R@#-GBf*SXDII0&`z;PufCc|qxFPz2U7TG8qk^MdMWL+GhLE5u zlB=5=lGGwLqmjr*DiaX8sU&Wuj)R4hKl@V0b(k)~B5wy%decmaNB_-k@3ZRSH15t! z3%{+AGY<1=b?TE=}T$U zC~-<@a?_6*7BMRLW&{X_*i%9v{KcL=tMFh#hz3k4%@*Oe7WiBS;VO#!httqc!q3T6 ziEH~*lKjykyEixLF!BD3@=}>2UyZ9_N)v+^_Lbl5w%!oOK}(hVrfkwhA(B~2AP-Lz z5q`%8T~PpqL@;DJo6vzpBgqkYh_4?(ImpCUYWS}D#IxSb{7Z;?JJe3B6uT9jkF|rL6{e^@3!;UG%>44?BCrJ;wRLrdYQ7mdYg%T*zfV!}i{edNYyG}9f6$>P(gkOa|OPt$Q_g73moMhS&{AFyaX z?KdC&;1ESEOxKV=q`(ORg#l%)pGAiF77MI6hZ=9!cMvMv#`*#$>W2sQH1BQgO?EvyNCR?~ql~^b1cS5#}(LkYe|nXDDi005j+nh#vNv zStK`H4Ebm>lBl^+1~m_0`iI`kBwBr7cvS{r43eN1S$UCKB57hPs%pqmDN}TnfuJ9j zS!B+nO)fAWcmLRwJ5;0BADx)c6e}~TG>h7BSIDNJ`25R^?I16;!pcwUXq4L`QB8Y* zdcz{->NXTl(vFq_6loab9y+VN;z(tY@GcbCR2*tZL0h1d@34fX(O*RW^naqXQm3)| z=vI3FS1Z~7f_c#auOkKU=8ksoG^I1>Wr!hGS(<*t%thFD#i%Ub3>k*15k@po#fsxC zO@I~-_wmF~^F{fQV}xR$yqDzk#)P??8Ra$VhE>0rfqS$o?b0={{|rN+N0a5329e~< zse~39mA*obSv@Gtdxlun`2byq?%wJ993|-JB>es z6bk`i$VVziQQ~~A|M0Fm2fvO%#dPHazn&0vi!w~%owf@HB4Ea`8fOg+kQGfmTX0;j z7;e2Vqd0&ytNZct6UGEY!OOb}8~x48d|4P?0D4BvIOZ#~ zo;}cm_{gSdO_gKz2PA^HHAGcjBVS!v#@fpPp%rMGFpszM8UAyj-|oeDr|7A{WV8vjvPdVKo6U=|+v7{VDOzI+2|K zFbzkCt6(S(Sc~ap?L@Y<`1_fS zDoNflFpmUioln`RmC({9GgR(nloy%~;2#zbJ<4r{#KZsZQ(s=(9eQsjoc-?+cls#d ze$k*k8WYrK$o+2qH(|2xT>~Cd$Zq~@I5rKb#eWAaa95qad150h!4kqv(lO3bmJy<$ zWOI)}NsRtl0xT5ASC@#$djP7|)vo9xt$08J%7Dx{7gprUru}+?WH={6m?hAsZdoyH zD3y}cxL--62;w;$GevtiNf-$wIiXv(9g{;8XOzH#o!kwDx3eC+3zX~*2IB~Sno8iy z3yNlAM=8Fu0$5gyPgceX>*Qf&q;<~o*OnQkGPIgAUCC9hi*Rgq{-8qip~0z$@aB)> z;7z@v!6L{t)GBeO`cD*<*#ecwACyNMy=${u^W1Y|&d)f2URvjUYGDFjLH<=+0fr7W z#tv@Clne_Oc4S-Ym4=KGCof5|HyMoDxIE?CjPSAZ2}w?+toTSbdc@e)DpYW&L3R79 z51Q4Rt37NO#v7c2q7B{xXBPxh-U>aF0(w{Bn!j6WR0W_0MMs|n4CL*lcC9T|euWw> z)jdbfpUC<-XHiQchn~xw=seo#3B3Fi`7nvYqs;6~@wgK=Sej)t<*NZfVaILD>*i$nr+c zK#h|r^TL?;+2@G+0NN7%{n?;N43fv;{j$PJ-EBvwwWZR~BF3A5L|2?GXEz79Y}#*y z;2M@ZeC0!EE_|dEW9!OzxiM;aV)Zv}IthlgupTtJaD7u=Bs*i;tg3{552F5e+DCziM z0HVkw1|h_zA)luP^ijwjaPTPBH$0|8QOf^!7{KOZF}Q+WUOFtA98@H-`2jL*92D>= zV4^NS?tw9SII@(dgaS~{5D33RO%pS}n**@b;m7xY$Lu!!-qlqE3ew-Urr!VUCx(*M zVjVhQBJ;ASdJ*l!D1KYj93Kg`WCooFNt!@~b#Nwuhl_hZkI+ZHPJjmay*{WqcDAmV zB?kZrKn)ASrJI26?(7|%UaNjHYAfg#iEba-g6DJ9zjR1dP6s3f`{Q>US!yRFj-o(r zxKQ#@X>#P?Tw7%NzxRbw`G6mmS|d}78gfsw*W_KZ)5m4pt$1W~bp(MuED+kzX-G#;g*cG!RvI<+?z zPCoi9*;_b64wzJ&Hlk8Pm(*LHK8a^L16pdV)8Rc3FJ}1#EFc97Fd4+3U4A;HC1;9& zFaSRch542=Y;lP&9uaJ#F5vqYJJ}^Jy|+M~#r;AfCpDV3bxvfWHYmnM*cXNcF?$u8 zpxCbC!$|(Nwq5XM`P_U@`b9@;n)-QHQ*le+P1~BjP9<|%JP+~#4mD9;jH($sT8VBZ zDyiHo-HMKs9f}2S2vJRKdjUxbI-)4ge}x1}lc)CM2h&>vB{I%E`96Ioc$C3pGV5_h zap1N$zQe>84O?0T>^%(|n#GLH;f z>lA##wZ?4*OgF zPDl;d$=a>O2(%1FMk&*FnB>wbZjESfMfyC8sEL#IGVUix0W>g`hCrYGbg&W z_U2<}nI!$L^h64n2?PYCqJxvyS%vqbwnJBpD;$9%1nnZD{2-7eKs^xwG}icmEEGU3 z_EfiJ|0`qv@%+72q54c#;=~-lyz)KY_HG$uPr&4VZ?#$)!cL=7#3W32dGsmFvpE4F z5#Sbk#@B^{m#;hBo)t!705-Sw_N64g?T&z6*0Atu+tFb888`}bmE;&!DM05d515(m zO1Po>n2K;}vA=m)7_jeSc!k??=>R5az*7+joX-ngQfae}i1)IY_x8`2$NAcJYj*bh z8VG1;L6p-bF=+1q$9T2acJ*_uCi+&ZlsEzbAM{(ikN)BwDzmd&;5|k&mK3Q6B;&gQ zT4{aPJhcftKxwaaU>0PSH<_U!dn>Qv6P6FI0iv7^I1KQ+^F_s~yUq*{>^_gMV)0ux zE1UcPrp$etGtOad78jX8>xp8txVmZ45cIbQ+ zW9^`1GALz?UVns+R*AbCnK*i}OeN?)^9urWHmt_#HfFBHVikI~i&(I1fC_N!fRiu(uAMb>f$CPqMD`a= ziJr=#G_VrhVp8+ z=Khb{Ox)VJ@RS}^z?1S3i@NJw82w=;0n1*fM9!XQjwc=vLG#^v9a+8tT&jjp#yGr=L}nefSgz2MSjL#LT+q;o}9a+CKTFXYW0ac|<$q`@vBdbIgvZ}sQewTkuT zQ|?SRs262p&i;>!a{Y(2pcufgv5#o>7IBN4 zt>~cqYv*PQ?l(+kE7zkR)^DubGb--B|9SuEv!i~1L@9)zM=ardpBUlTNg&5l0qsWU zDRUCDR3NWWTfZ8y*S&2}rbs~L{DcrFnBqULh^B4DqBp7ozI$NdN3T7|KYV@w1NLvf zH6|*3wi-FoIIn5CK10`(ZHmo)j}Q0qdaKefP#Z3FhN5BgC+J+RnABa)*I6%<_KW@} zq$X9 zf3jTUE2)PZM~R`kW5XQOQR)8L&h?15un7p9hz-5EY7xN3WTBN`a9m~nU&A{bih|_O zVr4ZRBAR%gH7(LBx%->R1|e%J9iqXq!0A+r3V6AI*En1GJjZw>lNoZwYcA-XD(CkX zaIv{QQ!6uT0>)OuQUQw`R;dex@d&rlG3K{pHp=fG2u+$kxBm?xD4-B$o}<(ds+0nZ zFeN!n$(p%#2cJ(+60dwPt6RJNvi!2AT6g^(U(HHPuh-f`y}q88x)xSdEmDf=_Z4Dd zLx0TEUH`W>O?-L{IM>_~*Ri2K4DTa`^_lc3)$)0U>Y3Ec9N(0MyZ7WAC|wR7)8taHN+{u%rWF0-M$M&R0G(3n|ZgaJ@cw^iGB~EDBW@`CJBJ2&!9AG z=Oc7K?j6^|9ci5k$sFQPx^7;H_Ue&NwK3xh0Z!)e1-wF#j9&LWUnw~bn@$H#+p>kH z_~gQ>SB${RT8elZaWR1HA6w3xo_?_7-AmLiKby{AHD-K5bZyzTiEJd)0XCq9s5id88bLxjq#Ft8 z?o=8h^|{PX4a_RCWdK>kpht|7*-)vBkwxChAv6O)c#Ti)?451Eu3H997GVsK?kg zm~Tb$=~6(ikCrA+Nn=3~4xjZW=_>{XROC2j-wIT667*3$C%%8#Dz5mr%IYsA3TmcN zUkkpD?|QlW0+-Mb<$PltNLK*)xZvH6XA$~CMS)sjXHR8K%?y+aXiDPW+?@%yufX_-I56`4#X0Y zLL(e@ER_{3DD-`=TAA~noIum7o!j%~WMi-!ZA zcRYz~_u^rg@UTEG3T@CgkX&Xtq+ysen#@VLA*MTzZ)mLE7rg7f*fM!9^jXm5??pC5 z6s<9$G=i}vB)PSk#Pj$W8QP03eb~NW@W5QW{x^p1koO6Kc+_XifeqXk!DgIrj_;kw z9`@Vo2eYjbp%zL$`;x^sx=>Zq-!_QnvG1U{pdNDxxeqh!%FpB)`Pl6pK$8JY`=)U@ zAf2pI`(uMR1mJ*e0~E?JuOi5F=^OssDr6u?Rg&(~+;;UC#(xn!)V>s*`9?Sl_RwUAj8=I|gI;NUy{Nrr zhNkU)iQcO)KGjdTRO$r^;wZG#sPmq&g6*TnvG3Ta_hZh7fASw|-~ZceUHLMC_w#n? z%lC7PAO$i^;L>*L6t7Cs&f#zDAYiQ2JXfT7x$M}a4187J!d6vxtpuE=3f;*rqpe0* z#8lE9cuF#d3Ari93tm^*)aO{ND^1xg75{#KkM6N$-Mw%ImWHLxZQ5f|2UJ64x;X%b z;F^Bz2cph*%|i0?gQY4BUIc?8_eySQD{<=tT;6nh2P7gu^*&`cw^qwO{c#>~+Twbi zQ0{uCTcY{#AY+M62Ss6e;$k-GNWUG88jHO63+vtv3{%UOOMK^!#h{a=hMgyuS)Xo(|Yd!N2wHp4_m_xL(Um zcTaLsyR}sx?Q6(OBTq&e3&kt94DdDYKK~@oCvut~bgEzUprs91U}=eeK5L~KrIy%+KB+q7Y+JS1D= z-JK;7>BB8!ZdC6s)btB|8aE8Z-ul?SJ&^vgbkw#;fQrtFe-=6CHs%`215;F!R=qg@+zc5i#Nff23gdRgps@QEkUGE*VsLsQ6(yh`!TJA$dmgt%MECNGr;G{&Z3yvy2s? zUe3EA@<=);qRTjhBscof$U9z!n!>+3gvx8Hm{czx^_a09R$FoYQm=6BUP4onh%5}K z+N7tJ(oke0ki$B#UZrDgXFvR@uP}LCe%2X-$KzT+WNwjTck9|^XA%k@oi>jm+}kK? z-5@yT#2^!=$*Ol2QT3dBkK;Oj8`ipWpyX{@G96M zO)``4nVW22Z_>ywkVIV~O258FiQYu^7t#z$zfzB@^5aov%2>CESQtCv%U32n>b}8$ zm%JUy$K=e}|An`&j%862eJ@&wz_mJa!`O8Kup%Ggf=25T^2?_!v&t7tHQiuv<6)g2 zj4CMmC9bJm)GoPE?kc_bH4J7@v#-*k%%{J+Lx@_WV9N93o@$~VN34>}Ljbz;>qW*G zz0tf3P=ERK5d_NCN*vuT!nJ>m_^}yWgxjG`^%I-Z;Bfl91P9ooTs08t@pN(T+D%A? zJ6tG2H-RS`>>;sD{z=Yqa31p;45a<7E9-2clt2DxS=HFu-0W8UY2Sp6My}yL_2#jp zl)UO@GrNIrltgv(eWiUjj+TZ!qYa_HTha|{@uCQrNbvQ^B*DCo&35~3S@g`IUc0GT ziizpTi6h{iA+x^M@K_WtEn;f98g7om66@k}K0_{YoZ3|ob?p`<^16rFI8M;*YnSTN zCMo9YPpXaHY*>FUiPN#J4W@=vXZ`Y&e+2~0icSqt$jvgq(!UovdzJrmnS2E>ATXMX z;?icd0mT&S*i=jccKg*%hwU)ZM3;P@x+rd0uYa9=lQ|l+I6hL4E&x0iu*38H**i{Sh=>wI zWGEe%n7ZxPRM4umRA?;u<%&bmKHdoyXX3b}eA@;B{WNeT(*@GF%rM%*_O1LVpagq* z&CJ`0&jgNk8tLYRvlyAsj(t_cYPOhZrbGOz^zU4CWFKhXGizC&H(gCpFvWY))LXnO zp86HYy#EmlA6OxC*)$%!Jv^<$>V1zOm|;@Ln*xJ7iXwWLNFmB*Pja^SN2S)Z#bOQr z_SusX{9tZMw*nJKuz4G5H8*142z&)~(4PA9IO5P^mkV+Y zr6=n6c9wrnDcc?d@ndC$^luqvm9_`LO0sAg;)CDCkI_Gkzi*G9g9~>DeMDmXpK={X z7)h{$chuhHB97;-fi|v#0k=jZ0gHQZkzNZX!HN%d{SV5Qr<^w7j-!dw4s0~yvw?Nq zN6sRO`0OvS)`^5SRr78BRMQ-^-})FQJ5$mi{GjhlBt}-l2c!5{g8G`YrX0O3=f5;e>}010;Jd!y`6%T;{zp6*zihzjZ7+S zh@XC_PupiyTg1nGgUxbPfaU;{&j%DW)hcihYTh?Kcb$*%=Zi{tS{! zT6Z#(_O+!m_z8gYE_@Gj5nvrM>13H0YdJ=n>6aQyBeACJSMgoUFd7^hFzn0`>j9J_ ztsh_RXWCkLomVKgE(Z5-kb7DeFUr(LRL`zF!v#--w$!`KZ-qQu`*o<_P-SA7s=vzqSL!U`z#Xl+MuCh*#BwKPbs74E!gZFt zDoOK{45J*`7P{}eH}`Fle!4ZjWtMjHdj6Ir-c9~yNIm}aB+Dy3@1*<#gZneHIAK$O zPd}Rn+8yLtt&|k|{o3kstgR7CUaSd>3``kfbzHz{{#o0S?7p6BAj@N=N=6SYTml}1 z-xA4;?R#V@IDtF)<6Y?6nF~ z4`0nV|4nUH-YkhD!Cb9;Za+EjU&SeweOxR@Axodzy{}*Nk@{O3X;N81(EQO@0-<#9 zSD@b|mDOD!4kPCKT5o|5kN3+)mGY*f?-9U-aMLB&^3ZD=X;Z&8hyG5b$tG{?vcLT@ zKdz~Us4ZJDh8PEW%;)M*+54mdGL^JN7Wy)+1SYYU-ejadWSCZZGx<_R*Tv{080-ZD?Tn9#AksKAnZ(9 zW!K&@mEKw1SteD%{)SR+N!d@4VcM64%c`zLVpV37hC@1T60!N`EkvmDlo4~0qv8WS zAZZ*K>DZV(&4sd@x(@Tv_6-9f|~O@{dHZvGITPe{Zr7ME(h0LO;iYF`%z zsG+@fs`bxTIGU2q*7Ww&z{vT+Nlb#^-__Qj&8w9xEZA?%t>NNBiyG zRE!&`$My}qp0b-S|BchwK7N&2VE&;Jt^WJ&jbI=Gy{2lwP_Yk-0$@?3j2#J~zcn#6 zA^bd8a4SsNuS7-=yfCROo^xri;L1LQj zh1QQ)=>G0Qjy=YoV9&lAgDX?i%0kkl#`SSS*nVyv@4yiXoyUK^#xxpLZLyD4sV3Xt zW{)d|9BYTypp;0$b_80QPq8S(Ftpd;Lt2KM6gQiU%fa zf6U^LW?KnX?8HFL#S!t&?KeLJ*)Pw>YHPfhgizUds<>`MSDJ!6MfG6CVqIqo*B%-@ z>6Yt=19&a#>%R--44Hl?jIM^*Ut?u5Do$qDa^*@8xjuh?$m&-lCC5}8@L1IyzAL=t zP&7H9>*{AZVZaxXLGv9JW7X*{h=3=Tpz5G~R7y2t%~)Q$nIV_=L;aL8I@v?`&a_zj zU%sYR3uvW7kG;_V$>~z+t!Zw-%lUi)Nylv((eO zck#~?YC8dN+1Tj*wexV6l3(qR77#H$zAVVgr+SAN1Np@BbK06k*|JR{h+{|=;l2Fe zsM9#*U(3`_7u6}?OTP>gIgVnbti?~Hx{oKie`(Y|Z|7g@esU@M1^xwmKYkYu{UD7d zO90$e3VxgqV!XKKC%OHVQhG4PAyJvgk{wJtw;H{e*E87q^g+^7lSL!4s4hCDs@s3b zx7B|z=^Jo-&qFQrU`#FI6@(6B9?QHM6-!0GV-)|1NL9fNe4tA4%cJ6<$6i%gN=*WFa(F)WpQ`)HWBUNv(NU-Ov}me2dm#~ zGfS*;Y~4dtKgfFevp-`oCrYl`KvqkfST>6)si~61-@xvu^s1z?BVtm{*sGYUcyN|z zMe3D%mdt!a#7AWGy<_xJa+aB_2L((}J;?y;lZa3W~3NycbFIX~sw2VM*BjYovdn$ z&7Hs@1&@QY8@@~9XW4Xq{OUrhg8voez0bXNkC70Of3c)VWtsT&9!p>)en}6D(oOI} zM4ZG2C!ya-*%aE;jMDHVW)ZNCEFHqvKSX0rVBP`rA|l0y-b3%VUufCTl2TA=QQ0(` zlSI&l>Y^`IaQ2xs#sggD(l6&w1-W=Dad9LAk~ z+QRKnSUdzK$)D73kl3Jz!C)Xt0_L(~)bu?<0u8qg6=zihzlq2Tk)248<=djuVenh( zgUXl(J~Kisxk(dj!p{=;qMwO=vc``AAn@gony<46<_ig)e0Ujc# z4JwRZnmWt}5#r+9Er9#}EJiMhOZ%gf!x^lCmh?x=?)g^FXvQMJ307T*cpG;d0i{g< z^e}uymf0AqoWVu-t2HkDRlI`K?p$oUIJs^XLv&l==}sel`1I|a)8X*bQU+_d)QQDC zKhRW3h#O{Ib`?a#4`_Lbozp!An880U=?{8v6licz zO5dyDXLK=*z))8-&ZcxtHP%6j5;~JGSdmrvv$bI4`TfaX@ebP8%OtxdS)o#=XL4uy zkqn_6lsX7AD(H1v!Tv0{-1)&!1gFxwy0`8NXLZTn=#jNaC_53!ju+3Fp*cj=`ngVPhqlwhzs}%76uTA{+VC&JOl6s0X!b|br z{utDdL(|u%v}G1Ko1)uwV3)-{(J}kL*^!6h-7dI?!KhGPw|ohC!yx6%^fO(y7;fq_ z`=TD@#(HO{f|zX@Rd~L!q&#k^kR)|RmqG!rKkZ|J_)CQYn4%be8yHQroDxkpS!p`v zz0;W3@)nBOteWZC_u08Hsu<}*QNK-MNM&!Mo?a@rAlaZ4!Kw_4@r0G4YG9`1H5F?* z`SFU6lnq{);~FrU)s6i`SKq1*QU1T+yalGBEkBk3N`iJT`$83dguV5hHTF&f~Q8O`HXk}6(^bVnY zLq$14H>blDrH&9IDWie!K!L#BFJwOjbzM|wCp?S?AU3B)q;`m9vZR`zf8p$kMnWic z;SFSnLS2)x!?mxH;)GCFp-SzR$eW`O!&22$+V73Ju_zqHId@VjIa3xYq$)vV2zg& z)+Rv?-Uq#q#SBzJRVP_PQ%Cu_z>TYC@&B~|Y2)8QzVLU6tyasA+&;%1au;K&Xxel;`PCPJlBh;8dU z^2a>4$54k34+q;^1LZGX_<8E_+Pc5Lq-$hC54GZQ*i zHHu_uRB$`0iS5EI;K{%+G*A%ffWe{1XRz(`mX9C?hBhLcCWl5NMA$79j&2H-hagIW zoz9;xTls0$~y(+O3Ej-f@o9G7rJiXYE&neUX3`hytYPet_!%JAs{<21t zLD|kY5Y=>^y5=~=lYJH1%Ai+6W)mrWqX!i7{QDNqopu^Fd2q6neI8OAwDKQ<@c7Cq z?I#oP8s9U~;V^`ENRqH$*Bb^VWnbhFKXwJGL>;!j(m#uEJW-DAnqQ)E0>uzMQOlTc zHHy%BU6XHz5O3b(b;RE%{N8t> zM9ts9Sr&@L7TYQ_wu3c+RhhYRHmVY9tezqxDQc8q67WU{%*z-Wr;5oJ`FOwNp*Y&} z$t1$I5sy?yPoM}o9t#Py{<)S^CTBKC_4ApG5~G3BYZyY!{&(}NTy^3m#;9Rihh|A8 zrmA;Tg)+vW9wnbBRYvd6816?+MZDAV`LSg!wzb~d zhAo13th>B~Hzy)~@voakFE$8EIvR;@l-O} zLK$Bgy7V;-|>w zgTtjRO|yv+nTm=#r3Irt;v%_~NP28vpiC#0Ol6q^2(+TjdU}Dcet)yJRVMWQ?`@Hz zVE(!Ogg-nwA@Mh+Ku(=dV9>&VH;1KwSJ5+GN>SyM^gcSo1kAc5yC z*&Bh`I&m$?;LU(r(T1|c(cP)^%I3}S+i}4^Yj(Jvw8*liq*G~M zm-*>QTfKY_XPbo=m*E$$yo_$HaINW9I%6k&G+F7d`D}f|05jR|fo)NzA+*dRoOfnytXh z1>1*88E52t>rHGvaE9~+8LO?3Z7bzn7^=x0Zh!~o> z=!f+OV;SOu5Ng!!DDJ=Tt@$mwzVU)lUo7X7a*@1R zK;h!&K2g&!G}rxGkOVCbGJdSg-Wju7(YCkzz0H77|EB7OP(*xk5L#=%YuX)Cg`Qap zQxfs+P}7Y`-$0T4dyO8zO*n!P(38cX;?2q8z_D{}B{uthl2pg1gjHZvFgKAl+3v3p zFP_AOIn_4W86VaH1DDiLdQ`fiAc(o)zbD38x`GLLJQWC1&O%A~a%M>ut;pbh{VvhF zd7^ScRgWaDtM22Kop&4uf0~Y5_o*SaAMdj^ElK&aj@Lw1!c!DACmBdd1_9M}o0?Uc z8rOqtMu6=VqU5q{w&+5DX*gqgFMRS^A^a0cCO2u{97EM`%+?az)bRrLw8gC5VOxPQ z+9dP_Pn4C3iq1eaBx?+j2yT0cU~&->AGp? zgp^>kPOvt}P&7Wo@0=_3kBJ(<8#-=dDg$UfEKT$Ul)V77&)f0EEVS!=2H3xs?Njdj zN)ue^D3jRR21L>k2^gR0YvnztS(P%Q^Y09Yc?DyGMvQjj#N&^$8?}Rg=RlzJ9u8B)}6?P_eiRTM19GlZ8bX9q_hkN zsN{t`*s~UA-^zMW0?{6aEhk{%uI5JLboZ*=mahT;EQMFMRIW(9{JI3a%2N7|MLXuVc`?ivDnzWCeQs^z@z zg>Qs%M}^5x(YNZ+kxewEyJL}|Z(+6MD>au6k4V=MldacA5mBNIJBTeoDz)InP59#;r(?9aHb4+V{6Kt*pQ^3lMZJTkeHy>LRu2v*&%D zeydTjfMTwY&s;RV8&qF}5fegxx{nDX@hVz;!Mm{&GXHeE2qD2b|A`~}^GsqxHudG4wN1IYTgj ze}RzYM<7GJG$moc8um&!K%9chnS-t4Oeo&Kg}1j2lva!HO2z{uUgDriJCd1*W<9J< z+7b(d{53XRB8o)>OnEx^QwwPfEI=bTC4F6;L#0%d!SAC`Ju9(ruGGeqrToO5!i8@< zF=_i;D4`;}#jQdne7HGVEY@|ykUH2J0`>L;$lPiT|ER|cMFE`Sm3z$HGV()3hMh0% zgVSiN#af~Bm%LqAwNwuhZygk%baC1A&2$w2!Wo-3i@B*&iLFy^&Sqx$6z}y#MM|!S zl}CdxmV^paA;z2qa=3(l-V14sG!B~{sOAbUfldP#@L_?8S1ZUYx4jHrhwxKRRoY+c zg{{BO9SXr!+`?)j4&?S`QQf*~d-AmX`-W*XbWuq<`-s~c=^ZISB@HW>*~W4>X%()I z5G&g|r%fR~HDBlqp@RWD4G1m-MQ-*{?dzqpzgf+yvv{U9%t;8S*wVcbmlUz3E8Z{w zE|dWQ?G>keL{`kDXS#_1nol=J!Ith@_jUObp6Ui@K@sIB%0iahie_?WOo=UPy5lDB zNx!6delSf_ed;A8yS;CJEQzx7EdY29TVL4xbnIe9n8W;t zK%l=tgr2sIFvM`X%KYFo>0M;dgcH*j16QI~R&?uwjJ4DT={GWfbGdo4fBh*IFbN$l z*X;;%M`A#AjHbJI?5&W`fTHm3t=MO{|Do617{$M$YB#(FMu*4eoEAKz9r2}lp-CA;nS zL)fGQJ0wx6lo7RZmWY^DtHK>r8~88#+>vIRmZYZ<#}EPu1E_g%&NcXEjHf+HWl2 z335ag0TuLC$Ol^?y!w^VyPHdCsLD%%b8xwHere*vc~1pUDV3R)DI7LXemXhokN>>w zj6#w0cg@?=UN|D6Ga2fm_M|@ zfrwTV;WGi!^fAC&itm2c%q&{*7E8r^gf;EL7vjY1q*WL6R^}kV0i?S8-)A*|oU7d~ zTf}CDCar{{TO5RgNsIdroaG~0@B5wspiuLtxU>FOnTlNB8<0!)CwM^}s5aG}Ki4jf z0@_fu-lO*aDcqN*5s-di^Ijw_lzWaT%$c=2Fv;QZ7 zgUA0O9Rg%0;?}>(|JEjJP=N~WhctVd3Cs&Btu8Mx)~G>MMam?b?TG?ydEDdbc}?~s z)hp9ZL_nPk7V<|`s}||iYFhP(2$F$65L`vrr2aEE3A?#%NIS&R@NFmOe}16cb9s7c zH~a+W?~{A@r4nzeNj(ZF|F0)A&1i-P%|P|8EGwXG$1LGYqQa$aF62;%lTnJ8%IFA+ z7OSz7b8AGZWhQt4nGfx@Ly8<3=o%cQN`AjX5 zh3FgG3?VoYz-*^-=%R!6=fNYTlD(Cg+W^#WD7~aYOoR!vlRyj#*z0y>_)E~hGCa#0 zbzkd;LELA!F`AB2fIMaA0tcLBd665m&8$kCCv^8SmYUh~mtjBzf578hHG5$sWMZ5r zr;!X6Qh?2IEFh5`2T-Z`kB6=(S?)HCqre)%anWE*>v8lNG-nwv)`IcWIC$xtT>1zZp8vBP5EHlyDDtsSg2#r;+$ zthiPwD7)@G^&6)jl)mWafIs`jQ&mE9y*nH1j1>P6B{YahbCF{aav6A@);jXAC@bbz8z7o^q5L}TfY$ZcoLajU$+;VifaaO9#H@af^C;INe4%X zB*B7CxLqgWwi6|U0*q6u44|026a6T&MULIAwtA15T=|sI5cZlNZ{c9zady9Gv5g2c zs=6ti-^)sh=IijlN(eqTv&%5{gOPoRpzjFkN_Jiwj{CFwJ3P~w_z5b|lR~(BV`dTe zoyGlSAJ3!t+^*L}7EQtIFyVy{Yq| z_x1*~F&K{MjaLfov1L28hW6ax$AWYzYH`OM3us=&&@VVbOv6B%9<69KQB*-t$^_I! z)_-?hvLU{=x0!890_0#H9yY)7lk$!SS|=-bBPxlDr8L=_%U&=n9AAJPcZdYWm6E3u zqd~JXsF~agrFuKB@IK9GWCf$b06OqeH??H;nd+fWWddZxTQ$aC<$lIo%*9QS-)`*N z34o8UK2ZX{dD|3F*gyUO$c^8pN>Tp~{AzNx07L@L^Lim!X7C1q<-Z2^Pk~M^!L=P? z7Mbr!rZ~KOv;h{^b@K*HRHRs>^2(Ye5Sy@wlS-O5c z{(Pg<=-4f$^=Hp!X@V8jBDvv;7H8hsVsviGlBoOPgs@sF_siYn(qEtX_J_n}eY3Y+ zl#jZUIO?PD1H}h~V8%`+O*e!d(`5|(JEOW9lXE`*I59?&dxQV$$u!g^{lJOldHQ-B z{H4y)Q%QuX3l3{36+KQfHj)1QQ-4W39M5rnkW2g`%N}Q1Y%*nC+ft))5lP<~QSHgg zJXTOjUz+F47{HYOLhjIQA`wH6J&~x_-vR&>9{jVL4?Tm4^k14RPfZ_tp$!Z;41*~J zIsc}CI=bb-3*?WKj|N{!EwhG4!8rUlT~#Fm%T2=gzA({@riTEOFb5kQ7KZPe-dJi{ zbo#KM>gBRU5$V;_3l!klH<_M)6OEh-{ot4`vagC}i(_8sJ$D}m{|0ZpHujQ;)Yv`)o*)N=(-x`(AorR}{Ktm6N z8yTs_93-$?;%riW`(4yW6JKyV28nluDso*w5*YLz_>ff*(AwM(%YqMwx6`LS+vb{U z9=?M1m4lVE*tZEa=WAb`r?B0E6d=Jx(reG+&MRlf6Z9Fp?7fS0bvSCXaf(IIzb=@G z&z~j9{@PNj+_oAK30a`Lx_ckmGO(3ZQGzY`>}KC$wXdas$^k$u5g@gQUMe&?toJ1< zH(8ChE?s%bKeYAPec+|*GaZV=c7gn8K=_bva#8zyQlg`)Tt^`-MOE_N_P5N+&*_O0 zuDP|2YNC`2>%*(gw}ZlOnsdur!sBK`5zL{Qwa1KW*RY*o>(Ue}>utf3144^f$=AvB2y4iUq;xrf>3XY8WIAKXx?=KWBd92wKY!el)FIFN4s} zxyWr0$8My~HYCnS^XaO`Ao$0?!+Q6}ZC?KW$(7ztr?UW5=0c&Xa?A7L7bEM!G^ah4 z_(NCS&|q@=kX06xr)q#F zBR2|U3pfYCp1|FWpyAV~3m+NOjUmMO*y2i<`;FHN2-2O-`0}40u@6hBDf$y3fgAc2 z5>xzKpEjN>g+!Iy{9d*Ez%y6-D(2CuGG3-r-DzoB^5oMpX1<1+3WO_oOxpGVz)b@C z8xjKCwRCAG1wo|WU+LZ2 z+Lc$_lv?xd^HDs<%}IzyEwSM!jJ{3t_S^caV^S}T_8;q=mECGzeBtGd#MU$K8}Bzh ztzakRig~;yUyGl?y#`4DCt(_3Xz&L>hA?Z@Hp@&dXXR&<`*YTmj&}j%Eb2?(>*CiI>>Gr)RdMo78xJZpqRs!v( zf%IGk>`}S-vrT6hZIWhqoal#WF%4Q|Oi;D8Ypv1NSS8~=Py z1l$kBX~GE=0M!J;<$avfWPnn)B3wuh^HeyTr7 z9uu*d4O{lHAe6+ZF<;SO=g%I;`N)M^KLX5U3wAc0ve#67UIlFaY*Xg6anonoL6K=K zl#J+M=yc~ScqLvxFCGCWT^YLP*rBBryl{B0@^G{b6?5sl8|0~%p5V`C0Pr+xkiyRG z7d&n+V*I?$q?vqJFgbx^3=plW2RnP=8Va`t%6f)EPNZcK`^yARyf0U7nZidvZ?6BU zL1vRxDBtR|5ZD!|uM&>dzn09}OaA>5$z8ktJ{@Zlr84$4j^suL32j0Cg3A)@)0_VB+yKz%7?D#nP*l_BR;hUMH>S$)!=^Hq78~Ie`X(@n+5HXPSTO|o z`AZa&iAl(|)pL5RnNSJKh%bXc>Ma1r zfU=wjsw~(22p{o#M-%h2>W`3?ZUBA&{3+Y&Q*4fCD|Sv?Dn%wI^ChOb`^mt@@-s0#Q%} zSjMq23->}-kE9YX0G%v^GCbRqhtbi&XZTTn0x+d; zW&yi1@H*0f=VehG}iz(<1+@i@t?Qvj26XpM~srE^Cb6IS0 z+vru@fRf1|L@HAl4;Y$YGO%)z@Y2)kxOO(y8tL>!E2C^VN~Otsf_4ySPQt%y{gVMN+-<80XCRUj z#Jr9En33f3fSJq2hYp@|#~vp;PNX&&gw2Ie0IrgaM9-8#;4jY zo((EnY+ogVv}Pk9{1VyxGuvY?(+b`FBt>cS7WA+{qHF-lzre52l8C#^d)1pQPVVhN zRr?V@uNTWniED(lBC5kF7+o$1l1RSi3z!Ja<-gY%#cq-NqD28k`~Xum=gt7b#nd+M z7oaVA!ph&$E-}~D!8K{|!_boGyf)xRuz;=gI&Qm7YsHW$%+|aY=wW-F_`*F^TA)T+o${Y!{Rp z?lGw@D6Tbt#nY2iU7$Pqk7mvDBzKkrX7+VB&`dG7JxWsZUN|Y71vO}@Nl!Yx)cz{s z@#sgZ;D*lhH??8w(5JKp3O0kh4Q&q5H`2u{fUF8Dply=)7kW^CDKeVVYv2<@-tjr< zw0+k$x$L-P#Kl(vyr1d7Wy<}O7SnBmah}UQMV74IcqK zT;$VS-O|4#Dj%4kscXQx3+T*d!OD%&#W!ePSD(Vx{p@{Z4LcU%>WL-Xy%T_e%WHc1P!MmOx!;ylZ)8rj)DhPv*k@t za5g%7V;4%fhENp~Zj6rA=q2JZUjw@`r~^{5aKR2lDB20u@`)4S!?*~T{$>-OZZ2oI zx2xwRS6$tMqlI(eJQ2+EQKq-?or^r#{p%cW4M5Zgf_D z<9tB_5Oi1o+)lMGMGe#z)O%(+2_O{EQ!_flLf=OhTR0YAFl+mfHUcF?Zh6V~Q>Db` zE1@Q5RflnT)u^D;Iw>(}_gy`EL6YseJ$3wdqCnnI6s$FyftUi1*7cnE2xy;FM;|CT zkKJ^Bs%vW?6T3u2wtnH}UKTBX zNa4Z(!?PKt{NH=Hm=N)JlnS^x`Ht=UiNZkXs0Bd%z6*o+ZU$3eqEaNq#D(WUAtH7z zDY|bqs$RzR3o2(%DWEf>gVId{H}UK}QZN{NHv8j_ROpw2KBO2)jAbyq0VhcmcORa- z6uuz06VijO-Hc6`2z2(;j;W<}6#%3F*3X=S+GFn6Kvc4H6kyluU+*eV0y`DKfN09d zATIVf;QA{NrVkUE@@7UsJ`Qf*R{FO6Qp(koE_?vKd_w~sn+3PqaA{owp2_0Z+A*>8zc~_Hw%Oz`iUg2aLrsYHKu%R#GU1V8_GHfqv zcgiDU2d~sSl(nvkB)EGS)?!9+_H>@?s1JZktKTeA*`cs8Jm2b0Yr!_$8cH7=)b=|> z+=?eepopEt=E}49^AQTT#RycsD8VA!>#Xy~cc$Y{awseVkvkv9rPhI@TEsj7Y=tOL z8tcF%l71)JeS&=Ccz+83LT+o-DYQ~1XpRj5bGr<S9e)h)WmF|=W&3~) zLKRCJl^;Z=~Pp2 z5RDw2>VlPqXW#W-1F?3M_B7NopoH%~xwn0drvY~bqce==(7;17lht<1(iA-f0Wao; zm-)Krqm%ZAa3gWd-P<0vpV@!*qJi|l@!~Y)zU*BU{*Nn&V_e!yO_#0R+x|PQHlNCZ zN_$cTD;fpBk0ZS7?S@|c)%jen0qNtZ<2s;a^y83?o(pZoAf#kkAM#~Q7iv`mf0vK+ z+jvG&C>SZT!4n)tRGXkv^237PqYtS`!~d{6r5TBKw@}m>rD94GNWtj3?6>p9GV>>a z?UFA7zj8a0tz0lz1ey=JRQA{xYvZZFzRFWmAk5Mq5%(PN%jFn3;{>O=>svX}HhmNA zo-vBOTiV^MzCos&au={g!Z)%_m6gfpJ8e-Z=seUdPLqNOKy=wl)b2yNi%{|fH3m0s zRkZ&wT2=9Qj$L}KPxTe$+wfVGMGkP*Av~@Yg@CkuMFo8NfOKvx+HCHbpNq->R!Gp3 z_+JP+t(){!6a57y4PP?q6W)*-Oey`?;5Uy>n>8N->y-xmfS4JvfIbla$DeEX1h0X~ zv$*EN`?$;1TG_{a7Lf1Yd=~|-V!%HDwy43V_8ral^_HAgs=vJ*^nph0Pg4$rmoY11 zxg;PzUUkxYTT7Ha~$n$OVB%~7AV%6T=)uUju;3&FRe0_?4cK6SaXv&kqq zeqt>eMS^LG>n;|58KzYF5^GoD&n{@_eTLxy1U4C1>0Ok~}43V8JVtisfX&#wA z-+oblbptw>@cy68tu%N&EvZR{WvgO|tWLgtZ`kzi7kI;gs9J7<+yy2S_P~6rwTwYj zqWDHNX`6^0LH1exKhA3PJoR{}DX7wKGYj8*n9EUt6Y z;9E!-mbyuYX%l<`#(Qvu!ze8U_+zuHV&PaO*zmD$UgWrQDl7b70F?o1{^E~FVd_8F z04{8GKm(LR;7m)4es7ocrC0Z|g%U|GA%&@Tu>h3A;4Fo3l$o-Lo!Jh9K5NE|lzh4S zkw{!fVG@rO;39x>S{=`>28jBc+=zx_T^20+wwJAxNcu5Sn7qT{I%?s#=ul3p_(;Ex zMB+PAm^#M}pb(5)QYe=hd0^x+ILBbrWp|tZCH+1UiO&pLVIrUgK%3pp&%2&RM^65n z_3IsdZKFgoSn*q7YAZZUY6*ji0nTAkasr_ql7WU2N&jV_3X=n_$mV5IQKHl7 l3$w!;%4CaWiA2&{{6ETn@T^c3nw= 6" - } - }, - "node_modules/@types/archiver": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-2.1.3.tgz", - "integrity": "sha512-x37dj6VvV8jArjvqvZP+qz5+24qOwgFesLMvn98uNz8qebjCg+uteqquRf9mqaxxhcM7S1vPl4YFhBs2/abcFQ==", - "dev": true, - "dependencies": { - "@types/glob": "*" - } - }, - "node_modules/@types/caseless": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", - "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==", - "dev": true - }, - "node_modules/@types/compare-versions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/compare-versions/-/compare-versions-3.0.0.tgz", - "integrity": "sha512-HNXtUQQuW3ThO9DVfTNbdvClVr+8AZlNNa2pxk5qtEvObnT27qh0DdQXTN4h5PuTTGinxwXkRKXsllJxuAzGPw==", - "dev": true - }, - "node_modules/@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "node_modules/@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "dependencies": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "node_modules/@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "10.14.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.18.tgz", - "integrity": "sha512-ryO3Q3++yZC/+b8j8BdKd/dn9JlzlHBPdm80656xwYUdmPkpTGTjkAdt6BByiNupGPE8w0FhBgvYy/fX9hRNGQ==", - "dev": true - }, - "node_modules/@types/request": { - "version": "2.48.3", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.3.tgz", - "integrity": "sha512-3Wo2jNYwqgXcIz/rrq18AdOZUQB8cQ34CXZo+LUwPJNpvRAL86+Kc2wwI8mqpz9Cr1V+enIox5v+WZhy/p3h8w==", - "dev": true, - "dependencies": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.0" - } - }, - "node_modules/@types/request/node_modules/form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/@types/tough-cookie": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz", - "integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==", - "dev": true - }, - "node_modules/@types/ws": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.3.tgz", - "integrity": "sha512-yBTM0P05Tx9iXGq00BbJPo37ox68R5vaGTXivs6RGh/BQ6QP5zqZDGWdAO6JbRE/iR1l80xeGAwCQS2nMV9S/w==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dev": true, - "dependencies": { - "es6-promisify": "^5.0.0" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dependencies": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "node_modules/archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dependencies": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dependencies": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/archiver-utils/node_modules/readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "node_modules/base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz", - "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==", - "dependencies": { - "readable-stream": "^3.0.1" - } - }, - "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/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/buffer": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz", - "integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "engines": { - "node": "*" - } - }, - "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "node_modules/compare-versions": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.5.1.tgz", - "integrity": "sha512-9fGPIB7C6AyM18CJJBHt5EnCZDG3oiTJYy0NjfIAGjKpzv0tkxWko7TNQHF5ymqm7IH03tqmeuBxtvD+Izh6mg==" - }, - "node_modules/compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dependencies": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/compress-commons/node_modules/readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/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/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "node_modules/crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dependencies": { - "buffer": "^5.1.0" - } - }, - "node_modules/crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dependencies": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - }, - "engines": { - "node": ">= 6.9.0" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "node_modules/es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dev": true, - "dependencies": { - "es6-promise": "^4.0.3" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "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": "*" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "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/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", - "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", - "dependencies": { - "ajv": "^5.3.0", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "dev": true, - "dependencies": { - "agent-base": "4", - "debug": "3.1.0" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/https-proxy-agent": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", - "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", - "dev": true, - "dependencies": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "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==" - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "node_modules/json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "node_modules/lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dependencies": { - "readable-stream": "^2.0.5" - }, - "engines": { - "node": ">= 0.6.3" - } - }, - "node_modules/lazystream/node_modules/readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "node_modules/lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" - }, - "node_modules/lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" - }, - "node_modules/lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" - }, - "node_modules/lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" - }, - "node_modules/mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", - "dependencies": { - "mime-db": "~1.37.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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/minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "node_modules/mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "dependencies": { - "minimist": "0.0.8" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "dependencies": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/mocha/node_modules/glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "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": "*" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "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=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/promisify-child-process": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/promisify-child-process/-/promisify-child-process-2.1.2.tgz", - "integrity": "sha512-j2BRwNaM7fUwrd67avtqSTRevQXZiqS+T4Ky3VVaQdvzkPpsTByBAv+ZyBxuXgV/eUrCe2qYrOZvPvd+sMryeg==", - "dependencies": { - "@types/node": "^10.11.3" - } - }, - "node_modules/promisify-child-process/node_modules/@types/node": { - "version": "10.12.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.0.tgz", - "integrity": "sha512-3TUHC3jsBAB7qVRGxT6lWyYo2v96BMmD2PTcl47H25Lu7UXtFH/2qqmKiVrnel6Ne//0TFYf6uvNX+HW2FRkLQ==" - }, - "node_modules/psl": { - "version": "1.1.29", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", - "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" - }, - "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sshpk": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.1.tgz", - "integrity": "sha512-mSdgNUaidk+dRU5MhYtN9zebdzF2iG0cNPWy8HG+W8y+fT1JnSkh0fzzpjOa0L7P8i1Rscz38t0h4gPcKz43xA==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tar-stream": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz", - "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==", - "dependencies": { - "bl": "^3.0.0", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "node_modules/tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dependencies": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "node_modules/typescript": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.3.tgz", - "integrity": "sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/vscode": { - "version": "1.1.37", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.37.tgz", - "integrity": "sha512-vJNj6IlN7IJPdMavlQa1KoFB3Ihn06q1AiN3ZFI/HfzPNzbKZWPPuiU+XkpNOfGU5k15m4r80nxNPlM7wcc0wg==", - "deprecated": "This package is deprecated in favor of @types/vscode and vscode-test. For more information please read: https://code.visualstudio.com/updates/v1_36#_splitting-vscode-package-into-typesvscode-and-vscodetest", - "dev": true, - "license": "MIT", - "dependencies": { - "glob": "^7.1.2", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "mocha": "^5.2.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "vscode-test": "^0.4.1" - }, - "bin": { - "vscode-install": "bin/install" - }, - "engines": { - "node": ">=8.9.3" - } - }, - "node_modules/vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "engines": { - "node": ">=8.0.0 || >=10.0.0" - } - }, - "node_modules/vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "dependencies": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "engines": { - "vscode": "^1.30" - } - }, - "node_modules/vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dependencies": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "bin": { - "installServerIntoExtension": "bin/installServerIntoExtension" - } - }, - "node_modules/vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dependencies": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "node_modules/vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - }, - "node_modules/vscode-test": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.4.3.tgz", - "integrity": "sha512-EkMGqBSefZH2MgW65nY05rdRSko15uvzq4VAPM5jVmwYuFQKE7eikKXNJDRxL+OITXHB6pI+a3XqqD32Y3KC5w==", - "dev": true, - "dependencies": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - }, - "engines": { - "node": ">=8.9.3" - } - }, - "node_modules/vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "node_modules/vscode/node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/vscode/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/vscode/node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/vscode/node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/vscode/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/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "dependencies": { - "async-limiter": "~1.0.0" - } - }, - "node_modules/zip-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.2.tgz", - "integrity": "sha512-ykebHGa2+uzth/R4HZLkZh3XFJzivhVsjJt8bN3GvBzLaqqrUdRacu+c4QtnUgjkkQfsOuNE1JgLKMCPNmkKgg==", - "dependencies": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - }, - "engines": { - "node": ">= 6" - } - } - }, - "dependencies": { - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true - }, - "@types/archiver": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-2.1.3.tgz", - "integrity": "sha512-x37dj6VvV8jArjvqvZP+qz5+24qOwgFesLMvn98uNz8qebjCg+uteqquRf9mqaxxhcM7S1vPl4YFhBs2/abcFQ==", - "dev": true, - "requires": { - "@types/glob": "*" - } - }, - "@types/caseless": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", - "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==", - "dev": true - }, - "@types/compare-versions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/compare-versions/-/compare-versions-3.0.0.tgz", - "integrity": "sha512-HNXtUQQuW3ThO9DVfTNbdvClVr+8AZlNNa2pxk5qtEvObnT27qh0DdQXTN4h5PuTTGinxwXkRKXsllJxuAzGPw==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", - "dev": true - }, - "@types/node": { - "version": "10.14.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.18.tgz", - "integrity": "sha512-ryO3Q3++yZC/+b8j8BdKd/dn9JlzlHBPdm80656xwYUdmPkpTGTjkAdt6BByiNupGPE8w0FhBgvYy/fX9hRNGQ==", - "dev": true - }, - "@types/request": { - "version": "2.48.3", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.3.tgz", - "integrity": "sha512-3Wo2jNYwqgXcIz/rrq18AdOZUQB8cQ34CXZo+LUwPJNpvRAL86+Kc2wwI8mqpz9Cr1V+enIox5v+WZhy/p3h8w==", - "dev": true, - "requires": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.0" - }, - "dependencies": { - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - } - } - }, - "@types/tough-cookie": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz", - "integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==", - "dev": true - }, - "@types/ws": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.3.tgz", - "integrity": "sha512-yBTM0P05Tx9iXGq00BbJPo37ox68R5vaGTXivs6RGh/BQ6QP5zqZDGWdAO6JbRE/iR1l80xeGAwCQS2nMV9S/w==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "requires": { - "lodash": "^4.17.14" - } - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz", - "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==", - "requires": { - "readable-stream": "^3.0.1" - } - }, - "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" - } - }, - "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 - }, - "buffer": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz", - "integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==", - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" - }, - "combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "compare-versions": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.5.1.tgz", - "integrity": "sha512-9fGPIB7C6AyM18CJJBHt5EnCZDG3oiTJYy0NjfIAGjKpzv0tkxWko7TNQHF5ymqm7IH03tqmeuBxtvD+Izh6mg==" - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dev": true, - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "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" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", - "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", - "requires": { - "ajv": "^5.3.0", - "har-schema": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "dev": true, - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-proxy-agent": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", - "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", - "dev": true, - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "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==" - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" - }, - "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" - }, - "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", - "requires": { - "mime-db": "~1.37.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" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "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" - } - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "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==" - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "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=" - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "promisify-child-process": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/promisify-child-process/-/promisify-child-process-2.1.2.tgz", - "integrity": "sha512-j2BRwNaM7fUwrd67avtqSTRevQXZiqS+T4Ky3VVaQdvzkPpsTByBAv+ZyBxuXgV/eUrCe2qYrOZvPvd+sMryeg==", - "requires": { - "@types/node": "^10.11.3" - }, - "dependencies": { - "@types/node": { - "version": "10.12.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.0.tgz", - "integrity": "sha512-3TUHC3jsBAB7qVRGxT6lWyYo2v96BMmD2PTcl47H25Lu7UXtFH/2qqmKiVrnel6Ne//0TFYf6uvNX+HW2FRkLQ==" - } - } - }, - "psl": { - "version": "1.1.29", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", - "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sshpk": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.1.tgz", - "integrity": "sha512-mSdgNUaidk+dRU5MhYtN9zebdzF2iG0cNPWy8HG+W8y+fT1JnSkh0fzzpjOa0L7P8i1Rscz38t0h4gPcKz43xA==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tar-stream": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz", - "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==", - "requires": { - "bl": "^3.0.0", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "typescript": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.3.tgz", - "integrity": "sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw==", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vscode": { - "version": "1.1.37", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.37.tgz", - "integrity": "sha512-vJNj6IlN7IJPdMavlQa1KoFB3Ihn06q1AiN3ZFI/HfzPNzbKZWPPuiU+XkpNOfGU5k15m4r80nxNPlM7wcc0wg==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "mocha": "^5.2.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "vscode-test": "^0.4.1" - }, - "dependencies": { - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "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" - } - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "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 - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - } - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - }, - "vscode-test": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.4.3.tgz", - "integrity": "sha512-EkMGqBSefZH2MgW65nY05rdRSko15uvzq4VAPM5jVmwYuFQKE7eikKXNJDRxL+OITXHB6pI+a3XqqD32Y3KC5w==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "requires": { - "async-limiter": "~1.0.0" - } - }, - "zip-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.2.tgz", - "integrity": "sha512-ykebHGa2+uzth/R4HZLkZh3XFJzivhVsjJt8bN3GvBzLaqqrUdRacu+c4QtnUgjkkQfsOuNE1JgLKMCPNmkKgg==", - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - } - } -} diff --git a/vscode-dotty/package.json b/vscode-dotty/package.json deleted file mode 100644 index af7b08fed4f6..000000000000 --- a/vscode-dotty/package.json +++ /dev/null @@ -1,138 +0,0 @@ -{ - "name": "dotty", - "displayName": "Dotty Language Server", - "description": "IDE integration for Dotty, the experimental Scala compiler", - "version": "0.1.17-snapshot", - "license": "Apache-2.0", - "publisher": "lampepfl", - "repository": { - "type": "git", - "url": "https://github.com/lampepfl/dotty.git" - }, - "icon": "images/dotty-logo.png", - "engines": { - "vscode": "^1.30.0" - }, - "categories": [ - "Programming Languages" - ], - "keywords": [ - "scala", - "dotty", - "jvm", - "language-server" - ], - "main": "./out/src/extension", - "activationEvents": [ - "onLanguage:scala", - "workspaceContains:.dotty-ide.json" - ], - "contributes": { - "languages": [ - { - "id": "scala", - "extensions": [ - ".scala", - ".sc" - ], - "aliases": [ - "Scala" - ] - }, - { - "id": "tasty", - "extensions": [ - ".tasty" - ], - "aliases": [ - "TASTy" - ] - } - ], - "configuration": { - "type": "object", - "title": "Dotty configuration", - "properties": { - "dotty.runWorksheetOnSave": { - "type": "boolean", - "default": true, - "description": "If true, saving a worksheet will also run it." - }, - "dotty.trace.remoteWorkspaceDumpUrl": { - "type": "string", - "default": "", - "description": "Url to send local workspace dump to." - }, - "dotty.trace.remoteTracingUrl": { - "type": "string", - "default": "", - "description": "Url to send local LSP communication to." - }, - "dotty.trace.machineId": { - "type": [ - "string", - "null" - ], - "default": null, - "description": "ID of your machine used when Dotty Language Server tracing is turned on." - }, - "dotty.trace.maximumMessageSize": { - "type": "number", - "default": 512, - "description": "Maximum size for the messages sent to remote server. Larger ones will be split." - } - } - }, - "commands": [ - { - "command": "dotty.worksheet.run", - "title": "Run worksheet", - "category": "Scala" - }, - { - "command": "dotty.worksheet.cancel", - "title": "Cancel running worksheet", - "category": "Scala" - } - ], - "configurationDefaults": { - "[scala]": { - "editor.tabSize": 2, - "editor.insertSpaces": true - } - }, - "files.associations": { - "*.sc": "scala" - } - }, - "scripts": { - "tsc": "./node_modules/.bin/tsc", - "vscode:prepublish": "npm install && ./node_modules/.bin/tsc -p ./", - "compile": "./node_modules/.bin/tsc -p ./", - "test": "node ./node_modules/vscode/bin/test", - "postinstall": "node ./node_modules/vscode/bin/install && curl -L -o out/coursier https://github.com/coursier/coursier/raw/v2.0.0-RC3-4/coursier" - }, - "extensionDependencies": [ - "scala-lang.scala" - ], - "dependencies": { - "archiver": "^3.1.1", - "compare-versions": "^3.5.1", - "promisify-child-process": "^2.1.2", - "request": "^2.88.0", - "vscode-jsonrpc": "4.0.0", - "vscode-languageclient": "^5.2.1", - "vscode-languageserver": "^5.2.1", - "ws": "^6.2.1" - }, - "devDependencies": { - "@types/archiver": "^2.1.3", - "@types/compare-versions": "^3.0.0", - "@types/mocha": "^5.2.7", - "@types/node": "^10.14.18", - "@types/request": "^2.48.3", - "@types/ws": "^6.0.3", - "typescript": "^3.6.3", - "vscode": "^1.1.37" - } -} diff --git a/vscode-dotty/src/compat.ts b/vscode-dotty/src/compat.ts deleted file mode 100644 index ae170b9090db..000000000000 --- a/vscode-dotty/src/compat.ts +++ /dev/null @@ -1,46 +0,0 @@ -import * as vscode from 'vscode' - -import { HoverRequest } from 'vscode-languageclient' -import { MarkedString, LanguageClient, LanguageClientOptions, RevealOutputChannelOn, - ServerOptions } from 'vscode-languageclient' - -// Fix hover functionality when using this version of vscode-dotty with Dotty -// Language Server 0.9 or earlier. -// Without this, the displayed hover would be "[object Object]". -export function enableOldServerWorkaround(client: LanguageClient): void { - client.clientOptions.middleware = { - provideHover: (document, position, token, next) => { - // This code is adapted from HoverFeature#registerLanguageProvider in - // https://github.com/Microsoft/vscode-languageserver-node/blob/master/client/src/client.ts - return client - .sendRequest(HoverRequest.type, - client.code2ProtocolConverter.asTextDocumentPositionParams(document, position), token) - .then( - hover => { - if (!hover) { - return undefined - } - // The server is supposed to return string or { language: string, - // value: string } or an array of those things, but instead it returns - // an array of { value: string }. This used to work but with a recent - // vscode-languageclient the user ends up seeing "[object Object]" as - // the hover information. - // We work around this by manually parsing the array of { value: string } - // into a Hover. - const contents = hover.contents as { value: string }[] - let result: vscode.MarkdownString[] = [] - for (let element of contents) { - let item = new vscode.MarkdownString() - item.appendCodeblock(element.value, "scala") - result.push(item) - } - return new vscode.Hover(result) - }, - error => { - client.logFailedRequest(HoverRequest.type, error) - return Promise.resolve(null) - } - ) - } - } -} diff --git a/vscode-dotty/src/extension.ts b/vscode-dotty/src/extension.ts deleted file mode 100644 index 1ce5e52275f0..000000000000 --- a/vscode-dotty/src/extension.ts +++ /dev/null @@ -1,371 +0,0 @@ -import * as fs from 'fs' -import * as path from 'path' - -import * as pcp from 'promisify-child-process' -import * as compareVersions from 'compare-versions' - -import { ChildProcess } from "child_process" - -import { ExtensionContext, Disposable } from 'vscode' -import * as vscode from 'vscode' -import { LanguageClient, LanguageClientOptions, RevealOutputChannelOn, - ServerOptions } from 'vscode-languageclient' -import { enableOldServerWorkaround } from './compat' -import * as features from './features' -import { DecompiledDocumentProvider } from './tasty-decompiler' - -export let client: LanguageClient - -import * as rpc from 'vscode-jsonrpc' -import * as sbtserver from './sbt-server' -import { Tracer } from './tracer' - -export const extensionName = 'dotty' -const extensionConfig = vscode.workspace.getConfiguration(extensionName) - -let extensionContext: ExtensionContext -let outputChannel: vscode.OutputChannel -let tracer: Tracer - -/** The sbt process that may have been started by this extension */ -let sbtProcess: ChildProcess | undefined - -const sbtVersion = "1.2.3" -const sbtArtifact = `org.scala-sbt:sbt-launch:${sbtVersion}` -export const workspaceRoot = `${vscode.workspace.rootPath}` -const disableDottyIDEFile = path.join(workspaceRoot, ".dotty-ide-disabled") -const sbtProjectDir = path.join(workspaceRoot, "project") -const sbtPluginFile = path.join(sbtProjectDir, "dotty-plugin.sbt") -const sbtBuildPropertiesFile = path.join(sbtProjectDir, "build.properties") -const sbtBuildSbtFile = path.join(workspaceRoot, "build.sbt") -const languageServerArtifactFile = path.join(workspaceRoot, ".dotty-ide-artifact") -const languageServerConfigFile = path.join(workspaceRoot, ".dotty-ide.json") - -function isConfiguredProject() { - return ( fs.existsSync(sbtPluginFile) - || fs.existsSync(sbtBuildPropertiesFile) - || fs.existsSync(sbtBuildSbtFile) - || (fs.existsSync(languageServerArtifactFile) && fs.existsSync(languageServerConfigFile)) - ) -} - -export function activate(context: ExtensionContext) { - // Override the language configuration from vscode-scala (doing this from - // package.json does not work) - vscode.languages.setLanguageConfiguration("scala", { - "indentationRules": { - // Auto-indent when pressing enter on a line matching this regexp, in details: - // 1. If they're not preceded by `end`, auto-indent after `while`, `for`, `match`, `try`, `if` - // 2. Auto-indent after `if ...` as long as it doesn't match `if ... then ...` - // 3. Auto-indent after `then`, `else`, `do`, `catch`, `finally`, `yield`, `case`, `=`, `=>`, `<-`, `=>>`x - "increaseIndentPattern": - /(((?|<-|=>>)\s*?$/, - // Only auto-unindent completed `end` folowed by `while`, `for`, `match`, `try`, `if` - "decreaseIndentPattern": /(^\s*end\b\s*)\b(if|while|for|match|try)$/ - } - }) - - extensionContext = context - outputChannel = vscode.window.createOutputChannel("Dotty") - tracer = new Tracer({ - extensionContext, - extensionConfig, - extensionOut: outputChannel, - }) - - const coursierPath = path.join(extensionContext.extensionPath, "out", "coursier") - const dottyPluginSbtFileSource = path.join(extensionContext.extensionPath, "out", "dotty-plugin.sbt") - const buildSbtFileSource = path.join(extensionContext.extensionPath, "out", "build.sbt") - - if (process.env['DLS_DEV_MODE']) { - const portFile = path.join(workspaceRoot, ".dotty-ide-dev-port") - fs.readFile(portFile, (err, port) => { - if (err) { - outputChannel.appendLine(`Unable to parse ${portFile}`) - throw err - } - - run({ - module: context.asAbsolutePath(path.join("out", "src", "passthrough-server.js")), - args: [ port.toString() ] - }, false) - }) - - } else if (!fs.existsSync(disableDottyIDEFile)) { - - if (!vscode.workspace.workspaceFolders) { - const editor = vscode.window.activeTextEditor - if (editor && editor.document.uri.fsPath && editor.document.uri.fsPath.length > 0) { - setWorkspaceAndReload(editor.document) - } - } else { - let configuredProject: Thenable = Promise.resolve() - if (!isConfiguredProject()) { - configuredProject = vscode.window.showInformationMessage( - "This looks like an unconfigured Scala project. Would you like to start the Dotty IDE?", - "Yes", "No" - ).then(choice => { - if (choice === "Yes") { - bootstrapSbtProject(buildSbtFileSource, dottyPluginSbtFileSource) - return Promise.resolve() - } else if (choice === "No") { - fs.appendFile(disableDottyIDEFile, "", _ => {}) - return Promise.reject() - } - }) - .then(_ => connectToSbt(coursierPath)) - .then(sbt => { - return withProgress("Configuring Dotty IDE...", configureIDE(sbt)) - .then(_ => { sbtserver.tellSbt(outputChannel, sbt, "exit") }) - }) - } - - configuredProject - .then(_ => runLanguageServer(coursierPath, languageServerArtifactFile)) - } - } -} - -/** - * Find and set a workspace root if no folders are open in the workspace. If there are already - * folders open in the workspace, do nothing. - * - * Adding a first folder to the workspace completely reloads the extension. - */ -function setWorkspaceAndReload(document: vscode.TextDocument) { - const documentPath = path.parse(document.uri.fsPath).dir - const workspaceRoot = findWorkspaceRoot(documentPath) || documentPath - - vscode.window.showInformationMessage( - `It looks like '${workspaceRoot}' is the root of your Scala workspace. ` + - 'Would you like to open it?', - 'Yes', 'No' - ).then((value: String | undefined) => { - if (value === 'Yes') { - vscode.workspace.updateWorkspaceFolders(0, null, { uri: vscode.Uri.file(workspaceRoot) }) - } - }) -} - -/** - * Find the closest parent of `current` that contains a `build.sbt`. - */ -function findWorkspaceRoot(current: string): string | undefined { - const build = path.join(current, "build.sbt") - if (fs.existsSync(build)) return current - else { - const parent = path.resolve(current, "..") - if (parent != current) { - return findWorkspaceRoot(parent) - } - } -} - -/** - * Connect to sbt server (possibly by starting a new instance) and keep verifying that the - * connection is still alive. If it dies, restart sbt server. - */ -function connectToSbt(coursierPath: string): Thenable { - - return offeringToRetry(() => { - return withSbtInstance(coursierPath).then(connection => { - return connection - }) - }, "Couldn't connect to sbt server (see log for details)") -} - -export function deactivate() { - // If sbt was started by this extension, kill the process. - // FIXME: This will be a problem for other clients of this server. - if (sbtProcess) { - sbtProcess.kill() - } -} - -/** - * Display a progress bar with title `title` while `op` completes. - * - * @param title The title of the progress bar - * @param op The thenable that is monitored by the progress bar. - */ -function withProgress(title: string, op: Thenable): Thenable { - return vscode.window.withProgress({ - location: vscode.ProgressLocation.Window, - title: title - }, _ => op) -} - -/** Connect to an sbt server and run `configureIDE`. */ -function configureIDE(sbt: rpc.MessageConnection): Thenable { - - const tellSbt = (command: string) => { - return () => sbtserver.tellSbt(outputChannel, sbt, command) - } - - const failMessage = "`configureIDE` failed (see log for details)" - - // `configureIDE` is a command, which means that upon failure, sbt won't tell us anything - // until sbt/sbt#4370 is fixed. - // We run `compile` and `test:compile` first because they're tasks (so we get feedback from sbt - // in case of failure), and we're pretty sure configureIDE will pass if they passed. - return offeringToRetry(tellSbt("compile"), failMessage).then(_ => { - return offeringToRetry(tellSbt("test:compile"), failMessage).then(_ => { - return offeringToRetry(tellSbt("configureIDE"), failMessage) - }) - }) -} - -/** - * Present the user with a dialog to retry `op` after a failure, returns its result in case of - * success. - * - * @param op The operation to perform - * @param failMessage The message to display in the dialog offering to retry `op`. - * @return A promise that will either resolve to the result of `op`, or a dialog that will let - * the user retry the operation. - */ -function offeringToRetry(op: () => Thenable, failMessage: string): Thenable { - return op() - .then(success => Promise.resolve(success), - _ => { - outputChannel.show() - return vscode.window.showErrorMessage(failMessage, "Retry?") - .then(retry => { - if (retry) return offeringToRetry(op, failMessage) - else return Promise.reject() - }) - }) -} - -function runLanguageServer(coursierPath: string, languageServerArtifactFile: string) { - fs.readFile(languageServerArtifactFile, (err, data) => { - if (err) throw err - else { - const languageServerArtifact = data.toString().trim() - const languageServerVersion = languageServerArtifact.split(":")[2] - const isOldServer = compareVersions(languageServerVersion, "0.9.x") <= 0 - fetchWithCoursier(coursierPath, languageServerArtifact).then((languageServerClasspath) => { - run({ - command: "java", - args: ["-classpath", languageServerClasspath, "dotty.tools.languageserver.Main", "-stdio"] - }, isOldServer) - }) - } - }) -} - -function startNewSbtInstance(coursierPath: string) { - fetchWithCoursier(coursierPath, sbtArtifact).then((sbtClasspath) => { - sbtProcess = pcp.spawn("java", [ - "-Dsbt.log.noformat=true", - "-classpath", sbtClasspath, - "xsbt.boot.Boot" - ], { - cwd: workspaceRoot - }) - - // Close stdin, otherwise in case of error sbt will block waiting for the - // user input to reload or exit the build. - sbtProcess.stdin.end() - - sbtProcess.stdout.on('data', data => { - outputChannel.append(data.toString()) - }) - sbtProcess.stderr.on('data', data => { - outputChannel.append(data.toString()) - }) - }) -} - -/** - * Connects to an existing sbt server, or boots up one instance and connects to it. - */ -function withSbtInstance(coursierPath: string): Thenable { - const serverSocketInfo = path.join(workspaceRoot, "project", "target", "active.json") - - if (!fs.existsSync(serverSocketInfo)) { - startNewSbtInstance(coursierPath) - } - - return sbtserver.connectToSbtServer(outputChannel) -} - -function fetchWithCoursier(coursierPath: string, artifact: string, extra: string[] = []) { - return vscode.window.withProgress({ - location: vscode.ProgressLocation.Window, - title: `Fetching ${ artifact }` - }, _ => { - const args = [ - "-jar", coursierPath, - "fetch", - "-p", - artifact - ].concat(extra) - const coursierProc = pcp.spawn("java", args) - - let classPath = "" - - coursierProc.stdout.on('data', (data: Buffer) => { - classPath += data.toString().trim() - }) - coursierProc.stderr.on('data', (data: Buffer) => { - let msg = data.toString().trim() - outputChannel.appendLine(msg) - }) - - coursierProc.on('close', (code: number) => { - if (code != 0) { - let msg = `Couldn't fetch '${ artifact }' (exit code ${ code }).` - outputChannel.appendLine(msg) - throw new Error(msg) - } - }) - return coursierProc.then(() => { return classPath }) - }) -} - -function bootstrapSbtProject(buildSbtFileSource: string, - dottyPluginSbtFileSource: string) { - fs.mkdirSync(sbtProjectDir) - fs.appendFileSync(sbtBuildPropertiesFile, `sbt.version=${sbtVersion}`) - fs.copyFileSync(buildSbtFileSource, sbtBuildSbtFile) - fs.copyFileSync(dottyPluginSbtFileSource, path.join(sbtProjectDir, "plugins.sbt")) -} - -function run(serverOptions: ServerOptions, isOldServer: boolean) { - const lspOutputChannel = tracer.run() - - const clientOptions: LanguageClientOptions = { - documentSelector: [ - { scheme: 'file', pattern: '**/*.sc' }, - { scheme: 'untitled', pattern: '**/*.sc' }, - { scheme: 'file', pattern: '**/*.scala' }, - { scheme: 'untitled', pattern: '**/*.scala' } - ], - synchronize: { - configurationSection: 'dotty' - }, - outputChannel: lspOutputChannel, - revealOutputChannelOn: RevealOutputChannelOn.Never - } - - // register DecompiledDocumentProvider for Tasty decompiler results - const provider = new DecompiledDocumentProvider() - - const providerRegistration = Disposable.from( - vscode.workspace.registerTextDocumentContentProvider(DecompiledDocumentProvider.scheme, provider) - ) - - extensionContext.subscriptions.push(providerRegistration, provider) - - client = new LanguageClient(extensionName, "Dotty", serverOptions, clientOptions) - client.registerFeature(new features.WorksheetRunFeature(client)) - client.registerFeature(new features.TastyDecompilerFeature(client, provider)) - - if (isOldServer) - enableOldServerWorkaround(client) - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - extensionContext.subscriptions.push(client.start()) -} diff --git a/vscode-dotty/src/features.ts b/vscode-dotty/src/features.ts deleted file mode 100644 index a4242e7e23a0..000000000000 --- a/vscode-dotty/src/features.ts +++ /dev/null @@ -1,105 +0,0 @@ -import * as vscode from 'vscode' -import { - BaseLanguageClient, ClientCapabilities, DynamicFeature, ServerCapabilities, - TextDocumentFeature, TextDocumentRegistrationOptions, -} from 'vscode-languageclient' -import { generateUuid } from 'vscode-languageclient/lib/utils/uuid' -import { DocumentSelector } from 'vscode-languageserver-protocol' -import { Disposable } from 'vscode-jsonrpc' - -import { WorksheetRunRequest, TastyDecompileRequest } from './protocol' -import { WorksheetProvider } from './worksheet' -import { TastyDecompilerProvider, DecompiledDocumentProvider } from './tasty-decompiler' - -// Remove this if -// https://github.com/Microsoft/vscode-languageserver-node/issues/423 is fixed. -function ensure(target: T, key: K): T[K] { - if (target[key] === void 0) { - target[key] = {} as any - } - return target[key] -} - -export interface WorksheetClientCapabilities { - worksheet?: { - run?: { - dynamicRegistration?: boolean - } - } -} - -export interface WorksheetServerCapabilities { - /** - * The server provides support for running worksheets. - */ - worksheetRunProvider?: boolean -} - -export class WorksheetRunFeature extends TextDocumentFeature { - constructor(client: BaseLanguageClient) { - super(client, WorksheetRunRequest.type) - } - - public fillClientCapabilities(capabilities: ClientCapabilities & WorksheetClientCapabilities): void { - ensure(ensure(capabilities, "worksheet")!, "run")!.dynamicRegistration = true - } - - public initialize(capabilities: ServerCapabilities & WorksheetServerCapabilities, documentSelector: DocumentSelector): void { - if (!capabilities.worksheetRunProvider) { - return - } - - const selector: DocumentSelector = [ { language: 'scala', pattern: '**/*.sc' } ] - this.register(this.messages, { - id: generateUuid(), - registerOptions: { documentSelector: selector } - }) - } - - protected registerLanguageProvider(options: TextDocumentRegistrationOptions): Disposable { - let client = this._client - return new WorksheetProvider(client, options.documentSelector!) - } -} - -export interface TastyDecompilerServerCapabilities { - /** - * The server provides support for decompiling Tasty files. - */ - tastyDecompiler?: boolean -} - -export interface TastyDecompilerClientCapabilities { - tasty?: { - decompile?: { - dynamicRegistration?: boolean - } - } -} - -export class TastyDecompilerFeature extends TextDocumentFeature { - constructor(client: BaseLanguageClient, readonly provider: DecompiledDocumentProvider) { - super(client, TastyDecompileRequest.type) - } - - fillClientCapabilities(capabilities: ClientCapabilities & TastyDecompilerClientCapabilities): void { - ensure(ensure(capabilities, "tasty")!, "decompile")!.dynamicRegistration = true - } - - initialize(capabilities: ServerCapabilities & TastyDecompilerServerCapabilities, documentSelector: DocumentSelector): void { - if (!capabilities.tastyDecompiler) { - return - } - - const selector: DocumentSelector = [ { language: 'tasty' } ] - this.register(this.messages, { - id: generateUuid(), - registerOptions: { documentSelector: selector } - }) - } - - protected registerLanguageProvider(options: TextDocumentRegistrationOptions): vscode.Disposable { - let client = this._client - return new TastyDecompilerProvider(client, options.documentSelector!, this.provider) - } -} \ No newline at end of file diff --git a/vscode-dotty/src/passthrough-server.ts b/vscode-dotty/src/passthrough-server.ts deleted file mode 100644 index 7d3005fe71fe..000000000000 --- a/vscode-dotty/src/passthrough-server.ts +++ /dev/null @@ -1,49 +0,0 @@ -import * as net from 'net' - -let argv: string[] = process.argv.slice(2) -const firstArg: string | undefined = argv.shift() -let port: string -if (firstArg === undefined) { - throw new Error('Expected port as the first argument') -} else { - port = firstArg -} - -let client = new net.Socket() -client.setEncoding('utf8') -process.stdout.setEncoding('utf8') -process.stdin.setEncoding('utf8') - -let isConnected = false - -client.on('data', (data) => { - process.stdout.write(data.toString()) -}) -process.stdin.on('readable', () => { - let chunk = process.stdin.read() - if (chunk !== null) { - if (isConnected) { - client.write(chunk) - } else { - client.on('connect', () => { - client.write(chunk) - }) - } - } -}) - -client.on('error', (err) => { - if (!isConnected) { - startConnection() - } -}) - -function startConnection() { - setTimeout(() => { - client.connect(port, () => { - isConnected = true - }) - }, 1000) -} - -startConnection() diff --git a/vscode-dotty/src/protocol.ts b/vscode-dotty/src/protocol.ts deleted file mode 100644 index b8c77e6f13cb..000000000000 --- a/vscode-dotty/src/protocol.ts +++ /dev/null @@ -1,68 +0,0 @@ -import * as vscode from 'vscode' -import { RequestType, NotificationType } from 'vscode-jsonrpc' -import { Range, VersionedTextDocumentIdentifier, TextDocumentIdentifier } from 'vscode-languageserver-protocol' - -import { client } from './extension' - -/** The parameters for the `worksheet/run` request. */ -export interface WorksheetRunParams { - textDocument: VersionedTextDocumentIdentifier -} - -/** The result of the `worksheet/run` request. */ -export interface WorksheetRunResult { - success: boolean -} - -/** The parameters for the `worksheet/publishOutput` notification. */ -export interface WorksheetPublishOutputParams { - textDocument: VersionedTextDocumentIdentifier - // TODO: remove this property and make `range` non-optional once we - // stop supporting Dotty < 0.13.0-RC1 - /** - * @deprecated Use range instead. - */ - line?: number - range?: Range - content: string -} - -/** The parameters for the `tasty/decompile` request. */ -export interface TastyDecompileParams { - textDocument: TextDocumentIdentifier -} - -/** The result of the `tasty/decompile` request */ -export interface TastyDecompileResult { - tastyTree: string - scala: string - error: number -} - -export function asWorksheetRunParams(textDocument: vscode.TextDocument): WorksheetRunParams { - return { - textDocument: client.code2ProtocolConverter.asVersionedTextDocumentIdentifier(textDocument) - } -} - - -export function asTastyDecompileParams(textDocument: vscode.TextDocument): TastyDecompileParams { - return { - textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(textDocument) - } -} - -/** The `worksheet/run` request */ -export namespace WorksheetRunRequest { - export const type = new RequestType("worksheet/run") -} - -/** The `worksheet/publishOutput` notification */ -export namespace WorksheetPublishOutputNotification { - export const type = new NotificationType("worksheet/publishOutput") -} - -/** The `tasty/decompile` request */ -export namespace TastyDecompileRequest { - export const type = new RequestType("tasty/decompile") -} diff --git a/vscode-dotty/src/sbt-server.ts b/vscode-dotty/src/sbt-server.ts deleted file mode 100644 index 279d70f8af6e..000000000000 --- a/vscode-dotty/src/sbt-server.ts +++ /dev/null @@ -1,129 +0,0 @@ -/* - * sbt - * Copyright 2011 - 2018, Lightbend, Inc. - * Copyright 2008 - 2010, Mark Harrah - * Licensed under Apache License 2.0 (see LICENSE) - */ -// Copy pasted from vscode-sbt-scala - -'use strict' - -import * as fs from 'fs' -import * as net from 'net' -import * as os from 'os' -import * as path from 'path' -import * as url from 'url' - -import * as rpc from 'vscode-jsonrpc' - -import * as vscode from 'vscode' - -import { workspaceRoot } from './extension' - -/** The result of successful `sbt/exec` call. */ -export interface ExecResult { - status: string - channelName: string - execId: number - commandQueue: string[] - exitCode: number -} - -class CommandLine { - commandLine: string - constructor(commandLine: string) { - this.commandLine = commandLine - } -} - -/** - * Sends `command` to sbt with `sbt/exec`. - * - * @param log Where to log messages between this client and sbt server - * @param connection The connection to sbt server to use - * @param command The command to send to sbt - * - * @return The result of executing `command`. - */ -export async function tellSbt(log: vscode.OutputChannel, - connection: rpc.MessageConnection, - command: string): Promise { - log.appendLine(`>>> ${command}`) - const req = new rpc.RequestType("sbt/exec") - return await connection.sendRequest(req, new CommandLine(command)) -} - -/** - * Attempts to connect to an sbt server running in this workspace. - * - * @param log Where to log messages between VSCode and sbt server. - */ -export function connectToSbtServer(log: vscode.OutputChannel): Promise { - return waitForServer().then(socket => { - let connection = rpc.createMessageConnection( - new rpc.StreamMessageReader(socket), - new rpc.StreamMessageWriter(socket)) - - connection.listen() - - connection.onNotification("window/logMessage", (params) => { - log.appendLine(`<<< [${messageTypeToString(params.type)}] ${params.message}`) - }) - - return connection - }) -} - -function connectSocket(socket: net.Socket): net.Socket { - let u = discoverUrl(); - if (u.protocol == 'tcp:' && u.port) { - socket.connect(+u.port, '127.0.0.1'); - } else if (u.protocol == 'local:' && u.hostname && os.platform() == 'win32') { - let pipePath = '\\\\.\\pipe\\' + u.hostname - socket.connect(pipePath) - } else if (u.protocol == 'local:' && u.path) { - socket.connect(u.path) - } else { - throw 'Unknown protocol ' + u.protocol - } - return socket -} - -// the port file is hardcoded to a particular location relative to the build. -function discoverUrl(): url.Url { - let pf = path.join(workspaceRoot, 'project', 'target', 'active.json') - let portfile = JSON.parse(fs.readFileSync(pf).toString()) - return url.parse(portfile.uri) -} - -function delay(ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)) -} - -async function waitForServer(): Promise { - let socket: net.Socket - return vscode.window.withProgress({ - location: vscode.ProgressLocation.Window, - title: "Connecting to sbt server..." - }, async _ => { - let retries = 60 - while (!socket && retries > 0) { - try { socket = connectSocket(new net.Socket()) } - catch (e) { - retries-- - await delay(1000) - } - } - if (socket) return Promise.resolve(socket) - else return Promise.reject() - }) -} - -function messageTypeToString(messageType: number): string { - if (messageType == 1) return "error" - else if (messageType == 2) return "warn" - else if (messageType == 3) return "info" - else if (messageType == 4) return "log" - else return "???" -} - diff --git a/vscode-dotty/src/tasty-decompiler.ts b/vscode-dotty/src/tasty-decompiler.ts deleted file mode 100644 index 23b1583a5c16..000000000000 --- a/vscode-dotty/src/tasty-decompiler.ts +++ /dev/null @@ -1,211 +0,0 @@ -import * as vscode from 'vscode' -import * as path from 'path' -import { CancellationTokenSource, ProgressLocation } from 'vscode' -import { TastyDecompileRequest, TastyDecompileResult, - asTastyDecompileParams, } from './protocol' -import { BaseLanguageClient } from 'vscode-languageclient' -import { Disposable } from 'vscode-jsonrpc' - -const RESULT_OK = 0 -const ERROR_TASTY_VERSION = 1 -const ERROR_CLASS_NOT_FOUND = 2 -const ERROR_OTHER = -1 - -export class TastyDecompilerProvider implements Disposable { - private disposables: Disposable[] = [] - - constructor( - readonly client: BaseLanguageClient, - readonly documentSelector: vscode.DocumentSelector, - readonly provider: DecompiledDocumentProvider) { - this.disposables.push( - vscode.workspace.onDidOpenTextDocument(textDocument => { - if (this.isTasty(textDocument)) { - this.requestDecompile(textDocument).then(decompileResult => { - switch (decompileResult.error) { - case RESULT_OK: - let scalaDocument = provider.makeScalaDocument(textDocument, decompileResult.scala) - - vscode.workspace.openTextDocument(scalaDocument).then(doc => { - vscode.window.showTextDocument(doc, 1) - }) - - let fileName = textDocument.fileName.substring(textDocument.fileName.lastIndexOf(path.sep) + 1) - - TastyTreeView.create(fileName, decompileResult.tastyTree) - break - case ERROR_TASTY_VERSION: - vscode.window.showErrorMessage("Tasty file has unexpected signature.") - break - case ERROR_CLASS_NOT_FOUND: - vscode.window.showErrorMessage("The class file related to this TASTy file could not be found.") - break - case ERROR_OTHER: - vscode.window.showErrorMessage("A decompilation error has occurred.") - break - default: - vscode.window.showErrorMessage("Unknown Error.") - break - } - }) - } - }) - ) - } - - dispose(): void { - this.disposables.forEach(d => d.dispose()) - this.disposables = [] - } - - /** - * Request the TASTy in `textDocument` to be decompiled - */ - private requestDecompile(textDocument: vscode.TextDocument): Promise { - const requestParams = asTastyDecompileParams(textDocument) - const canceller = new CancellationTokenSource() - const token = canceller.token - - return new Promise(resolve => { - resolve(vscode.window.withProgress({ - location: ProgressLocation.Notification, - title: "Decompiling" - }, () => this.client.sendRequest(TastyDecompileRequest.type, requestParams, token) - )) - }).then(decompileResult => { - canceller.dispose() - return decompileResult - }) - } - - /** Is this document a tasty file? */ - private isTasty(document: vscode.TextDocument): boolean { - return vscode.languages.match(this.documentSelector, document) > 0 - } -} - -/** - * Provider of virtual, read-only, scala documents - */ -export class DecompiledDocumentProvider implements vscode.TextDocumentContentProvider { - static scheme = 'decompiled' - - private _documents = new Map() - private _subscriptions: vscode.Disposable - - constructor() { - // Don't keep closed documents in memory - this._subscriptions = vscode.workspace.onDidCloseTextDocument(doc => this._documents.delete(doc.uri.toString())) - } - - dispose() { - this._subscriptions.dispose() - this._documents.clear() - } - - provideTextDocumentContent(uri: vscode.Uri): string { - let document = this._documents.get(uri.toString()) - if (document) { - return document - } else { - return 'Failed to load result.' - } - } - - /** - * Creates a new virtual document ready to be provided and opened. - * - * @param textDocument The document containing the TASTy that was decompiled - * @param content The source code provided by the language server - */ - makeScalaDocument(textDocument: vscode.TextDocument, content: string): vscode.Uri { - let scalaDocument = textDocument.uri.with({ - scheme: DecompiledDocumentProvider.scheme, - path: textDocument.uri.path.replace(".tasty", ".scala") - }) - this._documents.set(scalaDocument.toString(), content) - return scalaDocument - } -} - -/** - * WebView used as container for preformatted TASTy trees - */ -class TastyTreeView { - public static readonly viewType = 'tastyTree' - - private readonly _panel: vscode.WebviewPanel - private _disposables: vscode.Disposable[] = [] - - /** - * Create new panel for a TASTy tree in a new column or column 2 if none is currently open - * - * @param title The panel's title - * @param content The panel's preformatted content - */ - public static create(title: string, content: string) { - const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined - - const panel = vscode.window.createWebviewPanel(TastyTreeView.viewType, "Tasty Tree", (column || vscode.ViewColumn.One) + 1, {}) - - new TastyTreeView(panel, title, content) - } - - private constructor( - panel: vscode.WebviewPanel, - title: string, - content: string - ) { - this._panel = panel - this.setContent(title, content) - - // Listen for when the panel is disposed - // This happens when the user closes the panel or when the panel is closed programmatically - this._panel.onDidDispose(() => this.dispose(), null, this._disposables) - } - - public dispose() { - this._panel.dispose() - - while (this._disposables.length) { - const x = this._disposables.pop() - if (x) { - x.dispose() - } - } - } - - private setContent(name: string, content: string) { - this._panel.title = name - this._panel.webview.html = this._getHtmlForWebview(content) - } - - private _getHtmlForWebview(content: string) { - return ` - - - - - - Tasty Tree - - -

-${content}
- - ` - } -} diff --git a/vscode-dotty/src/tracer.ts b/vscode-dotty/src/tracer.ts deleted file mode 100644 index 62afd4a140a8..000000000000 --- a/vscode-dotty/src/tracer.ts +++ /dev/null @@ -1,391 +0,0 @@ -import * as vscode from 'vscode' - -import * as fs from 'fs' -import * as path from 'path' - -import * as archiver from 'archiver' -import * as WebSocket from 'ws' -import * as request from 'request' - -import { extensionName } from './extension' -import { TracingConsentCache } from './tracing-consent' - -const consentCommandName = `${extensionName}.adjust-consent` - -export interface Ctx { - readonly extensionContext: vscode.ExtensionContext, - readonly extensionConfig: vscode.WorkspaceConfiguration, - readonly extensionOut: vscode.OutputChannel -} - -export class Tracer { - private readonly ctx: Ctx - - private projectId: string - private machineId: string - private sessionId: string - - private tracingConsent: TracingConsentCache - - private readonly remoteTracingUrl: string | undefined - private readonly remoteWorkspaceDumpUrl: string | undefined - private readonly maximumMessageSize: number - private get isTracingEnabled(): boolean { - return Boolean(this.remoteWorkspaceDumpUrl || this.remoteTracingUrl) - } - - constructor(ctx: Ctx) { - this.ctx = ctx - - this.tracingConsent = new TracingConsentCache(ctx.extensionContext.workspaceState) - - this.remoteWorkspaceDumpUrl = this.ctx.extensionConfig.get('trace.remoteWorkspaceDumpUrl') - this.remoteTracingUrl = this.ctx.extensionConfig.get('trace.remoteTracingUrl') - const maximumMessageSize = this.ctx.extensionConfig.get('trace.maximumMessageSize') - this.maximumMessageSize = maximumMessageSize === undefined || maximumMessageSize < 0 ? 0 : maximumMessageSize | 0 - - this.machineId = (() => { - const machineIdKey = 'trace.machineId' - function persisted(value: string): string { - ctx.extensionConfig.update(machineIdKey, value, vscode.ConfigurationTarget.Global) - return value - } - - const machineId = ctx.extensionConfig.get(machineIdKey) - if (machineId != null) return machineId - - // vscode.env.machineId is a dummy value if telemetry is off - cannot be used - const vscodeMachineId = vscode.workspace.getConfiguration().get('telemetry.machineId') - if (vscodeMachineId !== undefined) return persisted(vscodeMachineId) - - function uuidv4() { - // https://stackoverflow.com/a/2117523 - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8) - return v.toString(16) - }) - } - - return persisted(uuidv4()) - })() - - if (vscode.workspace.name !== undefined) { - // HACK: The projects cloned by students use the naming convention - // `$id-$name-$githubUsername`, so they leak the student's github - // username, to preserve anonymity, we drop the last part of the - // name. - this.projectId = vscode.workspace.name.replace(/^(\d+-.+)-.+$/, "$1") - } else { - this.projectId = 'no-project' - } - - this.sessionId = new Date().toISOString() - } - - run(): vscode.OutputChannel | undefined { - const consentCommandDisposable = vscode.commands.registerCommand(consentCommandName, () => this.askForTracingConsent()) - if (this.isTracingEnabled && this.tracingConsent.get() === 'no-answer') this.askForTracingConsent() - this.initializeAsyncWorkspaceDump() - - const lspOutputChannel = this.createLspOutputChannel() - const statusBarItem = this.createStatusBarItem() - for (const disposable of [consentCommandDisposable, lspOutputChannel, statusBarItem]) { - if (disposable) this.ctx.extensionContext.subscriptions.push(disposable) - } - return lspOutputChannel - } - - private askForTracingConsent(): void { - vscode.window.showInformationMessage( - 'To help us improve the Scala IDE support, we would like to collect ' + - 'the content of every Scala file in your project and ' + - 'every interaction with Scala files in the IDE, including keystrokes. ' + - 'This data will be stored anonymously (we won\'t know your name) on servers at EPFL in Switzerland.', - { 'modal': true }, - { title: 'Allow' }, - { title: 'Deny', isCloseAffordance: true } - ).then(value => { - if (value !== undefined && (value.title === 'Allow' || value.title === 'Deny')) this.tracingConsent.set(value.title) - }) - } - - private initializeAsyncWorkspaceDump() { - const url = this.remoteWorkspaceDumpUrl - if (!url) return - - const doInitialize = () => { - try { - this.asyncUploadWorkspaceDump(url) - } catch (err) { - this.logError('error during workspace dump', safeError(err)) - } - } - - if (this.tracingConsent.get() === 'Allow') { - doInitialize() - } else { - let didInitialize = false - this.tracingConsent.subscribe(() => { - if (didInitialize) return - didInitialize = true - doInitialize() - }) - } - } - - private createStatusBarItem(): vscode.StatusBarItem | undefined { - if (!this.isTracingEnabled) return undefined - const item = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 0) - item.command = consentCommandName - const renderStatusBarItem = () => { - item.text = (() => { - const desc = this.tracingConsent.get() === 'Allow' ? 'On' : 'Off' - return `$(radio-tower) Scala telemetry: ${desc}` - })() - - item.tooltip = (() => { - const desc = this.tracingConsent.get() === 'Allow' ? 'enabled' : 'disabled' - const toggle = this.tracingConsent.get() === 'Allow' ? 'disable' : 'enable' - return `Data collection for Scala is ${desc}. ` + - `Click to ${toggle} it.` - })() - } - renderStatusBarItem() - this.tracingConsent.subscribe(renderStatusBarItem) - item.show() - return item - } - - private createLspOutputChannel(): vscode.OutputChannel | undefined { - if (this.ctx.extensionConfig.get('trace.server') === undefined) { - if (this.remoteTracingUrl) this.ctx.extensionOut.appendLine( - 'error: tracing URL is set, but trace.server not - no remote tracing possible.' - ) - return undefined - } - - const lspOutputChannel = vscode.window.createOutputChannel('Dotty LSP Communication') - if (!this.remoteTracingUrl) return lspOutputChannel - try { - return this.createRemoteLspOutputChannel(this.remoteTracingUrl, lspOutputChannel) - } catch (err) { - this.logError('error during remote output channel creation', safeError(err)) - return lspOutputChannel - } - } - - private asyncUploadWorkspaceDump(url: string) { - const storagePath = this.ctx.extensionContext.storagePath - // TODO: handle multi-root workspaces - const rootPath = vscode.workspace.rootPath - if (storagePath === undefined || rootPath === undefined) { - this.logError('Cannot start workspace dump b/c of workspace state:', { storagePath, rootPath }) - return - } - - if (!fs.existsSync(storagePath)) fs.mkdirSync(storagePath) - const outputPath = path.join(storagePath, 'workspace-dump.zip') - if (fs.existsSync(outputPath)) fs.unlinkSync(outputPath) - const output = fs.createWriteStream(outputPath) - - const zip = archiver('zip') - zip.on('error', (err) => this.logError('zip error', safeError(err))) - zip.on('warning', (err) => this.logError('zip warning', safeError(err))) - zip.on('finish', () => { - this.ctx.extensionOut.appendLine('zip - finished') - fs.createReadStream(outputPath).pipe( - request.put(url, { - qs: { - client: this.machineId, - project: this.projectId, - session: this.sessionId - } - }) - .on('error', (err) => this.logError('zip upload connection error', url, safeError(err))) - .on('complete', (resp) => { - if (!(resp.statusCode >= 200 && resp.statusCode < 300)) { - this.logError('zip upload http error', url, resp.statusCode, resp.body) - } else { - this.ctx.extensionOut.appendLine('zip - http upload finished') - } - }) - ) - }) - - this.ctx.extensionOut.appendLine('zip - starting') - zip.pipe(output) - zip.glob('./**/*.{scala,sc,sbt,java}', { cwd: rootPath }) - zip.glob('./**/.dotty-ide{.json,-artifact}', { cwd: rootPath }) - zip.finalize() - } - - private createRemoteLspOutputChannel( - remoteTracingUrl: string, - localOutputChannel: vscode.OutputChannel - ): vscode.OutputChannel { - const createSocket = () => { - const socket = new WebSocket(remoteTracingUrl, { - headers: { - 'X-DLS-Project-ID': this.projectId, - 'X-DLS-Client-ID': this.machineId, - 'X-DLS-Session-ID': this.sessionId, - }, - }) - - const timer = setInterval( - () => { - if (socket.readyState === WebSocket.OPEN) { - socket.send('') - } else if (socket.readyState === WebSocket.CLOSED) { - clearInterval(timer) - } - }, - 10 * 1000 /*ms*/, - ) - - socket.onerror = (event) => { - this.logError( - 'socket error', - remoteTracingUrl, - new SafeJsonifier(event, (event) => ({ - error: safeError(event.error), - message: event.message, - type: event.type - })) - ) - } - - socket.onclose = (event) => { - this.logError( - 'socket closed', - remoteTracingUrl, - new SafeJsonifier(event, (event) => ({ - wasClean: event.wasClean, - code: event.code, - reason: event.reason - })) - ) - } - - return socket - } - - let alreadyCreated = false - let socket: WebSocket - // note: creating socket lazily is important for correctness - // if the user did not initially give his consent on IDE start, but gives it afterwards - // we only want to start a connection and upload data *after* being given consent - const withSocket: (thunk: (socket: WebSocket) => any) => void = (thunk) => { - // only try to create the socket _once_ to avoid endlessly looping - if (!alreadyCreated) { - alreadyCreated = true - try { - socket = createSocket() - } catch (err) { - this.logError('socket create error', safeError(err)) - } - } - - if (socket) thunk(socket) - } - - let log: string = '' - let messageCounter: number = 0 - // Avoid filling the user memory with log messages - let maxLocalMessages: number = 1000 - return { - name: 'websocket', - - append: (value: string) => { - messageCounter++ - if (messageCounter > maxLocalMessages) { - messageCounter = 0 - localOutputChannel.clear() - } - - localOutputChannel.append(value) - if (this.tracingConsent.get() === 'Deny') return - log += value - }, - - appendLine: (value: string) => { - messageCounter++ - if (messageCounter > maxLocalMessages) { - messageCounter = 0 - localOutputChannel.clear() - } - - localOutputChannel.appendLine(value) - if (this.tracingConsent.get() === 'Deny') { - log = '' - return - } - - log += value - log += '\n' - if (this.tracingConsent.get() === 'Allow') withSocket((socket) => { - if (socket.readyState === WebSocket.OPEN) { - const send = (msg: string) => socket.send(msg, (err) => { - if (err) { - this.logError('socket send error', err) - } - }) - - let start = 0 - while (start < log.length) { - send(log.substring(start, start + this.maximumMessageSize)) - start += this.maximumMessageSize - } - log = '' - } - }) - }, - - clear() { }, - show() { }, - hide() { }, - dispose() { - if (socket) socket.close() - localOutputChannel.dispose() - } - } - } - - private logError(message: string, ...rest: any[]) { - const msg = `[Dotty LSP Tracer] ${message}` - // in a browser, we'd be able to log a SafeJsonifier directly - // and get an inspectable object in the console - // unfortunately, Electron apparently uses .toJson if available, - // so we need to manually unwrap SafeJsonifiers - console.error(msg, ...rest.map((a) => a instanceof SafeJsonifier ? a.value : a)) - function cautiousStringify(a: any): string { - try { - return JSON.stringify(a, undefined, 4) - } catch (err) { - console.error('cannot stringify', err, a) - return a.toString() - } - } - this.ctx.extensionOut.appendLine([msg].concat(rest.map(cautiousStringify)).join(' ')) - } -} - -function safeError(e: Error): SafeJsonifier { - return new SafeJsonifier(e, (e) => e.toString()) -} - -/** - * Wraps a value of type T so it's possible to safely pass it to JSON.stringify. - * - * Values with circular references (errors, for example) cause JSON.stringify to throw an exception - */ -class SafeJsonifier { - constructor( - readonly value: T, - readonly valueToObject: (t: T) => {} - ) {} - - toJSON() { - return this.valueToObject(this.value) - } -} diff --git a/vscode-dotty/src/tracing-consent.ts b/vscode-dotty/src/tracing-consent.ts deleted file mode 100644 index 306fb1190b53..000000000000 --- a/vscode-dotty/src/tracing-consent.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Memento } from 'vscode' - -export type TracingConsent = 'Allow' | 'Deny' | 'no-answer' - -export class TracingConsentCache { - private readonly workspaceState: Memento - - // since updating Memento is async, caching prevents nonsense edge-cases - private cache?: TracingConsent - private subscribers: Array<() => void> = [] - - constructor(workspaceState: Memento) { - this.workspaceState = workspaceState - } - - get(): TracingConsent { - if (this.cache !== undefined) return this.cache - const setting = this.workspaceState.get('remote-tracing-consent') - this.cache = setting === undefined ? 'no-answer' - : setting ? 'Allow' - : 'Deny' - return this.cache - } - - set(value: 'Allow' | 'Deny'): void { - this.workspaceState.update('remote-tracing-consent', value === 'Allow') - this.cache = value - this.subscribers.forEach(f => f()) - } - - subscribe(callback: () => void): void { - this.subscribers.push(callback) - } -} diff --git a/vscode-dotty/src/worksheet.ts b/vscode-dotty/src/worksheet.ts deleted file mode 100644 index cd739edde2c3..000000000000 --- a/vscode-dotty/src/worksheet.ts +++ /dev/null @@ -1,385 +0,0 @@ -import * as vscode from 'vscode' -import { - CancellationToken, CancellationTokenSource, CodeLens, CodeLensProvider, Command, - Event, EventEmitter, ProgressLocation, Range, TextDocument, TextEdit -} from 'vscode' - -import { - asWorksheetRunParams, WorksheetRunRequest, WorksheetRunResult, - WorksheetPublishOutputParams, WorksheetPublishOutputNotification -} from './protocol' -import { BaseLanguageClient } from 'vscode-languageclient' -import { Disposable } from 'vscode-jsonrpc' - -/** - * The command key for running a worksheet. Exposed to users as - * `Run worksheet`. - */ -export const worksheetRunKey = "dotty.worksheet.run" - -/** - * The command key for cancelling a running worksheet. Exposed to users as - * `Cancel running worksheet`. - */ -export const worksheetCancelKey = "dotty.worksheet.cancel" - -/** - * If true, the setting for running the worksheet on save is enabled. - */ -function runWorksheetOnSave(): boolean { - return vscode.workspace.getConfiguration("dotty").get("runWorksheetOnSave") as boolean -} - -/** - * A wrapper around the information that VSCode needs to display text decorations. - * - * @param decorationType The styling options of this decoration - * @param decorationOptions The options of this decoraiton. - */ -class Decoration { - constructor(readonly decorationType: vscode.TextEditorDecorationType, - readonly decorationOptions: vscode.DecorationOptions) { - } -} - -/** A worksheet managed by vscode */ -class Worksheet implements Disposable { - - /** The version of this document the last time it was run */ - private runVersion: number = -1 - - /** All decorations that have been added so far */ - private decorations: Decoration[] = [] - - /** The minimum margin to add so that the decoration is shown after all text. */ - private margin: number = 0 - - private readonly _onDidStateChange: EventEmitter = new EventEmitter() - /** This event is fired when the worksheet starts or stops running. */ - readonly onDidStateChange: Event = this._onDidStateChange.event - - /** - * If this is not null, this can be used to signal cancellation of the - * currently running worksheet. - */ - private canceller?: CancellationTokenSource = undefined - - constructor(readonly document: vscode.TextDocument, readonly client: BaseLanguageClient) { - } - - dispose() { - this.reset() - this._onDidStateChange.dispose() - } - - /** Cancel any current run, remove all decorations, and resets this worksheet. */ - private reset(): void { - this.cancel() - - this.decorations.forEach(decoration => decoration.decorationType.dispose()) - this.decorations = [] - this.runVersion = -1 - this.margin = this.longestLine() + 5 - } - - /** If this worksheet is currently being run, cancel the run. */ - cancel(): void { - if (this.canceller) { - this.canceller.cancel() - this.canceller = undefined - - this._onDidStateChange.fire() - } - } - - /** Is this worksheet currently being run ? */ - isRunning(): boolean { - return this.canceller != undefined - } - - /** Display the output in the worksheet's editor. */ - handleMessage(output: WorksheetPublishOutputParams, editor: vscode.TextEditor) { - let range = output.range ? - this.client.protocol2CodeConverter.asRange(output.range) : - (output.line ? - new Range(output.line - 1, 0, output.line - 1, 0) : - new Range(0, 0, 0, 0)) - this.displayAndSaveResult(range, output.content, editor) - } - - /** - * Run the worksheet in `document`, if a previous run is in progress, it is - * cancelled first. - */ - run(): Promise { - this.cancel() - this.reset() - const canceller = new CancellationTokenSource() - const token = canceller.token - this.canceller = canceller // This ensures that isRunning() returns true. - - this._onDidStateChange.fire() - - return new Promise(resolve => { - this.runVersion = this.document.version - resolve( - vscode.window.withProgress({ - location: ProgressLocation.Window, - title: "Running worksheet" - }, () => this.client.sendRequest( - WorksheetRunRequest.type, asWorksheetRunParams(this.document), token - ))) - }).then(result => { - canceller.dispose() - if (this.canceller === canceller) { // If false, a new run has already started - // This ensures that isRunning() returns false. - this.canceller = undefined - - this._onDidStateChange.fire() - } - return result - }) - } - - /** - * Parse and display the result of running part of this worksheet. The result is saved so that it - * can be restored if this buffer is closed. - * - * @param range The range in the source that produced the result. - * @param runResult The result itself. - * @param editor The editor where to display the result. - */ - private displayAndSaveResult(range: Range, runResult: string, editor: vscode.TextEditor): void { - const resultLines = runResult.split(/\r\n|\r|\n/g) - - if (resultLines.length == 0) - return - - const lastLine = editor.document.lineAt(range.end.line) - const decorationOptions = { - range: range, - hoverMessage: new vscode.MarkdownString().appendCodeblock(runResult) - } - const decorationMargin = this.margin - lastLine.text.length - const decorationText = resultLines[0] + (resultLines.length > 1 ? `<${resultLines.length - 1} lines hidden, hover to see full output>` : "") - const decorationType = this.createDecoration(decorationMargin, decorationText) - const decoration = new Decoration(decorationType, decorationOptions) - this.decorations.push(decoration) - editor.setDecorations(decorationType, [decorationOptions]) - } - - /** - * Restore the decorations that belong to this worksheet in `editor`. If the document has been - * changed, since the last run of the worksheet, the decorations won't be added. - * - * @param editor The editor where to display the decorations. - */ - restoreDecorations(editor: vscode.TextEditor) { - if (editor.document.version == this.runVersion) { - this.decorations.forEach(decoration => { - editor.setDecorations(decoration.decorationType, [decoration.decorationOptions]) - }) - } - } - - /** - * Create a new `TextEditorDecorationType` showing `text`. The decoration - * will appear `margin` characters after the end of the line. - * - * @param margin The margin in characters between the end of the line - * and the decoration. - * @param text The text of the decoration. - * @return a new `TextEditorDecorationType`. - */ - private createDecoration(margin: number, text: string) { - return vscode.window.createTextEditorDecorationType({ - isWholeLine: true, - rangeBehavior: vscode.DecorationRangeBehavior.OpenClosed, - after: { - contentText: text, - margin: `0px 0px 0px ${margin}ch`, - fontStyle: "italic", - // It would make more sense to use the colors of commments in the - // current theme, but there's no API to access this currently - // (https://github.com/Microsoft/vscode/issues/32813). - color: new vscode.ThemeColor("terminal.ansiGreen"), - } - }) - } - - /** - * Finds the length in characters of the longest line of `document`. - * - * @param document The document to inspect. - * @return The length in characters of the longest line. - */ - private longestLine() { - let maxLength = 0 - const lineCount = this.document.lineCount - for (let i = 0; i < lineCount; ++i) { - let length = this.document.lineAt(i).text.length - maxLength = Math.max(maxLength, length) - } - - return maxLength - } -} - -export class WorksheetProvider implements Disposable { - private worksheets: Map = new Map() - private readonly _onDidWorksheetStateChange: EventEmitter = new EventEmitter() - /** This event is fired when a worksheet starts or stops running. */ - readonly onDidWorksheetStateChange: Event = this._onDidWorksheetStateChange.event - - private disposables: Disposable[] = [ this._onDidWorksheetStateChange ] - - constructor( - readonly client: BaseLanguageClient, - readonly documentSelector: vscode.DocumentSelector) { - const codeLensProvider = new WorksheetCodeLensProvider(this) - this.disposables.push( - codeLensProvider, - vscode.languages.registerCodeLensProvider(documentSelector, codeLensProvider), - vscode.workspace.onWillSaveTextDocument(event => { - const document = event.document - const worksheet = this.worksheetFor(document) - // If the document is not dirty, then `onDidSaveTextDocument` will not - // be called so we need to run the worksheet now. - // On the other hand, if the document _is_ dirty, we should _not_ run - // the worksheet now because the server state will not be synchronized - // with the client state, instead we let `onDidSaveTextDocument` - // handle it. - if (worksheet && runWorksheetOnSave() && !document.isDirty) { - worksheet.run() - } - }), - vscode.workspace.onDidSaveTextDocument(document => { - const worksheet = this.worksheetFor(document) - if (worksheet && runWorksheetOnSave()) { - worksheet.run() - } - }), - vscode.workspace.onDidCloseTextDocument(document => { - const worksheet = this.worksheetFor(document) - if (worksheet) { - worksheet.dispose() - this.worksheets.delete(document) - } - }), - vscode.window.onDidChangeActiveTextEditor(editor => { - if (editor) { - const worksheet = this.worksheetFor(editor.document) - if (worksheet) { - worksheet.restoreDecorations(editor) - } - } - }), - vscode.commands.registerCommand(worksheetRunKey, () => { - this.callOnActiveWorksheet(w => w.run()) - }), - vscode.commands.registerCommand(worksheetCancelKey, () => { - this.callOnActiveWorksheet(w => w.cancel()) - }) - ) - client.onNotification(WorksheetPublishOutputNotification.type, params => { - this.handleMessage(params) - }) - } - - dispose() { - this.worksheets.forEach(d => d.dispose()) - this.worksheets.clear() - this.disposables.forEach(d => d.dispose()) - this.disposables = [] - } - - /** Is this document a worksheet? */ - private isWorksheet(document: vscode.TextDocument): boolean { - return vscode.languages.match(this.documentSelector, document) > 0 - } - - /** If `document` is a worksheet, create a new worksheet for it, or return the existing one. */ - worksheetFor(document: vscode.TextDocument): Worksheet | undefined { - if (!this.isWorksheet(document)) return - else { - const existing = this.worksheets.get(document) - if (existing) { - return existing - } else { - const newWorksheet = new Worksheet(document, this.client) - this.worksheets.set(document, newWorksheet) - this.disposables.push( - newWorksheet.onDidStateChange(() => this._onDidWorksheetStateChange.fire(newWorksheet)) - ) - return newWorksheet - } - } - } - - /** If the active text editor contains a worksheet, apply `f` to it. */ - private callOnActiveWorksheet(f: (_: Worksheet) => void) { - let document = vscode.window.activeTextEditor && vscode.window.activeTextEditor.document - if (document) { - const worksheet = this.worksheetFor(document) - if (worksheet) { - f(worksheet) - } - } - } - - /** - * Handle the result of running part of a worksheet. - * This is called when we receive a `worksheet/publishOutput`. - * - * @param output The result of running part of a worksheet. - */ - private handleMessage(output: WorksheetPublishOutputParams) { - const editor = vscode.window.visibleTextEditors.find(e => { - let uri = e.document.uri.toString() - return uri == output.textDocument.uri - }) - - if (editor) { - const worksheet = this.worksheetFor(editor.document) - if (worksheet) { - worksheet.handleMessage(output, editor) - } - } - } -} - -class WorksheetCodeLensProvider implements CodeLensProvider, Disposable { - private readonly _onDidChangeCodeLenses: EventEmitter = new EventEmitter() - readonly onDidChangeCodeLenses: Event = this._onDidChangeCodeLenses.event - - private disposables: Disposable[] = [ this._onDidChangeCodeLenses ] - - constructor(readonly worksheetProvider: WorksheetProvider) { - this.disposables.push( - worksheetProvider.onDidWorksheetStateChange(() => this._onDidChangeCodeLenses.fire()) - ) - } - - dispose() { - this.disposables.forEach(d => d.dispose()) - this.disposables = [] - } - - private readonly runCommand: Command = { - command: worksheetRunKey, - title: "Run this worksheet" - } - - private readonly cancelCommand: Command = { - command: worksheetCancelKey, - title: "Worksheet running, click to cancel" - } - - provideCodeLenses(document: TextDocument, token: CancellationToken) { - const worksheet = this.worksheetProvider.worksheetFor(document) - if (worksheet) { - const cmd = worksheet.isRunning() ? this.cancelCommand : this.runCommand - return [ new CodeLens(new Range(0, 0, 0, 0), cmd) ] - } - } -} diff --git a/vscode-dotty/test/extension.test.ts b/vscode-dotty/test/extension.test.ts deleted file mode 100644 index 640e8c47f8a5..000000000000 --- a/vscode-dotty/test/extension.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -// -// Note: This example test is leveraging the Mocha test framework. -// Please refer to their documentation on https://mochajs.org/ for help. -// - -// The module 'assert' provides assertion methods from node -import * as assert from 'assert'; - -// You can import and use all API from the 'vscode' module -// as well as import your extension to test it -import * as vscode from 'vscode'; -import * as dotty from '../src/extension'; - -// Defines a Mocha test suite to group tests of similar kind together -suite("vscode-dotty tests", function () { - - // Defines a Mocha unit test - test("dummy test", function() { - assert.equal(1, 1) - }); -}); diff --git a/vscode-dotty/test/index.ts b/vscode-dotty/test/index.ts deleted file mode 100644 index 9fa2ea0d14b3..000000000000 --- a/vscode-dotty/test/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -// -// PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING -// -// This file is providing the test runner to use when running extension tests. -// By default the test runner in use is Mocha based. -// -// You can provide your own test runner if you want to override it by exporting -// a function run(testRoot: string, clb: (error:Error) => void) that the extension -// host can call to run the tests. The test runner is expected to use console.log -// to report the results back to the caller. When the tests are finished, return -// a possible error to the callback or null if none. - -import * as testRunner from 'vscode/lib/testrunner'; - -// You can directly control Mocha options by uncommenting the following lines -// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info -testRunner.configure({ - ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) - useColors: true // colored output from test results -}); - -module.exports = testRunner; \ No newline at end of file diff --git a/vscode-dotty/tsconfig.json b/vscode-dotty/tsconfig.json deleted file mode 100644 index 0eb0d1febc98..000000000000 --- a/vscode-dotty/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "target": "es6", - "outDir": "out", - "lib": [ - "es6" - ], - "sourceMap": true, - "rootDir": ".", - "strict": true - }, - "exclude": [ - "node_modules", - ".vscode-test" - ] -}