diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..a4de243
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,9 @@
+* text=auto
+
+*.lua eol=lf
+*.ligo eol=lf
+*.mligo eol=lf
+*.jsligo eol=lf
+*.religo eol=lf
+*.hjson eol=lf
+*.json eol=lf
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8bf301a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,18 @@
+# ami & eli definitions
+__tea/.ami-definitions/eli/*
+!__tea/.ami-definitions/eli/.gitkeep
+__tea/.ami-definitions/ami/*
+!__tea/.ami-definitions/ami/.gitkeep
+__tea/bin/*
+!__tea/bin/.gitkeep
+
+# ligo
+**/.ligo-work
+
+# build
+build/*
+!build/.gitkeep
+
+# deploy
+deploy/*
+!deploy/.gitkeep
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..63df3f0
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,88 @@
+{
+ "Lua.runtime.version": "Lua 5.4",
+ "Lua.misc.parameters": [ "--preview" ],
+ "Lua.workspace.library": [
+ "./__tea/.ami-definitions/eli",
+ "./__tea/.ami-definitions/ami"
+ ],
+ "Lua.diagnostics.globals": [
+ "cli",
+ "env",
+ "fs",
+ "hash",
+ "Logger",
+ "lz",
+ "net",
+ "path",
+ "proc",
+ "tar",
+ "util",
+ "ver",
+ "zip",
+
+ "am",
+ "hjson",
+
+ "log_success",
+ "log_trace",
+ "log_debug",
+ "log_info",
+ "log_warn",
+ "log_error",
+ "ami_error",
+ "ami_assert",
+
+ "PLUGIN_IN_MEM_CACHE",
+ "GLOBAL_LOGGER",
+
+ "EXIT_SETUP_ERROR",
+ "EXIT_NOT_INSTALLED",
+ "EXIT_NOT_IMPLEMENTED",
+ "EXIT_MISSING_API",
+ "EXIT_ELEVATION_REQUIRED",
+ "EXIT_SETUP_REQUIRED",
+ "EXIT_UNSUPPORTED_PLATFORM",
+ "EXIT_MISSING_PERMISSION",
+ "EXIT_INVALID_ELI_VERSION",
+ "EXIT_AMI_UPDATE_REQUIRED",
+ "EXIT_INVALID_CONFIGURATION",
+ "EXIT_INVALID_AMI_VERSION",
+ "EXIT_INVALID_AMI_BASE_INTERFACE",
+ "EXIT_APP_INVALID_MODEL",
+ "EXIT_APP_DOWNLOAD_ERROR",
+ "EXIT_APP_IO_ERROR",
+ "EXIT_APP_UN_ERROR",
+ "EXIT_APP_CONFIGURE_ERROR",
+ "EXIT_APP_START_ERROR",
+ "EXIT_APP_STOP_ERROR",
+ "EXIT_APP_INFO_ERROR",
+ "EXIT_APP_ABOUT_ERROR",
+ "EXIT_APP_INTERNAL_ERROR",
+ "EXIT_APP_UPDATE_ERROR",
+ "EXIT_CLI_SCHEME_MISSING",
+ "EXIT_CLI_ACTION_MISSING",
+ "EXIT_CLI_ARG_VALIDATION_ERROR",
+ "EXIT_CLI_INVALID_VALUE",
+ "EXIT_CLI_INVALID_DEFINITION",
+ "EXIT_CLI_CMD_UNKNOWN",
+ "EXIT_CLI_OPTION_UNKNOWN",
+ "EXIT_RM_ERROR",
+ "EXIT_RM_DATA_ERROR",
+ "EXIT_TPL_READ_ERROR",
+ "EXIT_TPL_WRITE_ERROR",
+ "EXIT_PLUGIN_DOWNLOAD_ERROR",
+ "EXIT_PLUGIN_INVALID_DEFINITION",
+ "EXIT_PLUGIN_LOAD_ERROR",
+ "EXIT_PLUGIN_EXEC_ERROR",
+ "EXIT_PKG_DOWNLOAD_ERROR",
+ "EXIT_PKG_INVALID_DEFINITION",
+ "EXIT_PKG_INVALID_VERSION",
+ "EXIT_PKG_INVALID_TYPE",
+ "EXIT_PKG_INTEGRITY_CHECK_ERROR",
+ "EXIT_PKG_LOAD_ERROR",
+ "EXIT_PKG_LAYER_EXTRACT_ERROR",
+ "EXIT_PKG_MODEL_GENERATION_ERROR",
+ "EXIT_INVALID_SOURCES_FILE",
+ "EXIT_UNKNOWN_ERROR"
+ ]
+}
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..92b14ed
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 alis.is
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/__tea/.ami-definitions/ami/.gitkeep b/__tea/.ami-definitions/ami/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/__tea/.ami-definitions/download-dev-metas.lua b/__tea/.ami-definitions/download-dev-metas.lua
new file mode 100644
index 0000000..9ce3ca8
--- /dev/null
+++ b/__tea/.ami-definitions/download-dev-metas.lua
@@ -0,0 +1,15 @@
+local _metaStore = "__tea/.ami-definitions/"
+local _eliMetaZip = _metaStore .. "eli/meta.zip"
+local _amiMetaZip = _metaStore .. "ami/meta.zip"
+
+log_info("Downloading metas...")
+net.download_file("https://github.com/alis-is/eli/releases/latest/download/meta.zip", _eliMetaZip,
+ { followRedirects = true })
+net.download_file("https://github.com/alis-is/ami/releases/latest/download/meta.zip", _amiMetaZip,
+ { followRedirects = true })
+
+log_info("Extracting metas...")
+zip.extract(_eliMetaZip, _metaStore .. "eli", { flattenRootDir = true })
+zip.extract(_amiMetaZip, _metaStore .. "ami", { flattenRootDir = true })
+
+log_success("eli & ami definitions downloaded")
diff --git a/__tea/.ami-definitions/eli/.gitkeep b/__tea/.ami-definitions/eli/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/__tea/.cmd/setup.lua b/__tea/.cmd/setup.lua
new file mode 100644
index 0000000..84e8eb3
--- /dev/null
+++ b/__tea/.cmd/setup.lua
@@ -0,0 +1,46 @@
+local _computed = require "__tea.common.computed"
+
+if type(_computed.CONTAINER_ENGINE) ~= "string" then
+ log_warn("Failed to detect container engine! You need one to be able to run sandbox.")
+ log_info("HINT: For docker see https://docs.docker.com/compose/gettingstarted/")
+ log_info("HINT: For podman see https://podman.io/getting-started/installation")
+else
+ log_info(_computed.CONTAINER_ENGINE .. " detected.")
+end
+
+if _computed.USE_LIGO_CONTAINER then
+ log_info("'image' in ligo configuration detected. Static ligo binary won't be downloaded.")
+else
+ -- download ligo
+ local _ligoVersion = am.app.get_configuration({ "ligo", "version" }, "latest")
+ log_info("Searching " .. _ligoVersion .. " ligo binary...")
+ -- 12294987 ligo project ID
+ local _releasesUrl = "https://gitlab.com/api/v4/projects/12294987/releases/" ..
+ (_ligoVersion == "latest" and "" or _ligoVersion)
+ local _releaseInfo = net.download_string(_releasesUrl)
+ if not _releaseInfo then return ami_error("Failed to obtain ligo release info from gitlab.") end
+ local _releases = hjson.parse(_releaseInfo)
+ local _latest
+ if _ligoVersion == "latest" then
+ _latest = _releases[1] -- lua indexes from 1 ;)
+ else
+ _latest = _releases
+ end
+
+ local _links = _latest.assets.links
+ local _pattern = ("Static Linux binary"):gsub('(%a)', function(v) return '[' .. v:lower() .. v:upper() .. ']' end)
+ local _ligoUrl
+ for _, link in ipairs(_links) do
+ if link.name:match(_pattern) then
+ _ligoUrl = link.url
+ break
+ end
+ end
+ ami_assert(_ligoUrl,
+ "Failed to get static linux binary URL!\nPlease try to specify LIGO_VERSION in configuration section of your app.hjson.")
+ local _ligoDestination = "__tea/bin/ligo"
+ log_info("Downloading " .. _latest.tag_name .. " ligo binary...")
+ net.download_file(_ligoUrl, "__tea/bin/ligo", { showDefaultProgress = 10 })
+ fs.chmod(_ligoDestination, 755)
+ log_success("ligo binary downloaded")
+end
diff --git a/__tea/assets/logo.svg b/__tea/assets/logo.svg
new file mode 100644
index 0000000..c71f835
--- /dev/null
+++ b/__tea/assets/logo.svg
@@ -0,0 +1,8 @@
+
diff --git a/__tea/bin/.gitkeep b/__tea/bin/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/__tea/common/computed.lua b/__tea/common/computed.lua
new file mode 100644
index 0000000..49cdd12
--- /dev/null
+++ b/__tea/common/computed.lua
@@ -0,0 +1,84 @@
+-- containers
+local function _get_container_engine()
+ local _prefers = am.app.get_configuration({ "containers", "engine" })
+ if type(_prefers) == "string" then return _prefers end
+ -- we prefer rootless setups so podman by default
+ if os.execute "podman --version > /dev/null" then
+ return "podman"
+ end
+ if os.execute "docker --version > /dev/null" then
+ return "docker"
+ end
+ return nil
+end
+
+local _containerEngine = _get_container_engine()
+
+-- ligo
+local _ligoContainer = type(am.app.get_configuration({ "ligo", "image" })) == "string"
+local _protocol = am.app.get_configuration({ "ligo", "protocol" })
+local _syntax = am.app.get_configuration({ "ligo", "syntax" }, "cameligo")
+local function _get_ligo_cmd()
+ if _ligoContainer then
+ return string.interpolate('${ENGINE} run --rm -v "$PWD":"$PWD" -w "$PWD" ${IMAGE}', {
+ ENGINE = _containerEngine,
+ IMAGE = _ligoContainer
+ })
+ end
+ return "./__tea/bin/ligo"
+end
+
+local function _find_file(dir, name)
+ local _candidates = fs.read_dir(dir, { returnFullPaths = true, asDirEntries = true })
+ for _, candidate in ipairs(_candidates) do
+ if string.match(candidate:name(), "^" .. name) then
+ return candidate:fullpath()
+ end
+ end
+ return "src/contract.mligo"
+end
+
+local _deploys = am.app.get_configuration("deploys", {})
+for _, v in pairs(_deploys) do
+ v.INITIAL_STORAGE_ARGS = am.app.get_configuration({ "ligo", "initial-storage-args" },
+ "(${admin-addr}: address), ${metadata}")
+end
+
+return {
+ ID = am.app.get("id", "tea-contract"),
+ USE_LIGO_CONTAINER = _ligoContainer,
+ CONTAINER_ENGINE = _containerEngine,
+ SANDBOX_VARS = {
+ ENGINE = _containerEngine,
+ NAME = am.app.get_configuration({ "sandbox", "name" }, "snadbox-" .. am.app.get("id", "tezos")),
+ IMAGE = am.app.get_configuration({ "sandbox", "image" }, "oxheadalpha/flextesa:latest"),
+ SCRIPT = am.app.get_configuration({ "sandbox", "script" }, "kathmandubox"),
+ RPC_PORT = am.app.get_configuration({ "sandbox", "rpc_port" }, "20000")
+ },
+ LIGO_VARS = {
+ LIGO = _get_ligo_cmd(),
+ CONTRACT_ID = am.app.get("id", "tea-contract"),
+ FILE = am.app.get_configuration({ "ligo", "contract-file" }, _find_file("src", "contract")),
+ ENTRYPOINT = am.app.get_configuration({ "ligo", "contract-entrypoint" }, "main"),
+ PROTOCOL = _protocol,
+ PROTOCOL_ARG = _protocol and "--protocol " .. _protocol or "",
+ SYNTAX = _syntax,
+ SYNTAX_ARG = "--syntax " .. _syntax,
+ BUILD_DIR = am.app.get_configuration({ "ligo", "build-directory" }, "build"),
+ },
+ DEPLOYS = _deploys,
+ COMPILE = {
+ TZ = am.app.get_configuration({ "compile", "tz" }, true),
+ JSON = am.app.get_configuration({ "compile", "json" }, true),
+ },
+ TEST_VARS = {
+ ROOT = am.app.get_configuration({ "tests", "root" }, _find_file("tests", "all"))
+ },
+ METADATA_VARS = {
+ SOURCE = am.app.get_configuration({ "metadata", "source" }, "src/metadata.hjson"),
+ OFFCHAIN_VIEWS = am.app.get_configuration({ "metadata", "offchain-views" }, "src/offchain-views.hjson"),
+ INDENT = am.app.get_configuration({ "metadata", "indent" }, false),
+ OFFCHAIN_VIEW_EXP_SUFFIX = am.app.get_configuration({ "metadata", "offchain-view-expression-suffix" },
+ "_off_chain_view")
+ }
+}
diff --git a/__tea/common/load-config.lua b/__tea/common/load-config.lua
new file mode 100644
index 0000000..2962ac3
--- /dev/null
+++ b/__tea/common/load-config.lua
@@ -0,0 +1,19 @@
+log_success, log_info = util.global_log_factory("eli", "success", "info")
+
+local _configuration = require"hjson".parse(fs.read_file("src/config.hjson"))
+for k, v in pairs(_configuration) do
+ _G[k] = v
+end
+
+local _offChainViews = require"hjson".parse(fs.read_file("src/offchain-views.hjson"))
+local _contractMetadata = require"hjson".parse(fs.read_file("src/metadata.hjson"))
+
+_G.configuration = _configuration
+_G.CONTRACT_METADATA = _contractMetadata
+_G.OFFCHAIN_VIEWS = _offChainViews
+
+return {
+ configuration = _configuration,
+ offchainViews = _offChainViews,
+ contractMetadata = _contractMetadata
+}
\ No newline at end of file
diff --git a/__tea/tools/compile/contract.lua b/__tea/tools/compile/contract.lua
new file mode 100644
index 0000000..bbe65b5
--- /dev/null
+++ b/__tea/tools/compile/contract.lua
@@ -0,0 +1,22 @@
+local _computed = require "__tea.common.computed"
+
+local _cmd = _computed.LIGO_VARS.LIGO .. " compile contract ${FILE} --entry-point ${ENTRYPOINT}" ..
+ " --michelson-format ${FORMAT} --output-file ${BUILD_DIR}/${CONTRACT_ID}${SUFFIX} ${PROTOCOL_ARG} ${SYNTAX_ARG}"
+
+if _computed.COMPILE.TZ then
+ log_info("Compiling contract to ${ID}.tz...", _computed)
+ local _ok = os.execute(string.interpolate(_cmd, util.merge_tables(_computed.LIGO_VARS, {
+ FORMAT = "text",
+ SUFFIX = ".tz"
+ })))
+ ami_assert(_ok, string.interpolate("Failed to compile contract ${ID}.tz", _computed))
+end
+
+if _computed.COMPILE.JSON then
+ log_info("Compiling contract to ${ID}.json...", _computed)
+ local _ok = os.execute(string.interpolate(_cmd, util.merge_tables(_computed.LIGO_VARS, {
+ FORMAT = "json",
+ SUFFIX = ".json"
+ })))
+ ami_assert(_ok, string.interpolate("Failed to compile contract ${ID}.json", _computed))
+end
diff --git a/__tea/tools/compile/metadata.lua b/__tea/tools/compile/metadata.lua
new file mode 100644
index 0000000..22fa5d6
--- /dev/null
+++ b/__tea/tools/compile/metadata.lua
@@ -0,0 +1,34 @@
+local _computed = require "__tea.common.computed"
+
+local _ok, _metadataFile = fs.safe_read_file(_computed.METADATA_VARS.SOURCE)
+ami_assert(_ok, string.interpolate("Failed to load metadata from ${SOURCE}!", _computed.METADATA_VARS))
+local _ok, _metadata = hjson.safe_parse(_metadataFile)
+ami_assert(_ok, string.interpolate("Failed to parse metadata (source: ${SOURCE})!", _computed.METADATA_VARS))
+
+local _ok, _ocViewsFile = fs.safe_read_file(_computed.METADATA_VARS.OFFCHAIN_VIEWS)
+if _ok then
+ local _ok, _ocViews = hjson.safe_parse(_ocViewsFile)
+ if _ok then
+ local _readyOcViews = {}
+ local _vars = util.merge_tables(_computed.LIGO_VARS, _computed.METADATA_VARS, true)
+ local _cmd = _computed.LIGO_VARS.LIGO .. " compile expression" ..
+ ' ${SYNTAX} ${name}${OFFCHAIN_VIEW_EXP_SUFFIX} --init-file ${FILE} --michelson-format json ${PROTOCOL_ARG}'
+
+ for _, v in ipairs(_ocViews) do
+ log_info("Compiling offchain view '${name}'...", v)
+ local _result = proc.exec(string.interpolate(_cmd, util.merge_tables(_vars, v, true)), { stdout = "pipe" })
+ ami_assert(_result.exitcode == 0, string.interpolate("Failed to compile ${name}!", v))
+ local _code = hjson.parse(_result.stdoutStream:read("a"))
+ local _ocv = util.clone(v, true)
+ _ocv.implementations[1].michelsonStorageView.code = _code
+ table.insert(_readyOcViews, _ocv)
+ end
+ _metadata.views = _readyOcViews
+ else
+ log_warn("Failed to parse offchain views definition. Offchain views wont be included in the metadata!")
+ end
+else
+ log_warn("Failed to load offchain views definition. Offchain views wont be included in the metadata!")
+end
+
+fs.write_file("build/metadata.json", hjson.stringify_to_json(_metadata, { indent = _computed.METADATA_VARS.INDENT and "\t", sortKeys = true }))
\ No newline at end of file
diff --git a/__tea/tools/compile/storage.lua b/__tea/tools/compile/storage.lua
new file mode 100644
index 0000000..63c284a
--- /dev/null
+++ b/__tea/tools/compile/storage.lua
@@ -0,0 +1,44 @@
+local _computed = require "__tea.common.computed"
+
+local _cmd = _computed.LIGO_VARS.LIGO ..
+ " compile storage ${FILE} 'generate_initial_storage(${INITIAL_STORAGE_ARGS})'" ..
+ " --michelson-format \\${FORMAT} --output-file ${BUILD_DIR}/${DEPLOY}-storage-${CONTRACT_ID}\\${SUFFIX} ${PROTOCOL_ARG} ${SYNTAX_ARG}"
+
+function string.tohex(str)
+ return (str:gsub('.', function (c)
+ return string.format('%02x', string.byte(c))
+ end))
+end
+
+for id, vars in pairs(_computed.DEPLOYS) do
+ local _ok, _metadata = fs.safe_read_file("build/metadata.json")
+ if not _ok then
+ log_warn("Failed to read metadata from 'build/metadata.json'! ('metadata' argument wont be available during initial storage generation)")
+ end
+ _metadata = "0x" .. string.tohex(_metadata) -- get hex
+ vars = util.merge_tables(_computed.LIGO_VARS, vars, true)
+ vars = util.merge_tables(vars, { DEPLOY = id, metadata = _ok and _metadata or nil --[[requires 2 pass]] }, true)
+ -- first pass - replace common
+ _cmd = string.interpolate(_cmd, vars)
+ if _computed.COMPILE.TZ then
+ local _vars = util.merge_tables(vars, {
+ FORMAT = "text",
+ SUFFIX = ".tz",
+ })
+ log_info("Compiling initial storage tz for ${DEPLOY}...", _vars)
+ local _ok = os.execute(string.interpolate(_cmd, _vars))
+ ami_assert(_ok,
+ string.interpolate("Failed to compile contract ${BUILD_DIR}/${DEPLOY}-storage-${CONTRACT_ID}.tz", _vars))
+ end
+
+ if _computed.COMPILE.JSON then
+ local _vars = util.merge_tables(vars, {
+ FORMAT = "json",
+ SUFFIX = ".json",
+ })
+ log_info("Compiling initial storage json for ${DEPLOY}...", _vars)
+ local _ok = os.execute(string.interpolate(_cmd, _vars))
+ ami_assert(_ok,
+ string.interpolate("Failed to compile contract ${BUILD_DIR}/${DEPLOY}-storage-${CONTRACT_ID}.tz", _computed))
+ end
+end
diff --git a/__tea/tools/deploy/deploy.lua b/__tea/tools/deploy/deploy.lua
new file mode 100644
index 0000000..af541c2
--- /dev/null
+++ b/__tea/tools/deploy/deploy.lua
@@ -0,0 +1,48 @@
+local _args = table.pack(...)
+local _deployArgs = {}
+local _force = false
+for _, v in ipairs(_args) do
+ if v == "--force" then
+ _force = true
+ goto CONTINUE
+ end
+ table.insert(_deployArgs, v)
+ ::CONTINUE::
+end
+
+local _computed = require("__tea.common.computed")
+
+local _deploys = am.app.get_configuration("deploys", {})
+ami_assert(type(_deploys) == "table" and #table.keys(_deploys) > 0, "No deploys found")
+
+local _matched = false
+for _, id in ipairs(_deployArgs) do
+ local _deployConfig = _deploys[id]
+ if _deployConfig == nil then
+ log_warn("Deploy ${ID} not found!", { ID = id })
+ goto CONTINUE
+ end
+ _matched = true
+ local _ok, _deployer = pcall(require, "__tea.tools.deploy.plugin." .. _deployConfig.kind)
+ if not _ok then
+ log_warn("Failed to load deployer - ${DEPLOYER} - for deployment '${ID}'!", { ID = id, DEPLOYER = _deployConfig.kind })
+ goto CONTINUE
+ end
+ if type(_deployer) ~= "function" then
+ log_warn("Invalid deployer - ${DEPLOYER} (expected function, got: ${TYPE}) - of deployment '${ID}'!",
+ { ID = id, DEPLOYER = _deployConfig.kind, TYPE = type(_deployer) })
+ goto CONTINUE
+ end
+ log_info("Deploying ${ID} with ${DEPLOYER}", { ID = id, DEPLOYER = _deployConfig.kind })
+ local _ok, _err = pcall(_deployer, util.merge_tables(_deployConfig, {
+ DEPLOYMENT_ID = id,
+ ID = _computed.ID,
+ FORCE = _force
+ }, true))
+ ami_assert(_ok, "Failed to deploy - " .. id .. "! (" .. tostring(_err) .. ")")
+ log_success("${ID} deployed.", { ID = id })
+ ::CONTINUE::
+end
+if not _matched then
+ log_warn("No deploys matched!")
+end
diff --git a/__tea/tools/deploy/plugin/sandbox-tezos-client.lua b/__tea/tools/deploy/plugin/sandbox-tezos-client.lua
new file mode 100644
index 0000000..37359fd
--- /dev/null
+++ b/__tea/tools/deploy/plugin/sandbox-tezos-client.lua
@@ -0,0 +1,27 @@
+local _computed = require("__tea.common.computed")
+
+local _deployCmd = "${ENGINE} exec -it ${NAME} ${TEZOS_CLIENT_PATH}" ..
+ " originate contract ${CONTRACT_ID} transferring 0 from ${SOURCE} running " ..
+ "'${CONTRACT_CODE}' --init '${INITIAL_STORAGE}' --burn-cap ${BURN_CAP} --force"
+local _checkCmd = "${ENGINE} exec -it ${NAME} ${TEZOS_CLIENT_PATH}" ..
+ " show known contract ${CONTRACT_ID}"
+
+return function(options)
+ local _vars = util.merge_tables(_computed.SANDBOX_VARS, {
+ TEZOS_CLIENT_PATH = options.path or "tezos-client",
+ BURN_CAP = options["burn-cap"] or "10",
+ CONTRACT_ID = _computed.ID,
+ SOURCE = options.source,
+ CONTRACT_CODE = string.trim(fs.read_file(string.interpolate("build/${ID}.tz", options))),
+ INITIAL_STORAGE = string.trim(fs.read_file(string.interpolate("build/${DEPLOYMENT_ID}-storage-${ID}.tz", options)))
+ }, true)
+
+ local _ok, _, _code = os.execute(string.interpolate(_deployCmd, _vars))
+ if not _ok then error("exit code " .. tostring(_code)) end
+
+ local _result = proc.exec(string.interpolate(_checkCmd, _vars), { stdout = "pipe" })
+ if _result.exitcode ~= 0 then error("failed to get deployed contract address") end
+ local _deployFile = string.interpolate("deploy/${DEPLOYMENT_ID}-${ID}.json", options)
+ local _contractAddress = string.trim(_result.stdoutStream:read("a"))
+ if not fs.safe_write_file(_deployFile, hjson.stringify_to_json({ contractAddress = _contractAddress})) then error("failed to save contract address to ") end
+end
\ No newline at end of file
diff --git a/__tea/tools/deploy/plugin/taquito.lua b/__tea/tools/deploy/plugin/taquito.lua
new file mode 100644
index 0000000..330276f
--- /dev/null
+++ b/__tea/tools/deploy/plugin/taquito.lua
@@ -0,0 +1 @@
+error("not implemented")
\ No newline at end of file
diff --git a/__tea/tools/deploy/plugin/tezos-client.lua b/__tea/tools/deploy/plugin/tezos-client.lua
new file mode 100644
index 0000000..404c969
--- /dev/null
+++ b/__tea/tools/deploy/plugin/tezos-client.lua
@@ -0,0 +1,27 @@
+local _computed = require("__tea.common.computed")
+
+local _deployCmd = "${TEZOS_CLIENT_PATH}" ..
+ " originate contract ${CONTRACT_ID} transferring 0 from ${SOURCE} running " ..
+ "'${CONTRACT_CODE}' --init '${INITIAL_STORAGE}' --burn-cap ${BURN_CAP} --force"
+local _checkCmd = "${TEZOS_CLIENT_PATH}" ..
+ " show known contract ${CONTRACT_ID}"
+
+return function(options)
+ local _vars = util.merge_tables(_computed.SANDBOX_VARS, {
+ TEZOS_CLIENT_PATH = options.path or "tezos-client",
+ BURN_CAP = options["burn-cap"] or "10",
+ CONTRACT_ID = _computed.ID,
+ SOURCE = options.source,
+ CONTRACT_CODE = string.trim(fs.read_file(string.interpolate("build/${ID}.tz", options))),
+ INITIAL_STORAGE = string.trim(fs.read_file(string.interpolate("build/${DEPLOYMENT_ID}-storage-${ID}.tz", options)))
+ }, true)
+
+ local _ok, _, _code = os.execute(string.interpolate(_deployCmd, _vars))
+ if not _ok then error("exit code " .. tostring(_code)) end
+
+ local _result = proc.exec(string.interpolate(_checkCmd, _vars), { stdout = "pipe" })
+ if _result.exitcode ~= 0 then error("failed to get deployed contract address") end
+ local _deployFile = string.interpolate("deploy/${DEPLOYMENT_ID}-${ID}.json", options)
+ local _contractAddress = string.trim(_result.stdoutStream:read("a"))
+ if not fs.safe_write_file(_deployFile, hjson.stringify_to_json({ contractAddress = _contractAddress })) then error("failed to save contract address to ") end
+end
diff --git a/__tea/tools/sandbox/start.lua b/__tea/tools/sandbox/start.lua
new file mode 100644
index 0000000..770c47a
--- /dev/null
+++ b/__tea/tools/sandbox/start.lua
@@ -0,0 +1,6 @@
+local _computed = require("__tea.common.computed")
+
+local _cmd = string.interpolate("${ENGINE} run --rm --name ${NAME} --detach -p ${RPC_PORT}:20000 -e block_time=5" ..
+" ${IMAGE} ${SCRIPT} start", _computed.SANDBOX_VARS)
+
+ami_assert(os.execute(_cmd), "Failed to start sandbox!")
\ No newline at end of file
diff --git a/__tea/tools/sandbox/stop.lua b/__tea/tools/sandbox/stop.lua
new file mode 100644
index 0000000..9633b5e
--- /dev/null
+++ b/__tea/tools/sandbox/stop.lua
@@ -0,0 +1,5 @@
+local _computed = require("__tea.common.computed")
+
+local _cmd = string.interpolate("${ENGINE} stop ${NAME}", _computed.SANDBOX_VARS)
+
+ami_assert(os.execute(_cmd), "Failed to stop sandbox!")
\ No newline at end of file
diff --git a/__tea/tools/tests/js.lua b/__tea/tools/tests/js.lua
new file mode 100644
index 0000000..9d2f90b
--- /dev/null
+++ b/__tea/tools/tests/js.lua
@@ -0,0 +1,6 @@
+local _args = table.pack(...)
+
+local _cmd = #_args == 0 and "npm run test" or "npm run test-selection"
+os.chdir("web")
+os.execute(string.join(" ", _cmd, ...))
+os.chdir("..")
\ No newline at end of file
diff --git a/__tea/tools/tests/ligo.lua b/__tea/tools/tests/ligo.lua
new file mode 100644
index 0000000..e64f5ff
--- /dev/null
+++ b/__tea/tools/tests/ligo.lua
@@ -0,0 +1,5 @@
+local _computed = require "__tea.common.computed"
+
+local _cmd = _computed.LIGO_VARS.LIGO .. " run test ${ROOT}"
+os.execute(string.interpolate(_cmd, _computed.TEST_VARS))
+-- ligo reports failure on its own
\ No newline at end of file
diff --git a/ami.lua b/ami.lua
new file mode 100644
index 0000000..d574d98
--- /dev/null
+++ b/ami.lua
@@ -0,0 +1,104 @@
+return {
+ title = "TEA",
+ base = "base",
+ commands = {
+ setup = {
+ description = "TEA 'setup' sub command",
+ summary = "Downloads latest ligo library and required dependencies for TEA operation",
+ action = "__tea/.cmd/setup.lua",
+ contextFailExitCode = EXIT_SETUP_ERROR
+ },
+ compile = {
+ description = "TEA 'compile' sub command",
+ summary = 'Runs all compile stages',
+ options = {
+ clean = { description = "Clean build directory before compilation" },
+ contract = { description = "Compiles contract to tz and json" },
+ storage = { description = "Compiles initial contract storage" },
+ metadata = { description = "Generates contract metadata" },
+ jsmodule = { description = "Compiles js module" }
+ },
+ action = function(_options, _, _, _)
+ local _noOptions = #table.keys(_options) == 0
+ if _noOptions or _options.clean then
+ local _entries = fs.read_dir("build", { returnFullPaths = true }) --[=[@as string[]]=]
+ _entries = util.merge_arrays(_entries, fs.read_dir("web/dist", { returnFullPaths = true }) --[=[@as string[]]=]) --[=[@as string[]]=]
+ for _, _entry in ipairs(_entries) do
+ if not _entry:match(".gitkeep$") then
+ fs.remove(_entry --[[@as string]], { recurse = true })
+ end
+ end
+ end
+
+ if _noOptions or _options.contract then
+ am.execute_extension("__tea/tools/compile/contract.lua", { contextFailExitCode = EXIT_APP_INTERNAL_ERROR })
+ end
+
+ if _noOptions or _options.metadata then
+ am.execute_extension("__tea/tools/compile/metadata.lua", { contextFailExitCode = EXIT_APP_INTERNAL_ERROR })
+ end
+
+ if _noOptions or _options.storage then
+ am.execute_extension("__tea/tools/compile/storage.lua", { contextFailExitCode = EXIT_APP_INTERNAL_ERROR })
+ end
+
+ if _noOptions or _options.jsmodule then
+ os.chdir("web")
+ am.execute_external("npm", { "run", "build" })
+ os.chdir("..")
+ end
+ log_success("compilation stage complete.")
+ end,
+ contextFailExitCode = EXIT_APP_INTERNAL_ERROR
+ },
+ deploy = {
+ description = "TEA 'deploy' sub command",
+ summary = "Deploys compiled smart contract",
+ type = "raw",
+ contextFailExitCode = EXIT_APP_START_ERROR,
+ action = "__tea/tools/deploy/deploy.lua"
+ },
+ sandbox = {
+ title = "TEA - sandbox",
+ description = "TEA 'sandbox' control",
+ summary = "Provides ability to control sandbox",
+ commands = {
+ start = {
+ description = "TEA 'start-sandbox' sub command",
+ summary = "Starts tezos sandbox",
+ action = "__tea/tools/sandbox/start.lua",
+ contextFailExitCode = EXIT_APP_INTERNAL_ERROR
+ },
+ stop = {
+ description = "TEA 'stop-sandbox' sub command",
+ summary = "Stops tezos sandbox",
+ action = "__tea/tools/sandbox/stop.lua",
+ contextFailExitCode = EXIT_APP_INTERNAL_ERROR
+ }
+ },
+ action = function(_, _command, _args, _cli)
+ if not _command then am.print_help(_cli, {}); return end
+ am.execute(_command, _args)
+ end
+ },
+ test = {
+ description = "TEA 'test' sub command",
+ summary = "Runs ligo tests",
+ action = "__tea/tools/tests/ligo.lua",
+ contextFailExitCode = EXIT_APP_INTERNAL_ERROR
+ },
+ ["test-js"] = {
+ description = "TEA 'test-js' sub command",
+ summary = "Runs ligo tests",
+ action = "__tea/tools/tests/js.lua",
+ type = "raw",
+ contextFailExitCode = EXIT_APP_INTERNAL_ERROR
+ },
+ ["download-dev-metas"] = {
+ hidden = true,
+ summary = "Downloads ami definitions for autocompletion in TEA development",
+ action = "__tea/.ami-definitions/download-dev-metas.lua",
+ contextFailExitCode = EXIT_APP_INTERNAL_ERROR
+ }
+ }
+}
diff --git a/app.hjson b/app.hjson
new file mode 100644
index 0000000..ab269a6
--- /dev/null
+++ b/app.hjson
@@ -0,0 +1,60 @@
+id: tea-contract-template
+type: standalone
+configuration: {
+ deploys: {
+ sandbox: {
+ // alice key from sandbox
+ admin-addr: '"tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb"'
+ kind: sandbox-tezos-client
+ // path: tezos-client
+ source: alice
+ burn-cap: 5
+
+ // requires installed tezos-client
+ // kind: tezos-client
+ // // path: tezos-client
+ // source: alice
+ // burn-cap: 5
+
+ // requires installed js modules
+ // kind: taquito
+ // rpc:
+ // // path: tezos-client
+ // source: edsk3RFfvaFaxbHx8BMtEW1rKQcPtDML3LXjNqMNLCzC3wLC1bWbAt
+ }
+ }
+ ligo: {
+ version: latest
+ // or exact
+ // version: 0.50.0
+ // or container
+ // image: ligolang/ligo:0.49.0
+ protocol: kathmandu
+ // initial-storage-args: (${admin-addr}: address), ${metadata}
+ }
+ sandbox: {
+ // name: tezos-sandbox
+ // defaults to `sandbox-${id}`
+ image: oxheadalpha/flextesa:20220715
+ script: kathmandubox
+ // rpc_port: 20000
+ }
+ metadata: {
+ // source: src/metadata.hjson
+ // offchain-views: src/offchain-views.hjson
+ // indent: false
+ // offchain-view-expression-suffix: _off_chain_view
+ }
+ compile: {
+ //tz: true
+ //json: true
+ }
+ tests: {
+ // root: by default looks up all.* in tests directory
+ // root: tests/all.mligo
+ }
+ // usually autodetected
+ // containers: {
+ // engine: docker
+ // }
+}
diff --git a/build/.gitkeep b/build/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/deploy/.gitkeep b/deploy/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..6605e53
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,73 @@
+# TEA
+
+
+
+
+
+
+
+TEA is small, adaptable and **self contained** development environment for Tezos smart contracts.
+- small - dependencies of this project alone are only ~1.2MB
+- adaptable - all behavior is determined based on [app.hjson](https://github.com/alis-is/tea/blob/main/app.hjson), can be tracked down and adjusted through [ami.lua](https://github.com/alis-is/tea/blob/main/ami.lua)
+- self contained - all features as included within - adjust them anyway you like or need
+
+Start your new Tezos project faster than you prepare cup of tea. :)
+
+## What does TEA provide?
+- **ligo** compilation and tests (*SmartPy is not supported right now but with TEA adaptability you can make it to.*)
+- **taquito** based module for dapp development
+- e2e tests with taquito and sandbox
+
+## Dependencies
+- eli and ami - for `ami` commands - only ~1.2MB
+- (optional) [podman](https://podman.io/getting-started/installation) or [docker](https://docs.docker.com/engine/install/)
+- (optional) [nodejs](https://nodejs.org/en/download/) for dapp development
+- For development on windows use [wsl2](https://docs.microsoft.com/en-us/windows/wsl/install)
+
+## Get Started
+
+1. Clone repository
+ - `git clone https://github.com/alis-is/tea.git`
+2. Get `eli` and `ami` (lua engines powering tea)
+ - `wget -q https://raw.githubusercontent.com/alis-is/ami/master/install.sh -O /tmp/install.sh && sh /tmp/install.sh`
+3. Install optional dependencies if needed
+4. (optional) Edit `app.hjson` to adjust template behavior
+ - **You should set id to name of your project.** (Build and deploy commands use this id to name files)
+5. `ami setup` (Downloads ligo if needed)
+6. You are ready to code
+
+**NOTE**: *TEA is fully self contained template. No behavior is specified in outside packages or set in stone. You can adjust it however you like. Just edit behavior within `__tea` directory.* ;)
+
+## Guide
+
+TEA is operated with commands through `ami`. All commands respects your configuration within `app.hjson` and are defined within `ami.lua`
+
+TEA provides bellow commands (see `--help` of each for details):
+- `ami sandbox start` start sandbox
+- `ami sandbox stop` stop sandbox
+- `ami compile` compiles contract, initial storage and views
+- `ami deploy ` deploys deploy or multiple based on id
+- `ami test` runs ligo tests (stored in `tests`)
+- `ami test-js` runs web module tests (stored in `web/tests`)
+ - *requires started sandbox*
+ - `ami test-js tests/admin.specs.js` runs `tests/admin.specs.js` tests
+
+## Sample workflow
+
+1. Code your contract
+2. Run `ami compile` to compile contract and storage (See `--help` for options or selective compilation)
+3. Run `ami test` to execute ligo tests
+4. Run `ami deploy ` to deploy contract to your deploys
+ - `ami deploy sandbox` to deploy to sandbox with default `app.hjson`
+5. Run `ami test-js` to test js-module
+
+## Development with VS Code
+
+1. Install [Lua extension from sumneko](https://marketplace.visualstudio.com/items?itemName=sumneko.lua)
+2. Run `ami download-dev-metas` to download meta definitions for autocomplete
+3. Adjust template as needed. Entire template codebase is scoped within `__tea` directory.
+
+## Projects using this template
+
+- [Starlords](https://starlords.xyz/)
+- [BakeBuddy](https://www.bakebuddy.xyz/)
\ No newline at end of file
diff --git a/src/.gitkeep b/src/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/src/contract.mligo b/src/contract.mligo
new file mode 100644
index 0000000..8e48ee1
--- /dev/null
+++ b/src/contract.mligo
@@ -0,0 +1,22 @@
+#include "types.mligo"
+
+// actions
+#include "core/actions.mligo"
+
+// onchain views
+#include "views/lock.mligo"
+#include "views/state.mligo"
+
+let main(action, store: action_type * storage_type): return_type =
+ match action with
+ Increment n -> add (n, store)
+ | Decrement n -> sub (n, store)
+ | SetLock l -> set_lock(l, store)
+ | Default -> ([]: operation list), store
+
+let generate_initial_storage(admin, about: address * bytes): storage_type =
+ let metadata = (Big_map.empty: contract_metadata_type) in
+ let metadata: contract_metadata_type = Big_map.update ("") (Some(Bytes.pack("tezos-storage:content"))) metadata in
+ let metadata = Big_map.update ("content") (Some(about)) metadata in
+ { state = 0; admin = admin; locked = true; metadata = metadata }
+
diff --git a/src/core/actions.mligo b/src/core/actions.mligo
new file mode 100644
index 0000000..c6f16b3
--- /dev/null
+++ b/src/core/actions.mligo
@@ -0,0 +1,10 @@
+#include "util/assert.mligo"
+#include "admin/lock.mligo"
+#include "common/increment.mligo"
+#include "common/decrement.mligo"
+
+type action_type =
+ Increment of int
+ | Decrement of int
+ | SetLock of bool
+ | [@annot:def] Default
\ No newline at end of file
diff --git a/src/core/admin/lock.mligo b/src/core/admin/lock.mligo
new file mode 100644
index 0000000..361d490
--- /dev/null
+++ b/src/core/admin/lock.mligo
@@ -0,0 +1,3 @@
+let set_lock (lockState, store: bool * storage_type): return_type =
+ let _assert = assert_admin(store) in
+ ([]: operation list), { store with locked = lockState }
\ No newline at end of file
diff --git a/src/core/common/decrement.mligo b/src/core/common/decrement.mligo
new file mode 100644
index 0000000..3883755
--- /dev/null
+++ b/src/core/common/decrement.mligo
@@ -0,0 +1,3 @@
+let sub (n, store: int * storage_type): return_type =
+ let _assert = assert_admin_or_not_locked(store) in
+ ([]: operation list), { store with state = store.state - n }
diff --git a/src/core/common/increment.mligo b/src/core/common/increment.mligo
new file mode 100644
index 0000000..b85b8e6
--- /dev/null
+++ b/src/core/common/increment.mligo
@@ -0,0 +1,3 @@
+let add (n, store: int * storage_type): return_type =
+ let _assert = assert_admin_or_not_locked(store) in
+ ([]: operation list), { store with state = store.state + n }
\ No newline at end of file
diff --git a/src/core/util/assert.mligo b/src/core/util/assert.mligo
new file mode 100644
index 0000000..2ca7668
--- /dev/null
+++ b/src/core/util/assert.mligo
@@ -0,0 +1,7 @@
+let assert_admin_or_not_locked (store: storage_type) : unit =
+ let sender = Tezos.get_sender() in
+ assert_with_error ((not store.locked) || sender = store.admin) "not admin"
+
+let assert_admin (store: storage_type): unit =
+ let sender = Tezos.get_sender() in
+ assert_with_error (sender = store.admin) "not admin"
diff --git a/src/metadata.hjson b/src/metadata.hjson
new file mode 100644
index 0000000..37041f2
--- /dev/null
+++ b/src/metadata.hjson
@@ -0,0 +1,9 @@
+name: TEA SCT
+description: TEA Smart Contract Template
+authors: [
+ V
+]
+homepage: https://github.com/alis-is/tea
+interfaces: [
+ TZIP-16-21fb73fe
+]
diff --git a/src/offchain-views.hjson b/src/offchain-views.hjson
new file mode 100644
index 0000000..0b297c8
--- /dev/null
+++ b/src/offchain-views.hjson
@@ -0,0 +1,36 @@
+[
+ {
+ name: get_state
+ description: Gets value of state
+ pure: true
+ implementations: [
+ {
+ michelsonStorageView: {
+ parameter: {
+ prim: unit
+ }
+ returnType: {
+ prim: nat
+ }
+ }
+ }
+ ]
+ }
+ {
+ name: get_lock_state
+ description: Gets value of state
+ pure: true
+ implementations: [
+ {
+ michelsonStorageView: {
+ parameter: {
+ prim: unit
+ }
+ returnType: {
+ prim: bool
+ }
+ }
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/src/types.mligo b/src/types.mligo
new file mode 100644
index 0000000..349772f
--- /dev/null
+++ b/src/types.mligo
@@ -0,0 +1,10 @@
+type contract_metadata_type = (string, bytes)big_map
+
+type storage_type = {
+ state: int;
+ admin: address;
+ locked: bool;
+ metadata: contract_metadata_type
+}
+
+type return_type = operation list * storage_type
diff --git a/src/views/lock.mligo b/src/views/lock.mligo
new file mode 100644
index 0000000..d1cd963
--- /dev/null
+++ b/src/views/lock.mligo
@@ -0,0 +1,4 @@
+[@view] let get_lock_state(_params, store: unit * storage_type): bool =
+ store.locked
+
+let get_lock_state_off_chain_view(params, store: unit * storage_type): bool = get_lock_state (params, store)
\ No newline at end of file
diff --git a/src/views/state.mligo b/src/views/state.mligo
new file mode 100644
index 0000000..68efcb4
--- /dev/null
+++ b/src/views/state.mligo
@@ -0,0 +1,4 @@
+[@view] let get_state (_params, store: unit * storage_type): int =
+ store.state
+
+let get_state_off_chain_view(params, store: unit * storage_type): int = get_state(params, store)
\ No newline at end of file
diff --git a/tests/all.mligo b/tests/all.mligo
new file mode 100644
index 0000000..38ee2b7
--- /dev/null
+++ b/tests/all.mligo
@@ -0,0 +1,46 @@
+#include "../src/contract.mligo"
+
+let test_deploy =
+ let initial_storage: storage_type = generate_initial_storage ("tz1aSkwEot3L2kmUvcoxzjMomb9mvBNuzFK6": address) in
+ let taddr, _, _ = Test.originate main initial_storage 0tez in
+ let storage = Test.get_storage taddr in
+ assert (storage.admin = initial_storage.admin && storage.state = initial_storage.state && storage.locked = initial_storage.locked)
+
+let test_add_locked_not_admin =
+ let initial_storage: storage_type = generate_initial_storage ("tz1aSkwEot3L2kmUvcoxzjMomb9mvBNuzFK6": address) in
+ let taddr, _, _ = Test.originate main initial_storage 0tez in
+ let contr = Test.to_contract taddr in
+ let result = Test.transfer_to_contract contr (Increment (1)) 0mutez in
+ let txResult = match result with
+ Fail (v) -> v
+ | Success (_v) -> failwith("should fail") in
+ let _ = match txResult with
+ Rejected (reason) ->
+ assert((Test.to_string reason.0) = "\"not admin\"")
+ | Balance_too_low(_e) -> failwith("should reject")
+ | Other(_e) -> failwith("should reject") in
+ let storage = Test.get_storage taddr in
+ assert (storage.state = initial_storage.state)
+
+let test_add_locked_admin =
+ let addr = Test.nth_bootstrap_account 0 in
+ let initial_storage: storage_type = generate_initial_storage addr in
+ let _ = Test.set_source addr in
+ let taddr, _, _ = Test.originate main initial_storage 0tez in
+ let contr = Test.to_contract taddr in
+ let _ = Test.transfer_to_contract_exn contr (Increment (1)) 0mutez in
+ let storage = Test.get_storage taddr in
+ assert (storage.state = initial_storage.state + 1)
+
+let test_add_unlocked_admin =
+ let addr = Test.nth_bootstrap_account 0 in
+ let initial_storage: storage_type = generate_initial_storage addr in
+ let _ = Test.set_source addr in
+ let taddr, _, _ = Test.originate main initial_storage 0tez in
+ let contr = Test.to_contract taddr in
+ let _ = Test.transfer_to_contract_exn contr (SetLock (false)) 0mutez in
+ let addr = Test.nth_bootstrap_account 1 in
+ let _ = Test.set_source addr in
+ let _ = Test.transfer_to_contract_exn contr (Increment (1)) 0mutez in
+ let storage = Test.get_storage taddr in
+ assert (storage.state = initial_storage.state + 1)
\ No newline at end of file
diff --git a/web/.gitignore b/web/.gitignore
new file mode 100644
index 0000000..35cbfcd
--- /dev/null
+++ b/web/.gitignore
@@ -0,0 +1,4 @@
+node_modules/*
+
+dist/*
+!dist/.gitkeep
diff --git a/web/dist/.gitkeep b/web/dist/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/web/package-lock.json b/web/package-lock.json
new file mode 100644
index 0000000..4527b0d
--- /dev/null
+++ b/web/package-lock.json
@@ -0,0 +1,2080 @@
+{
+ "name": "tea-contract-template-js",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true
+ },
+ "@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ }
+ },
+ "acorn": {
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+ "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
+ "dev": true
+ },
+ "acorn-walk": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
+ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+ "dev": true
+ },
+ "aggregate-error": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz",
+ "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==",
+ "dev": true,
+ "requires": {
+ "clean-stack": "^4.0.0",
+ "indent-string": "^5.0.0"
+ }
+ },
+ "ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.0.tgz",
+ "integrity": "sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==",
+ "dev": true
+ },
+ "anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "array-find-index": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+ "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==",
+ "dev": true
+ },
+ "array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true
+ },
+ "arrgv": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/arrgv/-/arrgv-1.0.2.tgz",
+ "integrity": "sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==",
+ "dev": true
+ },
+ "arrify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz",
+ "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==",
+ "dev": true
+ },
+ "ava": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/ava/-/ava-4.3.3.tgz",
+ "integrity": "sha512-9Egq/d9R74ExrWohHeqUlexjDbgZJX5jA1Wq4KCTqc3wIfpGEK79zVy4rBtofJ9YKIxs4PzhJ8BgbW5PlAYe6w==",
+ "dev": true,
+ "requires": {
+ "acorn": "^8.7.1",
+ "acorn-walk": "^8.2.0",
+ "ansi-styles": "^6.1.0",
+ "arrgv": "^1.0.2",
+ "arrify": "^3.0.0",
+ "callsites": "^4.0.0",
+ "cbor": "^8.1.0",
+ "chalk": "^5.0.1",
+ "chokidar": "^3.5.3",
+ "chunkd": "^2.0.1",
+ "ci-info": "^3.3.1",
+ "ci-parallel-vars": "^1.0.1",
+ "clean-yaml-object": "^0.1.0",
+ "cli-truncate": "^3.1.0",
+ "code-excerpt": "^4.0.0",
+ "common-path-prefix": "^3.0.0",
+ "concordance": "^5.0.4",
+ "currently-unhandled": "^0.4.1",
+ "debug": "^4.3.4",
+ "del": "^6.1.1",
+ "emittery": "^0.11.0",
+ "figures": "^4.0.1",
+ "globby": "^13.1.1",
+ "ignore-by-default": "^2.1.0",
+ "indent-string": "^5.0.0",
+ "is-error": "^2.2.2",
+ "is-plain-object": "^5.0.0",
+ "is-promise": "^4.0.0",
+ "matcher": "^5.0.0",
+ "mem": "^9.0.2",
+ "ms": "^2.1.3",
+ "p-event": "^5.0.1",
+ "p-map": "^5.4.0",
+ "picomatch": "^2.3.1",
+ "pkg-conf": "^4.0.0",
+ "plur": "^5.1.0",
+ "pretty-ms": "^7.0.1",
+ "resolve-cwd": "^3.0.0",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.5",
+ "strip-ansi": "^7.0.1",
+ "supertap": "^3.0.1",
+ "temp-dir": "^2.0.0",
+ "write-file-atomic": "^4.0.1",
+ "yargs": "^17.5.1"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true
+ },
+ "blueimp-md5": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz",
+ "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==",
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ }
+ },
+ "callsites": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-4.0.0.tgz",
+ "integrity": "sha512-y3jRROutgpKdz5vzEhWM34TidDU8vkJppF8dszITeb1PQmSqV3DTxyV8G/lyO/DNvtE1YTedehmw9MPZsCBHxQ==",
+ "dev": true
+ },
+ "cbor": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz",
+ "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==",
+ "dev": true,
+ "requires": {
+ "nofilter": "^3.1.0"
+ }
+ },
+ "chalk": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz",
+ "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==",
+ "dev": true
+ },
+ "chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "requires": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "fsevents": "~2.3.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ }
+ },
+ "chunkd": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz",
+ "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==",
+ "dev": true
+ },
+ "ci-info": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz",
+ "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==",
+ "dev": true
+ },
+ "ci-parallel-vars": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.1.tgz",
+ "integrity": "sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==",
+ "dev": true
+ },
+ "clean-stack": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz",
+ "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "5.0.0"
+ }
+ },
+ "clean-yaml-object": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz",
+ "integrity": "sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==",
+ "dev": true
+ },
+ "cli-truncate": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz",
+ "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==",
+ "dev": true,
+ "requires": {
+ "slice-ansi": "^5.0.0",
+ "string-width": "^5.0.0"
+ }
+ },
+ "cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ }
+ }
+ },
+ "code-excerpt": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz",
+ "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==",
+ "dev": true,
+ "requires": {
+ "convert-to-spaces": "^2.0.1"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "common-path-prefix": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz",
+ "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "concordance": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.4.tgz",
+ "integrity": "sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==",
+ "dev": true,
+ "requires": {
+ "date-time": "^3.1.0",
+ "esutils": "^2.0.3",
+ "fast-diff": "^1.2.0",
+ "js-string-escape": "^1.0.1",
+ "lodash": "^4.17.15",
+ "md5-hex": "^3.0.1",
+ "semver": "^7.3.2",
+ "well-known-symbols": "^2.0.0"
+ }
+ },
+ "convert-to-spaces": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz",
+ "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ }
+ }
+ },
+ "currently-unhandled": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+ "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==",
+ "dev": true,
+ "requires": {
+ "array-find-index": "^1.0.1"
+ }
+ },
+ "date-time": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz",
+ "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==",
+ "dev": true,
+ "requires": {
+ "time-zone": "^1.0.0"
+ }
+ },
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "define-properties": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
+ "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
+ "dev": true,
+ "requires": {
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "del": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz",
+ "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==",
+ "dev": true,
+ "requires": {
+ "globby": "^11.0.1",
+ "graceful-fs": "^4.2.4",
+ "is-glob": "^4.0.1",
+ "is-path-cwd": "^2.2.0",
+ "is-path-inside": "^3.0.2",
+ "p-map": "^4.0.0",
+ "rimraf": "^3.0.2",
+ "slash": "^3.0.0"
+ },
+ "dependencies": {
+ "aggregate-error": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+ "dev": true,
+ "requires": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ }
+ },
+ "clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "dev": true
+ },
+ "globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "requires": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ }
+ },
+ "indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true
+ },
+ "p-map": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+ "dev": true,
+ "requires": {
+ "aggregate-error": "^3.0.0"
+ }
+ }
+ }
+ },
+ "dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "requires": {
+ "path-type": "^4.0.0"
+ }
+ },
+ "eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true
+ },
+ "emittery": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.11.0.tgz",
+ "integrity": "sha512-S/7tzL6v5i+4iJd627Nhv9cLFIo5weAIlGccqJFpnBoDB8U1TF2k5tez4J/QNuxyyhWuFqHg1L84Kd3m7iXg6g==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "es-abstract": {
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.2.tgz",
+ "integrity": "sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "function.prototype.name": "^1.1.5",
+ "get-intrinsic": "^1.1.2",
+ "get-symbol-description": "^1.0.0",
+ "has": "^1.0.3",
+ "has-property-descriptors": "^1.0.0",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.3",
+ "is-callable": "^1.2.4",
+ "is-negative-zero": "^2.0.2",
+ "is-regex": "^1.1.4",
+ "is-shared-array-buffer": "^1.0.2",
+ "is-string": "^1.0.7",
+ "is-weakref": "^1.0.2",
+ "object-inspect": "^1.12.2",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.4",
+ "regexp.prototype.flags": "^1.4.3",
+ "string.prototype.trimend": "^1.0.5",
+ "string.prototype.trimstart": "^1.0.5",
+ "unbox-primitive": "^1.0.2"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+ "dev": true
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true
+ },
+ "fast-diff": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+ "dev": true
+ },
+ "fast-glob": {
+ "version": "3.2.11",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
+ "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ }
+ },
+ "fastq": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
+ "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+ "dev": true,
+ "requires": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "figures": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-4.0.1.tgz",
+ "integrity": "sha512-rElJwkA/xS04Vfg+CaZodpso7VqBknOYbzi6I76hI4X80RUjkSxO2oAyPmGbuXUppywjqndOrQDl817hDnI++w==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^5.0.0",
+ "is-unicode-supported": "^1.2.0"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "find-up": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz",
+ "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^7.1.0",
+ "path-exists": "^5.0.0"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true
+ },
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "optional": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "function.prototype.name": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
+ "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.19.0",
+ "functions-have-names": "^1.2.2"
+ }
+ },
+ "functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
+ "get-intrinsic": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+ "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.3"
+ }
+ },
+ "get-symbol-description": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
+ "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.1"
+ }
+ },
+ "glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "globby": {
+ "version": "13.1.2",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.2.tgz",
+ "integrity": "sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==",
+ "dev": true,
+ "requires": {
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.11",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^4.0.0"
+ },
+ "dependencies": {
+ "slash": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz",
+ "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==",
+ "dev": true
+ }
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-bigints": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true
+ },
+ "has-property-descriptors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+ "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+ "dev": true,
+ "requires": {
+ "get-intrinsic": "^1.1.1"
+ }
+ },
+ "has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "dev": true
+ },
+ "has-tostringtag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+ "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.2"
+ }
+ },
+ "hjson": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/hjson/-/hjson-3.2.2.tgz",
+ "integrity": "sha512-MkUeB0cTIlppeSsndgESkfFD21T2nXPRaBStLtf3cAYA2bVEFdXlodZB0TukwZiobPD1Ksax5DK4RTZeaXCI3Q==",
+ "dev": true
+ },
+ "hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "dev": true
+ },
+ "ignore": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
+ "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+ "dev": true
+ },
+ "ignore-by-default": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-2.1.0.tgz",
+ "integrity": "sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==",
+ "dev": true
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz",
+ "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "internal-slot": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
+ "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
+ "dev": true,
+ "requires": {
+ "get-intrinsic": "^1.1.0",
+ "has": "^1.0.3",
+ "side-channel": "^1.0.4"
+ }
+ },
+ "irregular-plurals": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.3.0.tgz",
+ "integrity": "sha512-MVBLKUTangM3EfRPFROhmWQQKRDsrgI83J8GS3jXy+OwYqiR2/aoWndYQ5416jLE3uaGgLH7ncme3X9y09gZ3g==",
+ "dev": true
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true
+ },
+ "is-bigint": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "dev": true,
+ "requires": {
+ "has-bigints": "^1.0.1"
+ }
+ },
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
+ "is-boolean-object": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-callable": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
+ "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==",
+ "dev": true
+ },
+ "is-core-module": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
+ "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-date-object": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+ "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-error": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz",
+ "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==",
+ "dev": true
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
+ "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-negative-zero": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+ "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "is-number-object": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+ "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-path-cwd": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
+ "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
+ "dev": true
+ },
+ "is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true
+ },
+ "is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true
+ },
+ "is-promise": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
+ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
+ "dev": true
+ },
+ "is-regex": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+ "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-shared-array-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
+ "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2"
+ }
+ },
+ "is-string": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+ "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-symbol": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+ "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.2"
+ }
+ },
+ "is-unicode-supported": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.2.0.tgz",
+ "integrity": "sha512-wH+U77omcRzevfIG8dDhTS0V9zZyweakfD01FULl97+0EHiJTTZtJqxPSkIIo/SDPv/i07k/C9jAPY+jwLLeUQ==",
+ "dev": true
+ },
+ "is-weakref": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+ "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2"
+ }
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "js-string-escape": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
+ "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true
+ },
+ "load-json-file": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-7.0.1.tgz",
+ "integrity": "sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==",
+ "dev": true
+ },
+ "locate-path": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.1.1.tgz",
+ "integrity": "sha512-vJXaRMJgRVD3+cUZs3Mncj2mxpt5mP0EmNOsxRSZRMlbqjvxzDEOIUWXGmavo0ZC9+tNZCBLQ66reA11nbpHZg==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^6.0.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "lodash-es": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+ "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "map-age-cleaner": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
+ "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
+ "dev": true,
+ "requires": {
+ "p-defer": "^1.0.0"
+ }
+ },
+ "matcher": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/matcher/-/matcher-5.0.0.tgz",
+ "integrity": "sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^5.0.0"
+ }
+ },
+ "md5-hex": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz",
+ "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==",
+ "dev": true,
+ "requires": {
+ "blueimp-md5": "^2.10.0"
+ }
+ },
+ "mem": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/mem/-/mem-9.0.2.tgz",
+ "integrity": "sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A==",
+ "dev": true,
+ "requires": {
+ "map-age-cleaner": "^0.1.3",
+ "mimic-fn": "^4.0.0"
+ }
+ },
+ "memorystream": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
+ "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==",
+ "dev": true
+ },
+ "merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ }
+ },
+ "mimic-fn": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
+ "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "nofilter": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz",
+ "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==",
+ "dev": true
+ },
+ "normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ }
+ }
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "npm-run-all": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz",
+ "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "chalk": "^2.4.1",
+ "cross-spawn": "^6.0.5",
+ "memorystream": "^0.3.1",
+ "minimatch": "^3.0.4",
+ "pidtree": "^0.3.0",
+ "read-pkg": "^3.0.0",
+ "shell-quote": "^1.6.1",
+ "string.prototype.padend": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true
+ }
+ }
+ },
+ "object-inspect": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+ "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
+ "dev": true
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true
+ },
+ "object.assign": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
+ "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "has-symbols": "^1.0.3",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "p-defer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
+ "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==",
+ "dev": true
+ },
+ "p-event": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz",
+ "integrity": "sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==",
+ "dev": true,
+ "requires": {
+ "p-timeout": "^5.0.2"
+ }
+ },
+ "p-limit": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
+ "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
+ "dev": true,
+ "requires": {
+ "yocto-queue": "^1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz",
+ "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^4.0.0"
+ }
+ },
+ "p-map": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz",
+ "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==",
+ "dev": true,
+ "requires": {
+ "aggregate-error": "^4.0.0"
+ }
+ },
+ "p-timeout": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz",
+ "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==",
+ "dev": true
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "parse-ms": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz",
+ "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz",
+ "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true
+ },
+ "pidtree": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz",
+ "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==",
+ "dev": true
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "dev": true
+ },
+ "pkg-conf": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-4.0.0.tgz",
+ "integrity": "sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==",
+ "dev": true,
+ "requires": {
+ "find-up": "^6.0.0",
+ "load-json-file": "^7.0.0"
+ }
+ },
+ "plur": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/plur/-/plur-5.1.0.tgz",
+ "integrity": "sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==",
+ "dev": true,
+ "requires": {
+ "irregular-plurals": "^3.3.0"
+ }
+ },
+ "pretty-ms": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz",
+ "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==",
+ "dev": true,
+ "requires": {
+ "parse-ms": "^2.1.0"
+ }
+ },
+ "queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true
+ },
+ "read-pkg": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+ "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^4.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^3.0.0"
+ },
+ "dependencies": {
+ "load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "requires": {
+ "pify": "^3.0.0"
+ }
+ }
+ }
+ },
+ "readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "requires": {
+ "picomatch": "^2.2.1"
+ }
+ },
+ "regexp.prototype.flags": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
+ "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "functions-have-names": "^1.2.2"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ },
+ "resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "requires": {
+ "resolve-from": "^5.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true
+ },
+ "reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "requires": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "serialize-error": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
+ "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.13.1"
+ }
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
+ "dev": true
+ },
+ "shell-quote": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz",
+ "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==",
+ "dev": true
+ },
+ "side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ }
+ },
+ "signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz",
+ "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^6.0.0",
+ "is-fullwidth-code-point": "^4.0.0"
+ }
+ },
+ "spdx-correct": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+ "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+ "dev": true,
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+ "dev": true
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.12",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz",
+ "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==",
+ "dev": true
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true
+ },
+ "stack-utils": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz",
+ "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true
+ }
+ }
+ },
+ "string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "requires": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ }
+ },
+ "string.prototype.padend": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz",
+ "integrity": "sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.19.1"
+ }
+ },
+ "string.prototype.trimend": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz",
+ "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.19.5"
+ }
+ },
+ "string.prototype.trimstart": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz",
+ "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.19.5"
+ }
+ },
+ "strip-ansi": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz",
+ "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^6.0.1"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true
+ },
+ "supertap": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/supertap/-/supertap-3.0.1.tgz",
+ "integrity": "sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==",
+ "dev": true,
+ "requires": {
+ "indent-string": "^5.0.0",
+ "js-yaml": "^3.14.1",
+ "serialize-error": "^7.0.1",
+ "strip-ansi": "^7.0.1"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true
+ },
+ "temp-dir": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz",
+ "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==",
+ "dev": true
+ },
+ "time-zone": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz",
+ "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "type-fest": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
+ "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
+ "dev": true
+ },
+ "typescript": {
+ "version": "4.8.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz",
+ "integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==",
+ "dev": true
+ },
+ "unbox-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+ "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.0.3",
+ "which-boxed-primitive": "^1.0.2"
+ }
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "requires": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "well-known-symbols": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz",
+ "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==",
+ "dev": true
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "which-boxed-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+ "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+ "dev": true,
+ "requires": {
+ "is-bigint": "^1.0.1",
+ "is-boolean-object": "^1.1.0",
+ "is-number-object": "^1.0.4",
+ "is-string": "^1.0.5",
+ "is-symbol": "^1.0.3"
+ }
+ },
+ "wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ }
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true
+ },
+ "write-file-atomic": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
+ "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^3.0.7"
+ }
+ },
+ "y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "17.5.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
+ "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
+ "dev": true,
+ "requires": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ }
+ }
+ },
+ "yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true
+ },
+ "yocto-queue": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz",
+ "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==",
+ "dev": true
+ }
+ }
+}
diff --git a/web/package.json b/web/package.json
new file mode 100644
index 0000000..bda1696
--- /dev/null
+++ b/web/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "tea-contract-template-js",
+ "version": "1.0.0",
+ "description": "Taquito wrapper for tea contract template",
+ "main": "index.mjs",
+ "directories": {
+ "test": "tests"
+ },
+ "scripts": {
+ "test": "ava --no-worker-threads -v --serial --timeout 10m tests/*.spec.mjs",
+ "test-selection": "ava --no-worker-threads -v --serial --timeout 10m",
+ "build": "run-p build:*",
+ "build:es": "tsc --outDir dist/es --module esnext",
+ "build:cjs": "tsc --outDir dist/cjs --module commonjs"
+ },
+ "author": "alis.is",
+ "license": "MIT",
+ "devDependencies": {
+ "ava": "^4.3.3",
+ "hjson": "^3.2.2",
+ "lodash-es": "^4.17.21",
+ "npm-run-all": "^4.1.5",
+ "typescript": "^4.8.2"
+ },
+ "peerDependencies": {
+ "@taquito/michel-codec": "^13.0.1",
+ "@taquito/signer": "^13.0.1",
+ "@taquito/taquito": "^13.0.1",
+ "@taquito/tzip12": "^13.0.1",
+ "@taquito/tzip16": "^13.0.1"
+ }
+}
diff --git a/web/src/admin.ts b/web/src/admin.ts
new file mode 100644
index 0000000..74bef64
--- /dev/null
+++ b/web/src/admin.ts
@@ -0,0 +1,14 @@
+import { Contract } from "./contract";
+
+export interface IOperatorOpParams {
+ owner: string,
+ operator: string,
+ token_id: number
+}
+
+export class AdminContract extends Contract {
+ async setLock(locked: boolean) {
+ const contract = await this.get_contract();
+ return await contract.methodsObject.setLock(locked).send()
+ }
+}
\ No newline at end of file
diff --git a/web/src/contract.ts b/web/src/contract.ts
new file mode 100644
index 0000000..234cf81
--- /dev/null
+++ b/web/src/contract.ts
@@ -0,0 +1,67 @@
+import { TezosToolkit, Signer, Wallet, ContractAbstraction } from "@taquito/taquito";
+//import { Tzip12Module, tzip12, Tzip12ContractAbstraction } from "@taquito/tzip12";
+import { Tzip16Module, tzip16, Tzip16ContractAbstraction } from "@taquito/tzip16";
+import { RpcClientInterface } from "@taquito/rpc";
+
+export interface IOperatorOpParams {
+ owner: string,
+ operator: string,
+ token_id: number
+}
+
+export class Contract {
+ private toolkit: TezosToolkit
+ private contractAddr: string
+
+ constructor(RPC_URL_or_TEZ_TOOLKIT: string, contractAddr: string, options: { signer: Signer })
+ constructor(RPC_URL_or_TEZ_TOOLKIT: TezosToolkit, contractAddr: string, options?: {})
+ constructor(RPC_URL_or_TEZ_TOOLKIT: string | TezosToolkit, contractAddr: string, options: { signer?: Signer } = {}) {
+ if (typeof RPC_URL_or_TEZ_TOOLKIT === "string") {
+ const toolkit = new TezosToolkit(RPC_URL_or_TEZ_TOOLKIT)
+ //toolkit.addExtension(new Tzip12Module());
+ toolkit.addExtension(new Tzip16Module());
+ toolkit.setProvider({ signer: options.signer });
+ if (typeof options !== "object") options = {};
+ this.toolkit = toolkit
+ this.contractAddr = contractAddr
+ return
+ }
+
+ this.toolkit = RPC_URL_or_TEZ_TOOLKIT
+ this.contractAddr = contractAddr
+ }
+
+ async get_contract(): Promise & { /*tzip12: () => Tzip12ContractAbstraction,*/ tzip16: () => Tzip16ContractAbstraction }> {
+ return await this.toolkit.wallet.at(this.contractAddr, tzip16 /* compose(tzip12, tzip16) */)
+ }
+
+ async get_rpc(): Promise {
+ return this.toolkit.rpc
+ }
+
+ get ContractAddress() {
+ return this.contractAddr
+ }
+
+ async get_contract_storage() {
+ return (await this.get_contract()).storage()
+ }
+
+ async get_addr() {
+ try {
+ return await this.toolkit.wallet.pkh()
+ } catch {
+ return await this.toolkit.signer.publicKeyHash()
+ }
+ }
+
+ async increment(n: number) {
+ const contract = await this.get_contract();
+ return await contract.methodsObject.increment(n).send()
+ }
+
+ async decrement(n: number) {
+ const contract = await this.get_contract();
+ return await contract.methodsObject.decrement(n).send()
+ }
+}
\ No newline at end of file
diff --git a/web/src/index.ts b/web/src/index.ts
new file mode 100644
index 0000000..b3d81c3
--- /dev/null
+++ b/web/src/index.ts
@@ -0,0 +1,4 @@
+import { AdminContract } from "./admin.js"
+import { Contract } from "./contract"
+
+export { AdminContract, Contract }
\ No newline at end of file
diff --git a/web/tests/admin.spec.mjs b/web/tests/admin.spec.mjs
new file mode 100644
index 0000000..9f307c0
--- /dev/null
+++ b/web/tests/admin.spec.mjs
@@ -0,0 +1,24 @@
+import test from "ava";
+import { setup } from "./base.mjs"
+
+test.serial("setLock", async (t) => {
+ const { admin } = await setup();
+ await (await admin.setLock(true)).confirmation() // reset
+
+ await (await admin.setLock(false)).confirmation()
+ let storage = (await admin.get_contract_storage())
+ t.is(storage.locked, false)
+ await (await admin.setLock(true)).confirmation()
+ storage = (await admin.get_contract_storage())
+ t.is(storage.locked, true)
+});
+
+test.serial("setLock (not admin)", async (t) => {
+ const { bobAsAdmin } = await setup();
+ try {
+ await (await bobAsAdmin.setLock(true)).confirmation() // reset
+ t.fail("Should not be able to adjust lock if not admin")
+ } catch (err) {
+ t.true(err.toString().includes("not admin"))
+ }
+});
diff --git a/web/tests/base.mjs b/web/tests/base.mjs
new file mode 100644
index 0000000..0b0e065
--- /dev/null
+++ b/web/tests/base.mjs
@@ -0,0 +1,22 @@
+import fs from "fs/promises";
+
+import { InMemorySigner } from "@taquito/signer";
+import { AdminContract, Contract } from "../dist/cjs/index.js"
+import { parse } from "hjson"
+import { get } from "lodash-es"
+const appHjson = parse((await fs.readFile("../app.hjson")).toString())
+
+const ADMIN_KEY = "edsk3QoqBuvdamxouPhin7swCvkQNgq4jP5KZPbwWNnwdZpSpJiEbq"
+const BOB_KEY = "edsk3RFfvaFaxbHx8BMtEW1rKQcPtDML3LXjNqMNLCzC3wLC1bWbAt"
+const RPC_URL = `http://localhost:${get(appHjson, "sandbox.rpc_port", 20000)}`
+
+export const setup = async () => {
+ const id = appHjson.id
+ const { contractAddress } = JSON.parse(
+ (await fs.readFile(`../deploy/sandbox-${id}.json`)).toString()
+ );
+ const admin = new AdminContract(RPC_URL, contractAddress, { test: true, signer: await InMemorySigner.fromSecretKey(ADMIN_KEY) });
+ const bob = new Contract(RPC_URL, contractAddress, { test: true, signer: await InMemorySigner.fromSecretKey(BOB_KEY) });
+ const bobAsAdmin = new AdminContract(RPC_URL, contractAddress, { test: true, signer: await InMemorySigner.fromSecretKey(BOB_KEY) });
+ return { bob, admin, bobAsAdmin, contractAddress }
+};
\ No newline at end of file
diff --git a/web/tests/contract.spec.mjs b/web/tests/contract.spec.mjs
new file mode 100644
index 0000000..cb8db8f
--- /dev/null
+++ b/web/tests/contract.spec.mjs
@@ -0,0 +1,72 @@
+import test from "ava";
+import { setup } from "./base.mjs"
+
+test.serial("increment (locked - admin)", async (t) => {
+ const { admin } = await setup();
+ await (await admin.setLock(true)).confirmation() // reset
+ let storage = (await admin.get_contract_storage())
+ const initialValue = storage.state.toNumber()
+ await (await admin.increment(2)).confirmation()
+ storage = (await admin.get_contract_storage())
+ t.is(storage.state.toNumber(), initialValue + 2)
+});
+
+test.serial("increment (locked - not admin)", async (t) => {
+ const { bob, admin } = await setup();
+ await (await admin.setLock(true)).confirmation() // reset
+ let storage = (await bob.get_contract_storage())
+ const initialValue = storage.state.toNumber()
+ try {
+ await (await bob.increment(2)).confirmation()
+ t.fail("Should not be able to increment if locked and not admin")
+ } catch (err) {
+ t.true(err.toString().includes("not admin"))
+ }
+ storage = (await bob.get_contract_storage())
+ t.is(storage.state.toNumber(), initialValue)
+});
+
+test.serial("increment (not locked - not admin)", async (t) => {
+ const { bob, admin } = await setup();
+ await (await admin.setLock(false)).confirmation() // reset
+ let storage = (await bob.get_contract_storage())
+ const initialValue = storage.state.toNumber()
+ await (await bob.increment(3)).confirmation()
+ storage = (await bob.get_contract_storage())
+ t.is(storage.state.toNumber(), initialValue + 3)
+});
+
+test.serial("decrement (locked - admin)", async (t) => {
+ const { admin } = await setup();
+ await (await admin.setLock(true)).confirmation() // reset
+ let storage = (await admin.get_contract_storage())
+ const initialValue = storage.state.toNumber()
+ await (await admin.decrement(2)).confirmation()
+ storage = (await admin.get_contract_storage())
+ t.is(storage.state.toNumber(), initialValue - 2)
+});
+
+test.serial("decrement (locked - not admin)", async (t) => {
+ const { bob, admin } = await setup();
+ await (await admin.setLock(true)).confirmation() // reset
+ let storage = (await bob.get_contract_storage())
+ const initialValue = storage.state.toNumber()
+ try {
+ await (await bob.decrement(2)).confirmation()
+ t.fail("Should not be able to decrement if locked and not admin")
+ } catch (err) {
+ t.true(err.toString().includes("not admin"))
+ }
+ storage = (await bob.get_contract_storage())
+ t.is(storage.state.toNumber(), initialValue)
+});
+
+test.serial("decrement (not locked - not admin)", async (t) => {
+ const { bob, admin } = await setup();
+ await (await admin.setLock(false)).confirmation() // reset
+ let storage = (await bob.get_contract_storage())
+ const initialValue = storage.state.toNumber()
+ await (await bob.decrement(3)).confirmation()
+ storage = (await bob.get_contract_storage())
+ t.is(storage.state.toNumber(), initialValue - 3)
+});
diff --git a/web/tsconfig.json b/web/tsconfig.json
new file mode 100644
index 0000000..bc70e17
--- /dev/null
+++ b/web/tsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ "target": "ES2019",
+ "moduleResolution": "node",
+ "importHelpers": true,
+ "allowJs": true,
+ "jsx": "preserve",
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "sourceMap": true,
+ "baseUrl": "./",
+ "strict": true,
+ "declaration": true,
+ "paths": {
+ "@src/*": [
+ "src/*"
+ ],
+ "@root/*": [
+ "./*"
+ ]
+ },
+ "allowSyntheticDefaultImports": true,
+ },
+ "include": [
+ "src"
+ ]
+}
\ No newline at end of file