diff --git a/.gitignore b/.gitignore index 1232745f4..d300f5159 100644 --- a/.gitignore +++ b/.gitignore @@ -392,3 +392,4 @@ dmypy.json ### Module-Specific Ignores /api/wfl /api/project.clj +api/.eastwood diff --git a/api/build/build.clj b/api/build/build.clj index ca9cd1a3f..7f6c18d93 100644 --- a/api/build/build.clj +++ b/api/build/build.clj @@ -26,10 +26,8 @@ .toInstant .toString) commit (util/shell! "git" "rev-parse" "HEAD") committed (->> commit - (util/shell! "git" "show" "-s" "--format=%cI") - OffsetDateTime/parse .toInstant .toString) - clean? (do-or-nil-silently - (util/shell! "git" "diff-index" "--quiet" "HEAD"))] + (util/shell! "git" "show" "-s" "--format=%cI") + OffsetDateTime/parse .toInstant .toString)] {:version (or (System/getenv "WFL_VERSION") "devel") :commit commit :committed committed @@ -76,18 +74,21 @@ (let [workflow (util/remove-extension (util/basename wdl)) file (io/file resources "workflows" (str workflow ".edn"))] (when-not (.exists file) - (println "generating description for" (util/basename wdl)) + (println "describing" (util/basename wdl) "to" (.getPath file)) (io/make-parents file) - (with-open [out (io/writer file)] - (binding [*out* out] - (-> (slurp wdl) firecloud/describe-workflow pprint)))))) + (let [edn (-> wdl slurp firecloud/describe-workflow)] + (spit file (with-out-str + (println (str/join [";; (write-workflow-description" + \space resources \space wdl ")"])) + (println ";;") + (pprint edn))))))) (defn ^:private find-wdls [] (letfn [(list-wdls [folder] (->> (file-seq (io/file folder)) (map #(.getCanonicalPath %)) (filter #(= (util/extension %) "wdl"))))] - (mapcat list-wdls ["resources" "test/resources"]))) + (mapcat list-wdls ["resources" "test/resources"]))) (defn prebuild "Stage any needed resources on the class path." diff --git a/api/deps.edn b/api/deps.edn index d15428daf..9f6e0b130 100755 --- a/api/deps.edn +++ b/api/deps.edn @@ -23,11 +23,7 @@ ojdbc14/ojdbc14 {:mvn/version "10.2.0.1.0"} org.apache.commons/commons-lang3 {:mvn/version "3.8.1"} org.apache.tika/tika-core {:mvn/version "1.26"} - org.apache.logging.log4j/log4j-api {:mvn/version "2.14.1"} - org.apache.logging.log4j/log4j-core {:mvn/version "2.14.1"} - org.apache.logging.log4j/log4j-slf4j-impl {:mvn/version "2.14.1"} org.postgresql/postgresql {:mvn/version "42.2.20"} - org.slf4j/slf4j-api {:mvn/version "1.7.30"} ring-oauth2/ring-oauth2 {:mvn/version "0.1.5"} ring/ring-core {:mvn/version "1.9.3"} ring/ring-defaults {:mvn/version "0.3.2"} @@ -49,20 +45,33 @@ {:wfl {:main-opts ["-m" "wfl.main"]} - :lint - {:extra-deps {cljfmt/cljfmt {:mvn/version "0.7.0"}}} + :check-format + {:extra-deps {cljfmt/cljfmt {:mvn/version "0.7.0"}} + :main-opts ["-m" "cljfmt.main" "check"]} :format {:extra-deps {cljfmt/cljfmt {:mvn/version "0.7.0"}} :main-opts ["-m" "cljfmt.main" "fix"]} :kondo - {:extra-deps {clj-kondo/clj-kondo {:mvn/version "2021.04.23"}} + {:extra-deps {clj-kondo/clj-kondo {:mvn/version "2021.06.01"}} :main-opts ["-m" "clj-kondo.main"]} :kibit {:extra-deps {jonase/kibit {:mvn/version "0.1.8"}} :main-opts ["-e" "(use,'kibit.driver),(external-run,[\"src\"],nil)"]} + + :eastwood + {:extra-deps {jonase/eastwood {:mvn/version "0.4.3"} + org.liquibase/liquibase-core + {:mvn/version "4.3.5" + :exclusions [ch.qos.logback/logback-classic]}} + :extra-paths ["test"] + :main-opts ["-m" "eastwood.lint" + {:add-linters #{#_:keyword-typos :unused-fn-args} + :config-files #{"resources/eastwood.clj"} + :source-paths ["src" "test"] + :ignored-faults {:keyword-typos {wfl.api.routes [true]}}}]} :liquibase {:extra-deps {org.liquibase/liquibase-core {:mvn/version "4.3.5" diff --git a/api/module.mk b/api/module.mk index 9218dd858..00056b1d8 100644 --- a/api/module.mk +++ b/api/module.mk @@ -33,7 +33,8 @@ JAR_LINK := $(DERIVED_TARGET_DIR)/wfl.jar $(PREBUILD): $(MODULE_DIR)/build/build.$(CLJ) $(PREBUILD): $(SCM_RESOURCES) $(TEST_SCM_RESOURCES) - @$(MKDIR) $(DERIVED_RESOURCES_DIR) $(DERIVED_SRC_DIR) $(DERIVED_TEST_DIR) + @$(MKDIR) $(DERIVED_RESOURCES_DIR) $(DERIVED_SRC_DIR) $(DERIVED_TEST_DIR) $(CLASSES_DIR) + $(CLOJURE) -M -e "(compile 'wfl.util)" $(CLOJURE) -X:prebuild @$(TOUCH) $@ @@ -52,9 +53,12 @@ $(BUILD): $(SCM_SRC) $(POM_OUT) $(LN) $(JAR) $(JAR_LINK) @$(TOUCH) $@ -# Run `clojure -M:format` in this directory when this fails. +LIKELY_FIX := 'Run `clojure -M:format` in this directory' $(LINT): $(SCM_SRC) $(SCM_RESOURCES) - $(CLOJURE) -M:lint -m cljfmt.main check + @$(CLOJURE) -M:check-format || (c=$$?; $(ECHO) $(LIKELY_FIX); $(EXIT) $$c) + @$(CLOJURE) -M:eastwood + @$(CLOJURE) -M:kibit + -@$(CLOJURE) -M:kondo --config ./resources/kondo.edn --lint . @$(TOUCH) $@ $(UNIT): $(TEST_SCM_SRC) diff --git a/api/resources/eastwood.clj b/api/resources/eastwood.clj new file mode 100644 index 000000000..071e18621 --- /dev/null +++ b/api/resources/eastwood.clj @@ -0,0 +1,4 @@ +#_:clj-kondo/ignore +(disable-warning + {:linter :constant-test + :if-inside-macroexpansion-of #{'wfl.util/assoc-when}}) diff --git a/api/resources/kondo.edn b/api/resources/kondo.edn new file mode 100644 index 000000000..0e16b6730 --- /dev/null +++ b/api/resources/kondo.edn @@ -0,0 +1 @@ +{:lint-as {wfl.jdbc/with-db-transaction clojure.core/with-open}} diff --git a/api/resources/log4j2.xml b/api/resources/log4j2.xml deleted file mode 100644 index 3b8d22efe..000000000 --- a/api/resources/log4j2.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - %d{hh:mm:ss} %-5level %logger{36} - %msg%n - - - - - - - - - - - - - - - - - - - - diff --git a/api/src/wfl/api/handlers.clj b/api/src/wfl/api/handlers.clj index 7b7faf7c0..a1aa61098 100644 --- a/api/src/wfl/api/handlers.clj +++ b/api/src/wfl/api/handlers.clj @@ -1,21 +1,22 @@ (ns wfl.api.handlers "Define handlers for API endpoints. Require wfl.module namespaces here." (:require [clojure.set :refer [rename-keys]] - [clojure.tools.logging :as log] - [clojure.tools.logging.readable :as logr] [ring.util.http-response :as response] [wfl.api.workloads :as workloads] + [wfl.configuration :as config] [wfl.jdbc :as jdbc] + [wfl.log :as log] [wfl.module.aou :as aou] - [wfl.module.arrays] [wfl.module.copyfile] [wfl.module.covid] [wfl.module.sg] [wfl.module.wgs] [wfl.module.xx] + [wfl.service.cromwell :as cromwell] [wfl.service.google.storage :as gcs] [wfl.service.postgres :as postgres] - [wfl.util :as util])) + [wfl.util :as util]) + (:import [wfl.util UserException])) (defn succeed "A successful response with BODY." @@ -27,11 +28,34 @@ [body] (constantly (succeed body))) +(defn get-logging-level + "Gets the current logging level of the API" + [request] + (log/info (select-keys request [:request-method :uri :body-params])) + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (letfn [(to-result [s] {:level s})] + (-> (config/get-config tx "LOGGING_LEVEL") + to-result + succeed)))) + +(defn update-logging-level + "Updates the current logging level of the API." + [request] + (log/info (select-keys request [:request-method :uri :parameters])) + (let [{:keys [level]} (get-in request [:parameters :query])] + (letfn [(to-result [s] {:level s})] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (-> (config/upsert-config tx "LOGGING_LEVEL" level) + first + (get :value) + to-result + succeed))))) + (defn append-to-aou-workload "Append workflows described in BODY of REQUEST to a started AoU workload." [request] + (log/info (select-keys request [:request-method :uri :body-params])) (let [{:keys [notifications uuid]} (get-in request [:parameters :body])] - (logr/infof "appending %s samples to workload %s" (count notifications) uuid) (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] (->> (workloads/load-workload-for-uuid tx uuid) (aou/append-to-workload! tx notifications) @@ -40,10 +64,10 @@ (defn post-create "Create the workload described in REQUEST." [request] - (let [workload-request (-> (:body-params request) - (rename-keys {:cromwell :executor})) + (log/info (select-keys request [:request-method :uri :body-params])) + (let [workload-request (rename-keys (:body-params request) + {:cromwell :executor}) {:keys [email]} (gcs/userinfo request)] - (logr/info "POST /api/v1/create with request: " workload-request) (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] (->> (assoc workload-request :creator email) (workloads/create-workload! tx) @@ -53,8 +77,8 @@ (defn get-workload "List all workloads or the workload(s) with UUID or PROJECT in REQUEST." [request] - (let [{:keys [uuid project] :as query} (get-in request [:parameters :query])] - (logr/info "GET /api/v1/workload with query: " query) + (log/info (select-keys request [:request-method :uri :parameters])) + (let [{:keys [uuid project]} (get-in request [:parameters :query])] (succeed (map util/to-edn (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] @@ -65,19 +89,52 @@ (defn get-workflows "Return the workflows managed by the workload." [request] - (let [uuid (get-in request [:path-params :uuid])] - (log/infof "GET /api/v1/workload/%s/workflows" uuid) + (log/info (select-keys request [:request-method :uri :parameters])) + (let [uuid (get-in request [:path-params :uuid]) + status (get-in request [:parameters :query :status])] (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> (workloads/load-workload-for-uuid tx uuid) - (workloads/workflows tx) + (->> (let [workload (workloads/load-workload-for-uuid tx uuid)] + (if status (workloads/workflows-by-status tx workload status) (workloads/workflows tx workload))) (mapv util/to-edn) succeed)))) +;; Visible for testing +(def retry-unsupported-status-error-message + "Retry unsupported for requested status.") +(def retry-no-workflows-error-message + "No workflows to retry for requested status.") + +(defn post-retry + "Retry the workflows identified in `request`." + [request] + (log/info (select-keys request [:request-method :uri :parameters])) + (let [uuid (get-in request [:path-params :uuid]) + status (get-in request [:body-params :status]) + supported? (cromwell/retry-status? status)] + (when-not supported? + (throw (UserException. retry-unsupported-status-error-message + {:workload uuid + :supported-statuses cromwell/retry-status? + :requested-status status + :status 400}))) + (->> (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (let [workload (workloads/load-workload-for-uuid tx uuid) + workflows (workloads/workflows-by-status tx workload status)] + (when (empty? workflows) + (throw (UserException. retry-no-workflows-error-message + {:workload uuid + :requested-status status + :status 400}))) + [workload workflows])) + (apply workloads/retry) + util/to-edn + succeed))) + (defn post-start "Start the workload with UUID in REQUEST." [request] + (log/info (select-keys request [:request-method :uri :parameters])) (let [{uuid :uuid} (:body-params request)] - (logr/infof "POST /api/v1/start with uuid: " uuid) (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] (let [{:keys [started] :as workload} (workloads/load-workload-for-uuid tx uuid)] @@ -88,8 +145,8 @@ (defn post-stop "Stop managing workflows for the workload specified by 'request'." [request] + (log/info (select-keys request [:request-method :uri :parameters])) (let [{uuid :uuid} (:body-params request)] - (logr/infof "POST /api/v1/stop with uuid: %s" uuid) (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] (->> (workloads/load-workload-for-uuid tx uuid) (workloads/stop-workload! tx) @@ -99,9 +156,9 @@ (defn post-exec "Create and start workload described in BODY of REQUEST" [request] - (let [workload-request (-> (:body-params request) - (rename-keys {:cromwell :executor}))] - (logr/info "POST /api/v1/exec with request: " workload-request) + (log/info (select-keys request [:request-method :uri :parameters])) + (let [workload-request (rename-keys (:body-params request) + {:cromwell :executor})] (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] (->> (gcs/userinfo request) :email diff --git a/api/src/wfl/api/routes.clj b/api/src/wfl/api/routes.clj index bc4e6ea30..4ee4522f7 100644 --- a/api/src/wfl/api/routes.clj +++ b/api/src/wfl/api/routes.clj @@ -1,8 +1,6 @@ (ns wfl.api.routes "Define routes for API endpoints." (:require [clojure.string :as str] - [clojure.tools.logging :as log] - [clojure.tools.logging.readable :as logr] [muuntaja.core :as muuntaja-core] [reitit.coercion.spec] [reitit.ring :as ring] @@ -13,9 +11,13 @@ [reitit.ring.middleware.parameters :as parameters] [reitit.swagger :as swagger] [wfl.api.handlers :as handlers] + [wfl.api.spec :as spec] [wfl.api.workloads :as workloads] [wfl.environment :as env] - [wfl.api.spec :as spec] + [wfl.log :as log] + [wfl.module.all :as all] + [wfl.module.aou :as aou] + [wfl.util :as util] [wfl.wfl :as wfl]) (:import [java.sql SQLException] [wfl.util UserException] @@ -32,25 +34,31 @@ :responses {200 {:body {:status string?}}} :swagger {:tags ["Informational"]}}}] ["/version" - {:get {:summary "Get the versions of server and supported pipelines" - :handler (handlers/success (let [versions (wfl/get-the-version) - pipeline-versions-keys (keep (fn [x] (when (and (string? x) - (str/ends-with? x ".wdl")) x)) - (keys versions))] - {:pipeline-versions (select-keys versions pipeline-versions-keys) - :version (apply dissoc versions pipeline-versions-keys)})) - :responses {200 {:body {:version map? - :pipeline-versions map?}}} - :swagger {:tags ["Informational"]}}}] + {:get {:summary "Get the versions of server and supported pipelines" + :handler (handlers/success (wfl/get-the-version)) + :responses {200 {:body ::spec/version-response}} + :swagger {:tags ["Informational"]}}}] ["/oauth2id" - {:get {:summary "Get the OAuth2 Client ID for this deployment of the server" - :handler (fn [_] (handlers/succeed {:oauth2-client-id (env/getenv "WFL_OAUTH2_CLIENT_ID")})) + {:get {:summary "Get the OAuth2 Client ID deployed for this server" + :handler (fn [_] (handlers/succeed + {:oauth2-client-id + (env/getenv "WFL_OAUTH2_CLIENT_ID")})) :responses {200 {:body {:oauth2-client-id string?}}} :swagger {:tags ["Informational"]}}}] + ["/api/v1/logging_level" + {:get {:no-doc true + :summary "Get the current logging level" + :handler handlers/get-logging-level + :responses {200 {:body ::log/logging-level-response}} + :swagger {:tags ["Informational"]}} + :post {:summary "Post a new logging level." + :parameters {:query ::log/logging-level-request} + :responses {200 {:body ::log/logging-level-response}} + :handler handlers/update-logging-level}}] ["/api/v1/append_to_aou" {:post {:summary "Append to an existing AOU workload." - :parameters {:body ::spec/append-to-aou-request} - :responses {200 {:body ::spec/append-to-aou-response}} + :parameters {:body ::aou/append-to-aou-request} + :responses {200 {:body ::aou/append-to-aou-response}} :handler handlers/append-to-aou-workload}}] ["/api/v1/workload" {:get {:summary "Get the workloads." @@ -59,9 +67,15 @@ :handler handlers/get-workload}}] ["/api/v1/workload/:uuid/workflows" {:get {:summary "Get workflows managed by the workload." - :parameters {:path {:uuid ::spec/uuid}} + :parameters {:path {:uuid ::all/uuid} :query ::spec/workflow-query} :responses {200 {:body ::spec/workflows}} :handler handlers/get-workflows}}] + ["/api/v1/workload/:uuid/retry" + {:post {:summary "Resubmit workflows in workload by status." + :parameters {:path {:uuid ::all/uuid} + :body {:status ::all/status}} + :responses {200 {:body ::spec/workload-response}} + :handler handlers/post-retry}}] ["/api/v1/create" {:post {:summary "Create a new workload." :parameters {:body ::spec/workload-request} @@ -69,12 +83,12 @@ :handler handlers/post-create}}] ["/api/v1/start" {:post {:summary "Start a workload." - :parameters {:body ::spec/uuid-kv} + :parameters {:body ::all/uuid-kv} :responses {200 {:body ::spec/workload-response}} :handler handlers/post-start}}] ["/api/v1/stop" {:post {:summary "Stop managing the workload specified by 'request'." - :parameters {:body ::spec/uuid-kv} + :parameters {:body ::all/uuid-kv} :responses {200 {:body ::spec/workload-response}} :handler handlers/post-stop}}] ["/api/v1/exec" @@ -83,18 +97,21 @@ :responses {200 {:body ::spec/workload-response}} :handler handlers/post-exec}}] ["/swagger/swagger.json" - {:get {:no-doc true ;; exclude this endpoint itself from swagger - :swagger {:info {:title (str wfl/the-name "-API") - :version (str (:version (wfl/get-the-version)))} - :securityDefinitions {:googleoauth {:type "oauth2" - :flow "implicit" - :authorizationUrl "https://accounts.google.com/o/oauth2/auth" - :scopes {:openid "Basic OpenID authorization" - :email "Read access to your email" - :profile "Read access to your profile"}}} - :tags [{:name "Informational"} - {:name "Authenticated"}] - :basePath "/"} ;; prefix for all paths + {:get {:no-doc true ; exclude this endpoint itself from swagger + :swagger + {:info {:title (str wfl/the-name "-API") + :version (str (:version (wfl/get-the-version)))} + :securityDefinitions + {:googleoauth + {:type "oauth2" + :flow "implicit" + :authorizationUrl "https://accounts.google.com/o/oauth2/auth" + :scopes {:openid "Basic OpenID authorization" + :email "Read access to your email" + :profile "Read access to your profile"}}} + :tags [{:name "Informational"} + {:name "Authenticated"}] + :basePath "/"} ; prefix for all paths :handler (swagger/create-swagger-handler)}}]]) (defn endpoint-swagger-auth-processor @@ -128,11 +145,12 @@ (defn logging-exception-handler "Like [[exception-handler]] but also log information about the exception." - [status message exception request] - (let [response (exception-handler status message exception request)] - (log/errorf "Server %s error at occurred at %s :" (:status response) (:uri request)) - (logr/error exception (:body response)) - response)) + [status message exception {:keys [uri] :as request}] + (let [{:keys [body status] :as result} + (exception-handler status message exception request)] + (log/error (format "Server %s error at occurred at %s :" status uri)) + (log/error (util/make-map exception body)) + result)) (def exception-middleware "Custom exception middleware, dispatch on fully qualified exception types." @@ -143,18 +161,18 @@ ::workloads/invalid-pipeline (partial exception-handler 400 "") ::workloads/workload-not-found (partial exception-handler 404 "") UserException (partial exception-handler 400 "") - ;; SQLException and all its child classes + ;; SQLException and all its child classes SQLException (partial logging-exception-handler 500 "SQL Exception") - ;; handle clj-http Slingshot stone exceptions + ;; handle clj-http Slingshot stone exceptions :clj-http.client/unexceptional-status (partial exception-handler 400 "HTTP Error on request") - ;; override the default handler + ;; override the default handler ::exception/default (partial logging-exception-handler 500 "Internal Server Error")}))) (def routes (ring/ring-handler (ring/router (endpoint-swagger-auth-processor endpoints) - {;; uncomment for easier debugging with coercion and middleware transformations + {;; uncomment to debug coercion and middleware transformations ;; :reitit.middleware/transform dev/print-request-diffs ;; :exception pretty/exception :data {:coercion reitit.coercion.spec/coercion @@ -175,5 +193,8 @@ multipart/multipart-middleware]}}) ;; get more correct http error responses on routes (ring/create-default-handler - {:not-found (fn [m] {:status 404 :body (format "Route %s not found" (:uri m))}) - :method-not-allowed (fn [m] {:status 405 :body (format "Method %s not allowed" (name (:request-method m)))})}))) + {:not-found (fn [m] {:status 404 + :body (format "Route %s not found" (:uri m))}) + :method-not-allowed (fn [m] {:status 405 + :body (format "Method %s not allowed" + (name (:request-method m)))})}))) diff --git a/api/src/wfl/api/spec.clj b/api/src/wfl/api/spec.clj index 9776c5929..3f635dbce 100644 --- a/api/src/wfl/api/spec.clj +++ b/api/src/wfl/api/spec.clj @@ -2,213 +2,51 @@ "Define specs used in routes" (:require [clojure.spec.alpha :as s] [clojure.string :as str] - [wfl.service.cromwell :as cromwell] - [wfl.util :as util]) - (:import [java.time OffsetDateTime] - [java.util UUID] - [javax.mail.internet InternetAddress])) + [wfl.module.all :as all] + [wfl.module.aou :as aou] + [wfl.module.batch :as batch] + [wfl.module.copyfile :as copyfile] + [wfl.module.covid :as covid] + [wfl.module.sg :as sg] + [wfl.module.wgs :as wgs] + [wfl.module.xx :as xx] + [wfl.util :as util])) + +(s/def ::workload-query (s/and (s/keys :opt-un [::all/uuid ::all/project]) + #(not (and (:uuid %) (:project %))))) -(defn uuid-string? [s] (uuid? (util/do-or-nil (UUID/fromString s)))) -(defn datetime-string? [s] (util/do-or-nil (OffsetDateTime/parse s))) +(s/def ::workflow-query (s/keys :opt-un [::all/status])) -(defn email-address? - "True if `s` is an email address." - [s] - (util/do-or-nil (or (.validate (InternetAddress. s)) true))) +(s/def :version/built util/datetime-string?) +(s/def :version/commit (s/and string? (comp not str/blank?))) +(s/def :version/committed util/datetime-string?) +(s/def :version/user (s/and string? (comp not str/blank?))) -;; shared -(s/def ::base_file_name string?) -(s/def ::commit (s/and string? (comp (partial == 40) count))) -(s/def ::contamination_vcf string?) -(s/def ::contamination_vcf_index string?) -(s/def ::cram_ref_fasta string?) -(s/def ::cram_ref_fasta_index string?) -(s/def ::timestamp (s/or :instant inst? :datetime datetime-string?)) -(s/def ::created ::timestamp) -(s/def :batch/creator string?) -(s/def :covid/creator email-address?) -(s/def ::cromwell string?) -(s/def ::dbsnp_vcf string?) -(s/def ::dbsnp_vcf_index string?) -(s/def ::environment string?) -(s/def ::finished ::timestamp) -(s/def ::input string?) -(s/def ::input_bam #(str/ends-with? % ".bam")) -(s/def ::input_cram #(str/ends-with? % ".cram")) -(s/def ::output string?) -(s/def ::pipeline string?) -(s/def ::project string?) -(s/def ::release string?) -(s/def ::status (set (conj cromwell/statuses "skipped"))) -(s/def ::started ::timestamp) -(s/def ::stopped ::timestamp) -(s/def ::updated ::timestamp) -(s/def ::uuid uuid-string?) -(s/def ::uuid-kv (s/keys :req-un [::uuid])) -(s/def ::version string?) -(s/def ::wdl string?) -(s/def ::options map?) -(s/def ::common map?) -(s/def ::workload-query (s/and (s/keys :opt-un [::uuid ::project]) - #(not (and (:uuid %) (:project %))))) +(s/def ::version-response (s/keys :req-un [:version/built + :version/commit + :version/committed + :version/user + ::all/version])) -;; compound (s/def ::items (s/* ::workload-inputs)) (s/def ::workload-inputs (s/keys :req-un [::inputs] - :opt-un [::options])) -(s/def ::inputs (s/or :aou ::aou-workflow-inputs - :arrays ::arrays-workflow-inputs - :copyfile ::copyfile-workflow-inputs - :wgs ::wgs-workflow-inputs - :xx ::xx-workflow-inputs - :sg ::sg-workflow-inputs + :opt-un [::all/options])) +(s/def ::inputs (s/or :aou ::aou/workflow-inputs + :copyfile ::copyfile/workflow-inputs + :wgs ::wgs/workflow-inputs + :xx ::xx/workflow-inputs + :sg ::sg/workflow-inputs :other map?)) (s/def ::workflow (s/keys :req-un [::inputs] - :opt-un [::status ::updated ::uuid ::options])) -(s/def ::workflows (s/* ::workflow)) - -;; aou -(s/def ::analysis_version_number integer?) -(s/def ::chip_well_barcode string?) -(s/def ::append-to-aou-request (s/keys :req-un [::notifications ::uuid])) -(s/def ::append-to-aou-response (s/* ::aou-workflow-inputs)) -(s/def ::aou-workflow-inputs (s/keys :req-un [::analysis_version_number - ::chip_well_barcode])) - -(s/def ::notifications (s/* ::aou-sample)) -(s/def ::aou-sample (s/keys :req-un [::analysis_version_number - ::chip_well_barcode])) - -;; arrays -(s/def ::entity-name string?) -(s/def ::entity-type string?) -(s/def ::arrays-workflow-inputs (s/keys :req-un [::entity-name - ::entity-type])) - -;; copyfile -(s/def ::copyfile-workflow-inputs (s/keys :req-un [::dst ::src])) -(s/def ::dst string?) -(s/def ::src string?) - -;; wgs (External Whole Genome Reprocessing) -(s/def ::wgs-workflow-inputs (s/keys :req-un [(or ::input_bam ::input_cram)])) - -;; xx (External Exome Reprocessing) -(s/def ::xx-workflow-inputs (s/keys :req-un [(or ::input_bam ::input_cram)])) - -;; sg (GDC Whole Genome Somatic single Sample) -(s/def ::sg-workflow-inputs (s/keys :req-un [::base_file_name - ::contamination_vcf - ::contamination_vcf_index - ::cram_ref_fasta - ::cram_ref_fasta_index - ::dbsnp_vcf - ::dbsnp_vcf_index - ::input_cram])) + :opt-un [::all/status ::all/updated ::all/uuid ::all/options])) -(s/def ::column string?) -(s/def ::dataset string?) -(s/def ::entityType string?) -(s/def ::identifier string?) -(s/def ::fromOutputs map?) -(s/def ::fromSource string?) -(s/def ::labels (s/* util/label?)) -(s/def ::name string?) -(s/def ::methodConfiguration (s/and string? util/terra-namespaced-name?)) -(s/def ::methodConfigurationVersion integer?) -(s/def ::table string?) -(s/def ::snapshotReaders (s/* email-address?)) -(s/def ::watchers (s/* email-address?)) -(s/def ::workspace (s/and string? util/terra-namespaced-name?)) -(s/def ::snapshots (s/* ::uuid)) - -(s/def :batch/executor string?) -(s/def :covid/executor (s/keys :req-un [::name - ::fromSource - ::methodConfiguration - ::methodConfigurationVersion - ::workspace])) - -(s/def ::sink (s/keys :req-un [::name - ::entityType - ::fromOutputs - ::identifier - ::workspace])) - -(s/def ::tdr-source - (s/keys :req-un [::name - ::column - ::dataset - ::table - ::snapshotReaders] - :opt-un [::snapshots])) - -(s/def ::snapshot-list-source - (s/keys :req-un [::name ::snapshots])) - -(s/def ::source (s/or :dataset ::tdr-source - :snapshots ::snapshot-list-source)) - -;; This is the wrong thing to do. See [1] for more information. -;; As a consequence, I've included the keys for a covid pipeline as optional -;; inputs for batch workloads so that these keys are not removed during -;; coercion. -;; [1]: https://github.com/metosin/reitit/issues/494 -(s/def ::batch-workload-request - (s/keys :opt-un [::common - ::input - ::items - ::labels - ::output - ::sink - ::source - ::watchers] - :req-un [(or ::cromwell :batch/executor) - ::pipeline - ::project])) - -(s/def ::batch-workload-response (s/keys :opt-un [::finished - ::input - ::started - ::stopped - ::wdl] - :req-un [::commit - ::created - :batch/creator - :batch/executor - ::output - ::pipeline - ::project - ::release - ::uuid - ::version])) - -(s/def ::covid-workload-request (s/keys :req-un [:covid/executor - ::project - ::sink - ::source] - :opt-un [::labels - ::watchers])) - -(s/def ::covid-workload-response (s/keys :req-un [::created - :covid/creator - :covid/executor - ::labels - ::sink - ::source - ::uuid - ::version - ::watchers] - :opt-un [::finished - ::started - ::stopped - ::updated])) +(s/def ::workflows (s/* ::workflow)) -(s/def ::workload-request (s/or :batch ::batch-workload-request - :covid ::covid-workload-request)) +(s/def ::workload-request (s/or :batch ::batch/workload-request + :covid ::covid/workload-request)) -(s/def ::workload-response (s/or :batch ::batch-workload-response - :covid ::covid-workload-response)) +(s/def ::workload-response (s/or :batch ::batch/workload-response + :covid ::covid/workload-response)) (s/def ::workload-responses (s/* ::workload-response)) diff --git a/api/src/wfl/api/workloads.clj b/api/src/wfl/api/workloads.clj index c07eb4c8c..dc715b3ec 100644 --- a/api/src/wfl/api/workloads.clj +++ b/api/src/wfl/api/workloads.clj @@ -1,8 +1,8 @@ (ns wfl.api.workloads - (:require [clojure.string :as str] - [clojure.tools.logging :as log] - [wfl.jdbc :as jdbc] - [wfl.util :as util])) + (:require [clojure.string :as str] + [wfl.log :as log] + [wfl.jdbc :as jdbc] + [wfl.util :as util])) ;; always derive from base :wfl/exception (derive ::invalid-pipeline :wfl/exception) @@ -11,38 +11,49 @@ ;; creating and dispatching workloads to cromwell (defmulti create-workload! "(transaction workload-request) -> workload" - (fn [_ body] (:pipeline body))) + (fn [_transaction request] (:pipeline request))) (defmulti start-workload! "(transaction workload) -> workload" - (fn [_ body] (:pipeline body))) + (fn [_transaction workload] (:pipeline workload))) (defmulti stop-workload! "(transaction workload) -> workload" - (fn [_ body] (:pipeline body))) + (fn [_transaction workload] (:pipeline workload))) (defmulti execute-workload! "(transaction workload) -> workload" - (fn [_ body] (:pipeline body))) + (fn [_transaction workload] (:pipeline workload))) (defmulti update-workload! "(transaction workload) -> workload" - (fn [_ body] (:pipeline body))) + (fn [_transaction workload] (:pipeline workload))) (defmulti workflows - "Use `tx` to return the workflows managed by the `workload`." - (fn [tx workload] (:pipeline workload))) + "Use db `transaction` to return the workflows managed by the `workload`, + optionally filtering by status." + (fn [_transaction workload] (:pipeline workload))) + +(defmulti workflows-by-status + "Use db `transaction` to return the workflows managed by the `workload` that + match `status`." + (fn [_transaction workload _status] (:pipeline workload))) + +(defmulti retry + "Retry/resubmit the `workflows` managed by the `workload` and return the + workload that manages the new workflows." + (fn [workload _workflows] (:pipeline workload))) (defmulti to-edn "Return an EDN representation of the `workload` that will be shown to users." - (fn [workload] (:pipeline workload))) + :pipeline) ;; loading utilities (defmulti load-workload-impl "Load the workload given a TRANSACTION and a partially loaded WORKLOAD. NOTE: do NOT call directly in product code - this is only meant to be called within this namespace." - (fn [_ body] (:pipeline body))) + (fn [_transaction body] (:pipeline body))) (defn ^:private try-load-workload-impl [tx workload] (try @@ -55,7 +66,7 @@ (defn load-workload-for-uuid "Use transaction `tx` to load `workload` with `uuid`." [tx uuid] - (log/debugf "Loading workload uuid=%s" uuid) + (log/debug (format "Loading workload uuid=%s" uuid)) (let [workloads (jdbc/query tx ["SELECT * FROM workload WHERE uuid = ?" uuid])] (when (empty? workloads) (throw (ex-info "No workload found matching uuid" @@ -66,7 +77,7 @@ (defn load-workload-for-id "Use transaction `tx` to load `workload` with `id`." [tx id] - (log/debugf "Loading workload id=%s" id) + (log/debug (format "Loading workload id=%s" id)) (let [workloads (jdbc/query tx ["SELECT * FROM workload WHERE id = ?" id])] (when (empty? workloads) (throw (ex-info "No workload found matching id" @@ -77,17 +88,16 @@ (defn load-workloads-with-project "Use transaction `tx` to load `workload`(s) with `project`." [tx project] - (log/debugf "Loading workloads with project=\"%s\"" project) - (let [do-load (partial load-workload-impl tx)] - (mapv do-load - (jdbc/query tx ["SELECT * FROM workload WHERE project = ?" project])))) + (log/debug (format "Loading workloads with project=\"%s\"" project)) + (let [query-str "SELECT * FROM workload WHERE project = ? ORDER BY id ASC"] + (mapv (partial load-workload-impl tx) (jdbc/query tx [query-str project])))) (defn load-workloads "Use transaction `tx` to load all known `workloads`." [tx] (log/debug "Loading all workloads") - (let [do-load (partial load-workload-impl tx)] - (mapv do-load (jdbc/query tx ["SELECT * FROM workload"])))) + (let [query-str "SELECT * FROM workload ORDER BY id ASC"] + (mapv (partial load-workload-impl tx) (jdbc/query tx query-str)))) ;; helper utility for point-free multi-method implementation registration. (defmacro defoverload @@ -137,6 +147,15 @@ :pipeline pipeline :type ::invalid-pipeline}))) +(defmethod retry + :default + [{:keys [pipeline] :as workload} _] + (throw + (ex-info "Failed to retry workflows - no such pipeline" + {:workload workload + :pipeline pipeline + :type ::invalid-pipeline}))) + (defmethod to-edn :default [{:keys [pipeline] :as workload}] diff --git a/api/src/wfl/configuration.clj b/api/src/wfl/configuration.clj new file mode 100644 index 000000000..cf529c03c --- /dev/null +++ b/api/src/wfl/configuration.clj @@ -0,0 +1,25 @@ +(ns wfl.configuration + "Configuration for WFL. A configuration table exists as a simple key + value store for simple configuration." + (:require [clojure.string :as str] + [wfl.jdbc :as jdbc])) + +(def ^:private configuration-table "configuration") + +(defn get-config + "Use transaction `tx` to load the current logging level of the application." + [tx key] + (let [configs (jdbc/query tx ["SELECT value FROM configuration WHERE key = ?" key])] + (if (empty? configs) + (-> :info name str/upper-case) + (str/upper-case (get (first configs) :value))))) + +(defn upsert-config + "Use transaction `tx` to insert or update a configuration row." + [tx key value] + (letfn [(get-row [] (jdbc/query tx ["SELECT * FROM configuration WHERE key = ?" key]))] + (if (empty? (get-row)) + (jdbc/insert! tx configuration-table {:key key :value value}) + (if (empty? (jdbc/update! tx configuration-table {:value value} ["key = ?" key])) + (throw (ex-info "Unable to update " key)) + (get-row))))) diff --git a/api/src/wfl/debug.clj b/api/src/wfl/debug.clj index 75e4ef33b..bb3102ee6 100644 --- a/api/src/wfl/debug.clj +++ b/api/src/wfl/debug.clj @@ -11,7 +11,7 @@ x#))) (defmacro trace - "Like DUMP but include location metadata." + "Like `dump` but include location metadata." [expression] (let [{:keys [line column]} (meta &form)] `(let [x# ~expression] diff --git a/api/src/wfl/environment.clj b/api/src/wfl/environment.clj index f0871797f..39e6f284e 100644 --- a/api/src/wfl/environment.clj +++ b/api/src/wfl/environment.clj @@ -1,8 +1,8 @@ (ns wfl.environment "Map environment to various values here." (:require [clojure.data.json :as json] - [clojure.tools.logging :as log] [clojure.string :as str] + [wfl.log :as log] [vault.client.http] ; vault.core needs this [vault.core :as vault])) @@ -30,33 +30,33 @@ (json/write-str :escape-slash false) .getBytes) "WFL_CLIO_URL" - #(-> "https://clio.gotc-dev.broadinstitute.org") + (fn [] "https://clio.gotc-dev.broadinstitute.org") "WFL_COOKIE_SECRET" #(-> "secret/dsde/gotc/dev/zero" vault-secrets :cookie_secret) "WFL_TDR_URL" - #(-> "https://jade.datarepo-dev.broadinstitute.org") + (fn [] "https://data.terra.bio") "WFL_OAUTH2_CLIENT_ID" #(-> "secret/dsde/gotc/dev/zero" vault-secrets :oauth2_client_id) "WFL_POSTGRES_PASSWORD" - #(-> "password") + (fn [] "password") "WFL_POSTGRES_URL" - #(-> "jdbc:postgresql:wfl") + (fn [] "jdbc:postgresql:wfl") "WFL_POSTGRES_USERNAME" - #(-> nil) + (fn [] nil) "WFL_FIRECLOUD_URL" - #(-> "https://api.firecloud.org") + (fn [] "https://api.firecloud.org") "WFL_RAWLS_URL" - #(-> "https://rawls.dsde-dev.broadinstitute.org") + (fn [] "https://rawls.dsde-dev.broadinstitute.org") + "WFL_DOCKSTORE_URL" + (fn [] "https://dockstore.org") ;; -- variables used in test code below this line -- "WFL_CROMWELL_URL" - #(-> "https://cromwell-gotc-auth.gotc-dev.broadinstitute.org") + (fn [] "https://cromwell-gotc-auth.gotc-dev.broadinstitute.org") "WFL_TDR_DEFAULT_PROFILE" - #(-> "390e7a85-d47f-4531-b612-165fc977d3bd") - "WFL_TDR_SA" - #(-> "jade-k8-sa@broad-jade-dev.iam.gserviceaccount.com") + (fn [] "6370f5a1-d777-4991-8200-ceab83521d43") "WFL_WFL_URL" - #(-> "https://dev-wfl.gotc-dev.broadinstitute.org")}) + (fn [] "https://dev-wfl.gotc-dev.broadinstitute.org")}) (def ^:private __getenv (memoize #(or (System/getenv %) (when-let [init (defaults %)] (init))))) @@ -69,5 +69,5 @@ (defn getenv "Lookup the value of the environment variable specified by `name`." [name] - (log/debugf "Reading environment variable %s" name) + (log/debug (format "Reading environment variable %s" name)) (or (@testing name) (__getenv name))) diff --git a/api/src/wfl/executor.clj b/api/src/wfl/executor.clj new file mode 100644 index 000000000..b80a4649c --- /dev/null +++ b/api/src/wfl/executor.clj @@ -0,0 +1,565 @@ +(ns wfl.executor + (:require [clojure.edn :as edn] + [clojure.set :as set :refer [rename-keys]] + [clojure.string :as str] + [ring.util.codec :refer [url-encode]] + [wfl.api.workloads :refer [defoverload]] + [wfl.jdbc :as jdbc] + [wfl.log :as log] + [wfl.service.dockstore :as dockstore] + [wfl.service.firecloud :as firecloud] + [wfl.service.postgres :as postgres] + [wfl.service.rawls :as rawls] + [wfl.stage :as stage :refer [log-prefix]] + [wfl.util :as util :refer [map-keys utc-now]]) + (:import [wfl.util UserException])) + +;; executor operations +(defmulti update-executor! + "Consume items from the `upstream-queue` and enqueue to the `executor` queue + for consumption by a later processing stage, performing any external effects + as necessary. Implementations should avoid maintaining in-memory state and + making long-running external calls, favouring internal queues to manage such + tasks asynchronously between invocations. Note that the `Executor` and + `Queue` are parameterised types and the `Queue`'s parameterisation must be + convertible to the `Executor`s." + (fn [_upstream-queue executor] (:type executor))) + +(defmulti executor-workflows + "Return the workflows managed by the `executor" + (fn [_transaction executor] (:type executor))) + +(defmulti executor-workflows-by-status + "Use db `transaction` to return the workflows created by the `executor` + matching `status`" + (fn [_transaction executor _status] (:type executor))) + +(defmulti executor-retry-workflows! + "Retry/resubmit the `workflows` managed by the `executor`." + (fn [executor _workflows] (:type executor))) + +;; load/save operations +(defmulti create-executor! + "Create an `Executor` instance using the database `transaction` and + configuration in the executor `request` and return a + `[type items]` pair to be written to a workload record as + `executor_type` and `executor_items`. + Notes: + - This is a factory method registered for workload creation. + - The `Executor` type string must match a value of the `executor` enum + in the database schema. + - This multimethod is type-dispatched on the `:name` association in the + `request`." + (fn [_transaction _workload-id request] (:name request))) + +(defmulti load-executor! + "Return the `Executor` implementation associated with the `executor_type` and + `executor_items` fields of the `workload` row in the database. + Note that this multimethod is type-dispatched on the `:executor_type` + association in the `workload`." + (fn [_transaction workload] (:executor_type workload))) + +(defmethod create-executor! :default + [_ _ {:keys [name] :as request}] + (throw (UserException. + "Invalid executor name" + {:name name + :request request + :status 400 + :executors (-> create-executor! methods (dissoc :default) keys)}))) + +;; Terra Executor +(def ^:private ^:const terra-executor-name "Terra") +(def ^:private ^:const terra-executor-type "TerraExecutor") +(def ^:private ^:const terra-executor-table "TerraExecutor") +(def ^:private ^:const terra-executor-serialized-fields + {:workspace :workspace + :methodConfiguration :method_configuration + :methodConfigurationVersion :method_configuration_version + :fromSource :from_source}) + +(defn ^:private write-terra-executor [tx id executor] + (let [create "CREATE TABLE %s OF TerraExecutorDetails (PRIMARY KEY (id))" + alter "ALTER TABLE %s ALTER COLUMN id ADD GENERATED ALWAYS AS IDENTITY" + details (format "%s_%09d" terra-executor-type id)] + (jdbc/db-do-commands tx [(format create details) (format alter details)]) + [terra-executor-type + (-> (select-keys executor (keys terra-executor-serialized-fields)) + (update :fromSource pr-str) + (set/rename-keys terra-executor-serialized-fields) + (assoc :details details) + (->> (jdbc/insert! tx terra-executor-table) first :id str))])) + +(defn ^:private load-terra-executor [tx {:keys [executor_items] :as workload}] + (if-let [id (util/parse-int executor_items)] + (-> (postgres/load-record-by-id! tx terra-executor-table id) + (assoc :type terra-executor-type) + (set/rename-keys (set/map-invert terra-executor-serialized-fields)) + (update :fromSource edn/read-string)) + (throw (ex-info "Invalid executor_items" {:workload workload})))) + +(defn ^:private throw-on-method-config-version-mismatch + [{:keys [methodConfigVersion] :as methodconfig} expected] + (when-not (== expected methodConfigVersion) + (throw (UserException. + "Unexpected method configuration version" + {:methodConfiguration methodconfig + :expected expected + :actual methodConfigVersion})))) + +(defn ^:private throw-unless-dockstore-method + "Throw unless the `sourceRepo` of `methodRepoMethod` is \"dockstore\"." + [{:keys [sourceRepo] :as methodRepoMethod}] + (when-not (= "dockstore" sourceRepo) + (throw (UserException. "Only Dockstore methods are supported." + {:status 400 :methodRepoMethod methodRepoMethod})))) + +(defn terra-executor-validate-request-or-throw + "Verify the method-configuration exists." + [{:keys [skipValidation + workspace + methodConfiguration + methodConfigurationVersion + fromSource] :as executor}] + (when-not skipValidation + (firecloud/workspace-or-throw workspace) + (when-not (= "importSnapshot" fromSource) + (throw + (UserException. "Unsupported coercion" (util/make-map fromSource)))) + (let [m (firecloud/method-configuration workspace methodConfiguration)] + (throw-on-method-config-version-mismatch m methodConfigurationVersion) + (throw-unless-dockstore-method (:methodRepoMethod m)))) + executor) + +(defn ^:private entity-from-snapshot + "Coerce the `snapshot` into a workspace entity via `fromSource`." + [{:keys [workspace fromSource] :as executor} {:keys [id name] :as snapshot}] + (when-not (= "importSnapshot" fromSource) + (throw (ex-info "Unknown conversion from snapshot to workspace entity." + {:executor executor + :snapshot snapshot}))) + (log/debug (format "%s Creating or getting snapshot reference %s in %s..." + (log-prefix executor) name workspace)) + (rawls/create-or-get-snapshot-reference workspace id name)) + +(defn ^:private from-source + "Coerce `object` to form understood by `executor``." + [executor [type value :as object]] + (case type + :datarepo/snapshot (entity-from-snapshot executor value) + (throw (ex-info "No method to coerce object into workspace entity" + {:executor executor + :object object})))) + +(defn ^:private update-method-configuration! + "Update `methodConfiguration` in `workspace` with snapshot reference `name` + as :dataReferenceName via Firecloud. + Update executor table record ID with incremented `methodConfigurationVersion`." + [{:keys [id + workspace + methodConfiguration + methodConfigurationVersion] :as executor} + reference] + (let [name (get-in reference [:metadata :name]) + current (firecloud/method-configuration workspace methodConfiguration) + _ (throw-on-method-config-version-mismatch + current methodConfigurationVersion) + inc'd (inc methodConfigurationVersion)] + (-> "%s Updating %s in %s with {:dataReferenceName %s :methodConfigVersion %s}" + (format (log-prefix executor) methodConfiguration workspace name inc'd) + log/debug) + (firecloud/update-method-configuration + workspace methodConfiguration + (assoc current :dataReferenceName name :methodConfigVersion inc'd)) + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (jdbc/update! tx terra-executor-table + {:method_configuration_version inc'd} + ["id = ?" id])))) + +(defn ^:private create-submission! + "Update `methodConfiguration` to use `reference`. + Create and return submission in `workspace` for `methodConfiguration` via Firecloud." + [{:keys [workspace methodConfiguration] :as executor} reference] + (update-method-configuration! executor reference) + (log/debug (format "%s Submitting %s to %s..." + (log-prefix executor) methodConfiguration workspace)) + (firecloud/submit-method workspace methodConfiguration)) + +(defn ^:private allocate-submission + "Write or allocate workflow records for `submission` in `details` table, + and return them." + [{:keys [details] :as executor} + reference + {:keys [submissionId workflows] :as _submission}] + (log/debug (format "%s Allocating %s workflow records for submission %s..." + (log-prefix executor) (count workflows) submissionId)) + (letfn [(to-row [now {:keys [status workflowId entityName] :as _workflow}] + {:reference (get-in reference [:metadata :resourceId]) + :submission submissionId + :workflow workflowId + :entity entityName + :status status + :updated now})] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> workflows + (map (partial to-row (utc-now))) + (jdbc/insert-multi! tx details))))) + +;; Workflows in newly created firecloud submissions may not have been scheduled +;; yet and thus do not have a workflow uuid. Thus, we first "allocate" the +;; workflow in the database and then later assign workflow uuids. +(defn ^:private update-unassigned-workflow-uuids! + "Assign workflow uuids from previous submissions" + [{:keys [workspace details] :as executor}] + (letfn [(read-a-submission-without-workflows [] + (let [query "SELECT id, submission, entity FROM %s + WHERE submission IN ( + SELECT submission FROM %s WHERE workflow IS NULL + LIMIT 1 + )"] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (let [records (jdbc/query tx (format query details details))] + (when-first [{:keys [submission]} records] + [submission records]))))) + (zip-record [{:keys [entity] :as record} + {:keys [workflowId workflowEntity status]}] + (when-not (= entity workflowEntity) + (throw (ex-info "Failed to write workflow uuid: entity did not match" + {:expected entity + :actual workflowEntity + :executor executor}))) + (assoc record :workflow workflowId :status status)) + (write-workflow-statuses [now records] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (run! + (fn [{:keys [id workflow status]}] + (jdbc/update! tx details + {:status status :workflow workflow :updated now} + ["id = ?" id])) + records)))] + (when-let [[submission records] (read-a-submission-without-workflows)] + (let [{:keys [workflows]} (firecloud/get-submission workspace submission)] + (when-not (== (count records) (count workflows)) + (throw (ex-info "Allocated more records than created workflows" + {:submission submission :executor executor}))) + (log/debug (format "%s Writing %s workflow uuids and statuses for submission %s..." + (log-prefix executor) (count workflows) submission)) + (->> workflows + (map #(update % :workflowEntity :entityName)) + (sort-by :workflowEntity) + (map zip-record (sort-by :entity records)) + (write-workflow-statuses (utc-now))))))) + +(def ^:private active-workflows-query-template + "Query template for fetching active workflows + from an executor details table to be specified at runtime." + (let [final-statuses (util/to-quoted-comma-separated-list rawls/final-statuses)] + (format "SELECT * FROM %%s + WHERE submission IS NOT NULL + AND workflow IS NOT NULL + AND status NOT IN %s + ORDER BY id ASC" + final-statuses))) + +(defn ^:private update-terra-workflow-statuses! + "Update statuses in `details` table for active `workspace` workflows." + [{:keys [workspace details] :as executor}] + (letfn [(update-status-from-firecloud + [{:keys [submission workflow] :as record}] + (->> (firecloud/get-workflow workspace submission workflow) + :status + (assoc record :status))) + (write-workflow-statuses [now records] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (run! + (fn [{:keys [id status] :as _record}] + (jdbc/update! tx details {:status status :updated now} + ["id = ?" id])) + (sort-by :entity records))))] + (log/debug (format "%s Updating statuses for active workflows..." + (log-prefix executor))) + (->> (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (jdbc/query tx (format active-workflows-query-template details))) + (mapv update-status-from-firecloud) + (write-workflow-statuses (utc-now))))) + +(defn ^:private update-terra-executor + "Create new submission from new `source` snapshot if available, + writing its workflows to `details` table. + Update statuses for active or failed workflows in `details` table. + Return `executor`." + [source executor] + (when-let [object (stage/peek-queue source)] + (let [entity (from-source executor object) + submission (create-submission! executor entity)] + (allocate-submission executor entity submission) + (stage/pop-queue! source))) + (update-unassigned-workflow-uuids! executor) + (update-terra-workflow-statuses! executor) + executor) + +(defn ^:private combine-record-workflow-and-outputs + [{:keys [updated] :as _record} + {:keys [workflowName] :as workflow} + firecloud-outputs] + (let [prefix (str workflowName ".") + outputs (-> firecloud-outputs + (get-in [:tasks (keyword workflowName) :outputs]) + (util/unprefix-keys prefix))] + (-> (assoc workflow :updated updated :outputs outputs) + (update :inputs #(util/unprefix-keys % prefix)) + (set/rename-keys {:id :uuid}) + (util/select-non-nil-keys [:inputs :uuid :status :outputs :updated])))) + +(defn ^:private peek-terra-executor-details + "Get first unconsumed successful workflow record from `details` table." + [{:keys [details] :as _executor}] + (let [query "SELECT * FROM %s + WHERE consumed IS NULL + AND status = 'Succeeded' + ORDER BY id ASC + LIMIT 1"] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> (format query details) + (jdbc/query tx) + first)))) + +(defn ^:private method-content-url + "Return the URL to the WDL content used by this `methodRepoMethod`. If the WDL + is hosted on GitHub, returns a jsdelivr URL to avoid GitHub rate limits." + [{:keys [methodPath methodVersion] :as methodRepoMethod}] + (throw-unless-dockstore-method methodRepoMethod) + (let [id (url-encode (str "#workflow/" methodPath)) + url (:url (dockstore/ga4gh-tool-descriptor id methodVersion "WDL"))] + (if-let [groups (re-find #"^https://raw.githubusercontent.com/(.*)$" url)] + (let [[author repo version path] (str/split (second groups) #"/" 4)] + (str/join "/" ["https://cdn.jsdelivr.net/gh" author (str repo "@" version) path])) + url))) + +;; visible for testing +(defn describe-method + "Describe the method associated with the `methodconfig`." + [workspace methodconfig] + (-> (firecloud/method-configuration workspace methodconfig) + :methodRepoMethod + method-content-url + firecloud/describe-workflow)) + +(defn ^:private peek-terra-executor-queue + "Get first unconsumed successful workflow from `executor` queue." + [{:keys [workspace methodConfiguration] :as executor}] + (when-let [{:keys [submission workflow] :as record} + (peek-terra-executor-details executor)] + [(describe-method workspace methodConfiguration) + (combine-record-workflow-and-outputs + record + (firecloud/get-workflow workspace submission workflow) + (firecloud/get-workflow-outputs workspace submission workflow))])) + +(defn ^:private pop-terra-executor-queue + "Consume first unconsumed successful workflow record in `details` table, + or throw if none." + [{:keys [details] :as executor}] + (if-let [{:keys [id] :as _record} (peek-terra-executor-details executor)] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (let [now (utc-now)] + (jdbc/update! tx details {:consumed now :updated now} ["id = ?" id]))) + (throw (ex-info "No successful workflows in queue" {:executor executor})))) + +(defn ^:private terra-executor-queue-length + "Return the number of workflows in the `executor` queue that are yet to be + consumed." + [{:keys [details] :as _executor}] + (let [query "SELECT COUNT(*) FROM %s + WHERE consumed IS NULL + AND (status IS NULL OR + status NOT IN ('Failed', 'Aborted'))"] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> (format query details) + (jdbc/query tx) + first + :count)))) + +(defn ^:private terra-workflows-from-records + [{:keys [workspace] :as _executor} records] + (letfn [(from-record [{:keys [workflow submission status] :as record}] + (combine-record-workflow-and-outputs + record + (firecloud/get-workflow workspace submission workflow) + (when (= "Succeeded" status) + (firecloud/get-workflow-outputs workspace submission workflow))))] + (map from-record records))) + +;; terra-executor-workflows and terra-executor-workflows-by-status do not return +;; workflows that are being or have been retried. Why? +;; +;; TL/DR: It's simpler maybe? +;; +;; The truth is I'm not sure of a *good* reason to do this. +;; +;; Some context/terminology: +;; Workflows are be serialised to the DB as a kind of flattened list of lists, +;; where there `HEAD` of each inner list is the most recent workflow attempt and +;; the `TAIL` of each inner list are all those previous attempts. +;; +;; In the DB, this is implemented such that each `HEAD` element does not have a +;; "pointer" to a another attempt and each retried workflow has a "pointer" to +;; the workflow that retied it (a linked list with the pointers reversed - think +;; git commit trees): +;; +;; Attempt0 -> Attempt1 -> ... -> HEAD +;; +;; My initial thought was that when getting workflows, you'd only want to see +;; the workflows at the `HEAD` (i.e. the most recent attempts at converting +;; inputs -> outputs). This would also make it harder to retry a workflow that +;; had already been retried*. This also drove the implementation making it +;; easier to find the HEAD of each list. +;; +;; Two alternatives come to mind: +;; - return the list of lists (though this would break hOps's retry code). +;; - include a {"retried": uuid} attribute in each workflow such that clients +;; could reconstruct the graph of retries. +;; +;; I lean towards 2 because it might expose a richer API for clients to gather +;; information from. The difficulty is that when workflows are initially +;; retried, they're not assigned a workflow UUID yet so users might see that +;; a workflow does not have a {"retried": uuid} immediately after they've tried +;; to retry it.** +;; +;; * It would still be possible and we'd have to come up with a strategy for +;; handling this - perhaps traverse the list and retry the workflow if there's +;; not already an active workflow at the `HEAD`. +;; +;; ** Admittedly, this is still a problem with this design. + +(defn ^:private terra-executor-workflows + "Return all the non-retried workflows executed by the `executor`." + [tx {:keys [details] :as executor}] + (postgres/throw-unless-table-exists tx details) + (let [query "SELECT * FROM %s + WHERE workflow IS NOT NULL + AND retry IS NULL + ORDER BY id ASC"] + (terra-workflows-from-records + executor + (jdbc/query tx (format query details))))) + +(defn ^:private terra-executor-workflows-by-status + "Return all the non-retried workflows matching `status` executed by the + `executor`." + [tx {:keys [details] :as executor} status] + (postgres/throw-unless-table-exists tx details) + (let [query "SELECT * FROM %s + WHERE workflow IS NOT NULL + AND retry IS NULL + AND status = ? + ORDER BY id ASC"] + (terra-workflows-from-records + executor + (jdbc/query tx [(format query details) status])))) + +(defn ^:private workflow-and-sibling-records + "Return the workflow records for all workflows in submissions + associated with the specified `workflows` -- + i.e. records for `workflows` and their siblings." + [tx {:keys [details] :as executor} workflows] + (postgres/throw-unless-table-exists tx details) + (let [workflow-ids (util/to-quoted-comma-separated-list (map :uuid workflows)) + _ (-> (str "%s For workflows %s, " + "fetching sibling workflow records by submission") + (format (log-prefix executor) workflow-ids) + log/debug) + ;; 1. Presently Rawls doesn't support submitting a subset of a snapshot: + ;; If we wish to retry 1+ workflows stemming from a snapshot, + ;; we must resubmit the snapshot in its entirety. + ;; 2. Though we are technically resubmitting snapshot references + ;; and not submissions, this query takes a submission-based approach. + ;; Why? Because there is no ambiguity when linking a submission + ;; to its workflows. With the capacity for retries, one reference + ;; may map to multiple sets of workflows, and retrying the reference + ;; should only update the sibling workflow records of those supplied. + query "SELECT * FROM %s + WHERE submission IN + (SELECT DISTINCT submission FROM %s + WHERE workflow IN %s)"] + (jdbc/query tx (format query details details workflow-ids)))) + +(defn update-retried-workflow-records + "Match `original-records` with `retry-records` on entity uuid, + update each original record to point to its retry record, + and propagate all updates to `details` table." + [{:keys [details] :as executor} [retry-records original-records]] + (letfn [(link-retry-to-original + [{:keys [entity] :as original} + {:keys [retryEntity id] :as retry}] + (when-not (= entity retryEntity) + (throw (ex-info (str "Failed to link retry to original workflow: " + "mismatched entities") + {:original original + :retry retry + :executor executor}))) + (assoc original :retry id)) + (write-retries + [now records] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (run! + (fn [{:keys [id retry]}] + (jdbc/update! tx details + {:retry retry :updated now} + ["id = ?" id])) + records)))] + (when-not (== (count retry-records) (count original-records)) + (throw (ex-info "All original records should be retried" + {:retry-records retry-records + :original-records original-records + :executor executor}))) + (log/debug (format "%s Linking %s retry records to their originals..." + (log-prefix executor) (count retry-records))) + (->> retry-records + (map #(rename-keys % {:entity :retryEntity})) + (sort-by :retryEntity) + (map link-retry-to-original (sort-by :entity original-records)) + (write-retries (utc-now))))) + +(defn ^:private terra-executor-retry-workflows + "Resubmit the snapshot references associated with `workflows` in `workspace` + and update each original workflow record with the row ID of its retry." + [{:keys [workspace] :as executor} workflows] + (letfn [(submit-reference [reference-id] + ;; Further work required to deal in generic entities + ;; rather than assumed snapshot references: + ;; https://broadinstitute.atlassian.net/browse/GH-1422 + (let [reference (rawls/get-snapshot-reference workspace reference-id)] + (->> reference + (create-submission! executor) + (allocate-submission executor reference))))] + (->> (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (workflow-and-sibling-records tx executor workflows)) + (group-by :reference) + (map-keys submit-reference) + (run! (partial update-retried-workflow-records executor))))) + +(defn ^:private terra-executor-done? [executor] + (zero? (stage/queue-length executor))) + +(defn ^:private terra-executor-to-edn [executor] + (-> executor + (util/select-non-nil-keys (keys terra-executor-serialized-fields)) + (assoc :name terra-executor-name))) + +(defmethod create-executor! terra-executor-name + [tx id request] + (write-terra-executor tx id (terra-executor-validate-request-or-throw request))) + +(defoverload load-executor! terra-executor-type load-terra-executor) +(defoverload update-executor! terra-executor-type update-terra-executor) +(defoverload executor-workflows terra-executor-type terra-executor-workflows) +(defoverload executor-workflows-by-status terra-executor-type terra-executor-workflows-by-status) +(defoverload executor-retry-workflows! terra-executor-type terra-executor-retry-workflows) + +(defoverload stage/peek-queue terra-executor-type peek-terra-executor-queue) +(defoverload stage/pop-queue! terra-executor-type pop-terra-executor-queue) +(defoverload stage/queue-length terra-executor-type terra-executor-queue-length) +(defoverload stage/done? terra-executor-type terra-executor-done?) + +(defoverload util/to-edn terra-executor-type terra-executor-to-edn) diff --git a/api/src/wfl/jdbc.clj b/api/src/wfl/jdbc.clj index 47efa19b8..fc4c8ccc8 100644 --- a/api/src/wfl/jdbc.clj +++ b/api/src/wfl/jdbc.clj @@ -1,18 +1,17 @@ (ns wfl.jdbc - "clojure.tools.logging wrapping for clojure.java.jdbc" - (:require [clojure.java.jdbc :as jdbc] - [clojure.tools.logging.readable :as log]) + "wfl.log wrapping for clojure.java.jdbc" + (:require [clojure.java.jdbc :as jdbc] + [clojure.string :as str] + [wfl.log :as logger]) (:import (clojure.lang IPersistentVector) (java.sql PreparedStatement Array))) (def ^:private remember-db "Memoized helper to only print the db out the first time" - (memoize (fn [db] - (let [random (rand-int 10000) - identifier (str (:user db) "@" (:connection-uri db) "#" random)] - (log/infof "JDBC new DB config %s observed (the #%s isn't important, just unique):" - identifier random) - (log/info (dissoc db :password)) + (memoize (fn [{:keys [connection-uri user] :as db}] + (let [random (rand-int 10000) + identifier (str user "@" connection-uri "#" random)] + (logger/info (dissoc db :password)) identifier)))) (defn format-db @@ -25,13 +24,13 @@ ([db sql-params] `(let [db# ~db sql-params# ~sql-params] - (log/trace "jdbc/query:" (format-db db#) sql-params#) + (logger/debug (str/join " " ["jdbc/query:" (format-db db#) sql-params#])) (jdbc/query db# sql-params#))) ([db sql-params opts] `(let [db# ~db sql-params# ~sql-params opts# ~opts] - (log/trace "jdbc/query:" (format-db db#) sql-params# opts#) + (logger/debug (str/join " " ["jdbc/query:" (format-db db#) sql-params# opts#])) (jdbc/query db# sql-params# opts#)))) (defmacro update! @@ -41,7 +40,7 @@ table# ~table set-map# ~set-map where-clause# ~where-clause] - (log/info "jdbc/update!" (format-db db#) table# set-map# where-clause#) + (logger/info (str/join " " ["jdbc/update!" (format-db db#) table# set-map# where-clause#])) (jdbc/update! db# table# set-map# where-clause#))) ([db table set-map where-clause opts] `(let [db# ~db @@ -49,7 +48,7 @@ set-map# ~set-map where-clause# ~where-clause opts# ~opts] - (log/info "jdbc/update!" (format-db db#) table# set-map# where-clause# opts#) + (logger/info (str/join " " ["jdbc/update!" (format-db db#) table# set-map# where-clause# opts#])) (jdbc/update! db# table# set-map# where-clause# opts#)))) (defmacro insert-multi! @@ -58,14 +57,14 @@ `(let [db# ~db table# ~table rows# ~rows] - (log/info "jdbc/insert-multi!" (format-db db#) table# rows#) + (logger/info (str/join " " ["jdbc/insert-multi!" (format-db db#) table# rows#])) (jdbc/insert-multi! db# table# rows#))) ([db table cols-or-rows values-or-opts] `(let [db# ~db table# ~table cols-or-rows# ~cols-or-rows values-or-opts# ~values-or-opts] - (log/info "jdbc/insert-multi!" (format-db db#) table# cols-or-rows# values-or-opts#) + (logger/info (str/join " " ["jdbc/insert-multi!" (format-db db#) table# cols-or-rows# values-or-opts#])) (jdbc/insert-multi! db# table# cols-or-rows# values-or-opts#))) ([db table cols values opts] `(let [db# ~db @@ -73,7 +72,7 @@ cols# ~cols values# ~values opts# ~opts] - (log/info "jdbc/insert-multi!" (format-db db#) table# cols# values# opts#) + (logger/info (str/join " " ["jdbc/insert-multi!" (format-db db#) table# cols# values# opts#])) (jdbc/insert-multi! db# table# cols# values# opts#)))) (defmacro execute! @@ -81,13 +80,13 @@ ([db sql-params] `(let [db# ~db sql-params# ~sql-params] - (log/info "jdbc/execute!" (format-db db#) sql-params#) + (logger/info (str/join " " ["jdbc/execute!" (format-db db#) sql-params#])) (jdbc/execute! db# sql-params#))) ([db sql-params opts] `(let [db# ~db sql-params# ~sql-params opts# ~opts] - (log/info "jdbc/execute!" (format-db db#) sql-params# opts#) + (logger/info (str/join " " ["jdbc/execute!" (format-db db#) sql-params# opts#])) (jdbc/execute! db# sql-params# opts#)))) (defmacro db-do-commands @@ -95,13 +94,13 @@ ([db sql-commands] `(let [db# ~db sql-commands# ~sql-commands] - (log/info "jbs/db-do-commands" (format-db db#) sql-commands#) + (logger/info (str/join " " ["jbs/db-do-commands" (format-db db#) sql-commands#])) (jdbc/db-do-commands db# sql-commands#))) ([db transaction? sql-commands] `(let [db# ~db transaction?# ~transaction? sql-commands# ~sql-commands] - (log/info "jbs/db-do-commands" (format-db db#) transaction?# sql-commands#) + (logger/info (str/join " " ["jbs/db-do-commands" (format-db db#) transaction?# sql-commands#])) (jdbc/db-do-commands db# transaction?# sql-commands#)))) (defmacro insert! @@ -110,31 +109,32 @@ `(let [db# ~db table# ~table row# ~row] - (log/info "jdbc/insert" (format-db db#) table# row#) + (logger/info (str/join " " ["jdbc/insert" (format-db db#) table# row#])) (jdbc/insert! db# table# row#))) ([db table cols-or-row values-or-opts] `(let [db# ~db table# ~table cols-or-row# ~cols-or-row values-or-opts# ~values-or-opts] - (log/info "jdbc/insert" (format-db db#) table# cols-or-row# values-or-opts#) + (logger/info (str/join " " ["jdbc/insert" (format-db db#) table# cols-or-row# values-or-opts#])) (jdbc/insert! db# table# cols-or-row# values-or-opts#))) ([db table cols values opts] `(let [db# ~db table# ~table cols# ~cols - values# ~values] - (log/info "jdbc/insert" (format-db db#) table# cols# values# opts) - "jdbc/insert" db# table# cols# values# opts))) + values# ~values + opts# ~opts] + (logger/info (str/join " " ["jdbc/insert" (format-db db#) table# cols# values# opts#])) + "jdbc/insert" db# table# cols# values# opts#))) (defmacro with-db-transaction "Logged alias for [[clojure.java.jdbc/with-db-transaction]]" [binding & body] `(let [id# (rand-int 10000) init# ~(second binding)] - (log/info "JDBC transaction" id# "started to" (format-db init#)) + (logger/info (str/join " " ["JDBC transaction" id# "started to" (format-db init#)])) (let [exe# (jdbc/with-db-transaction [~(first binding) init#] ~@body)] - (log/info "JDBC SQL transaction" id# "ended") + (logger/info (str/join " " ["JDBC SQL transaction" id# "ended"])) exe#))) (defmacro prepare-statement @@ -149,11 +149,11 @@ "Logged alias for [[clojure.java.jdbc/prepare-statement]]" ([db-spec] `(do - (log/info "JBDC SQL connection made (no opts):" (format-db ~db-spec)) + (logger/info (str/join " " ["JBDC SQL connection made (no opts):" (format-db ~db-spec)])) (jdbc/get-connection ~db-spec))) ([db-spec opts] `(do - (log/info "JBDC SQL connection made:" (format-db ~db-spec) ~opts) + (logger/info (str/join " " ["JBDC SQL connection made:" (format-db ~db-spec) ~opts])) (jdbc/get-connection ~db-spec ~opts)))) ;; Expertly copied and pasted from Stack Overflow: @@ -164,11 +164,11 @@ (let [conn (.getConnection stmt) meta (.getParameterMetaData stmt) [head & rest] (.getParameterTypeName meta i)] - (if-let [elem-type (when (= head \_) (apply str rest))] + (if-let [elem-type (when (= head \_) (str/join rest))] (.setObject stmt i (.createArrayOf conn elem-type (to-array v))) (.setObject stmt i v))))) (extend-protocol clojure.java.jdbc/IResultSetReadColumn Array (result-set-read-column [val _ _] - (into [] (.getArray val)))) + (vec (.getArray val)))) diff --git a/api/src/wfl/log.clj b/api/src/wfl/log.clj new file mode 100644 index 000000000..4a16a787a --- /dev/null +++ b/api/src/wfl/log.clj @@ -0,0 +1,117 @@ +(ns wfl.log + "Logging for WFL. The severity levels provided here are based off of + the severity levels supported by GCP's Stackdriver. A list of the supported + levels can be found here: https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#LogSeverity" + (:require [clojure.data.json :as json] + [clojure.string :as str] + [clojure.spec.alpha :as s]) + (:import [java.time Instant])) + +(def levels + "A list of the available logging levels the application can use." + [:debug :info :notice :warning :error :alert :critical :emergency]) + +(defn levels-contains? + "Validate that the provided label exists." + [s] + (let [level (-> s str/lower-case keyword)] + (some #(= level %) levels))) +(s/def ::level (s/and string? levels-contains?)) +(s/def ::logging-level-request (s/keys :req-un [::level])) +(s/def ::logging-level-response (s/keys :req-un [::level])) + +(defn ^:private key-fn + "Preserve the namespace of `key` when qualified." + [key] + ((:key-fn json/default-write-options) + (if (qualified-keyword? key) + (str (namespace key) \/ (name key)) + key))) + +(defprotocol Logger + "Log `edn` to `logger` as JSON." + (-write [logger edn])) + +(def disabled-logger + "A logger that does not log." + (reify Logger + (-write [_ _]))) + +(def stdout-logger + "A logger to write to standard output" + (reify Logger + (-write [logger edn] + (-> edn + (json/write-str :key-fn key-fn :escape-slash false) + println)))) + +(def ^:dynamic *logger* + "The logger now." + stdout-logger) + +(def logging-level + "The current logging level of the application." + (atom :info)) + +(defmacro log + "Log `expression` with `severity` and a optional set of special + fields to provide more information about a logging message. + + A detailed explanation of the fields and their meaning can be found + here: https://cloud.google.com/logging/docs/agent/logging/configuration#special-fields + + :httpRequest A structured record for the Http Request that was made + + :logging.googleapis.com/insertId An optional unique identifier. Logs with the same identifier and timestamp will be considered duplicates in Google Logging. + + :logging.googleapis.com/labels A map of key value pairs that can be searched on in Google Logging. + + :logging.googleapis.com/operation Additional information about a potentially long-running operation with which a log entry is associated. + + :logging.googleapis.com/trace Resource name of the trace associated with the log entry if any. + + :logging.googleapis.com/spanId The span ID within the trace associated with the log entry." + [severity expression & {:as additional-fields}] + (let [{:keys [line]} (meta &form)] + `(let [x# ~expression + [excl# incl#] (split-with (complement #{@logging-level}) levels)] + (when (contains? (set incl#) ~severity) + (-write *logger* + (merge {:timestamp (Instant/now) + :severity ~(-> severity name str/upper-case) + :message x# + :logging.googleapis.com/sourceLocation + {:file ~*file* :line ~line}} + ~additional-fields))) + nil))) + +(defmacro debug + "Log `expression` for debugging. + This is for debug or trace information." + [expression] + `(log :debug ~expression)) + +(defmacro info + "Log `expression` as information. + Used for routine information, such as ongoing status or performance." + [expression] + `(log :info ~expression)) + +(defmacro notice + "Log `expression` as a notice. + Used for normal but significant events, such as start up, + shut down, or a configuration change." + [expression] + `(log :notice ~expression)) + +(defmacro warn + "Log `expression` as a warning. + Used for warning events, which might cause problems." + [expression] + `(log :warning ~expression)) + +(defmacro error + "Log `expression` as an error. + Used for events that are likely to cause problems." + [expression] + `(log :error ~expression)) diff --git a/api/src/wfl/main.clj b/api/src/wfl/main.clj index e7db43e73..887e2d483 100644 --- a/api/src/wfl/main.clj +++ b/api/src/wfl/main.clj @@ -68,13 +68,12 @@ (try (let [[verb & args] the-args] (if-let [run (commands verb)] + (apply run args) (do - (apply run args) - (exit 0)) - (do - (if verb (printf "%s is not a command.\n" verb)) + (when verb (printf "%s is not a command.\n" verb)) (help) (exit 1)))) (catch Throwable t (println (.getMessage t)) - (exit 1)))) + (exit 1))) + (exit 0)) diff --git a/api/src/wfl/mime_type.clj b/api/src/wfl/mime_type.clj index 9d6a3e88e..493ee3250 100644 --- a/api/src/wfl/mime_type.clj +++ b/api/src/wfl/mime_type.clj @@ -1,6 +1,5 @@ (ns wfl.mime-type - (:require [clojure.string :as str] - [ring.util.mime-type :as mime-type] + (:require [ring.util.mime-type :as mime-type] [wfl.util :as util])) (def ^:private mime-types @@ -20,7 +19,7 @@ "Look up the mime-type of the filename by file extension." [filename] (loop [filename (util/basename filename)] - (if-let [ext (util/extension filename)] + (when-let [ext (util/extension filename)] (or (mime-types ext) (recur (util/remove-extension filename)))))) (defn ext-mime-type diff --git a/api/src/wfl/module/all.clj b/api/src/wfl/module/all.clj index 32cbbd8f3..18624295c 100644 --- a/api/src/wfl/module/all.clj +++ b/api/src/wfl/module/all.clj @@ -1,11 +1,12 @@ (ns wfl.module.all "Some utilities shared across module namespaces." - (:require [clojure.pprint :refer [pprint]] - [clojure.string :as str] - [wfl.jdbc :as jdbc] + (:require [clojure.spec.alpha :as s] + [clojure.string :as str] + [wfl.jdbc :as jdbc] + [wfl.service.cromwell :as cromwell] [wfl.service.google.storage :as gcs] - [wfl.util :as util] - [wfl.wfl :as wfl]) + [wfl.util :as util] + [wfl.wfl :as wfl]) (:import [java.util UUID])) (defn throw-when-output-exists-already! @@ -88,3 +89,54 @@ (jdbc/execute! tx ["UPDATE workload SET pipeline = ?::pipeline WHERE id = ?" pipeline id]) (jdbc/db-do-commands tx [work]) [id table])) + +(defn has? + "Return a function that takes a map and returns the result of applying the + `predicate?` to the value at the `key` in `map`, if one exists." + [key predicate?] + (fn [map] + (when-let [value (get map key)] + (predicate? value)))) + +;; shared specs +(s/def ::base_file_name string?) +(s/def ::commit (s/and string? (comp (partial == 40) count))) +(s/def ::contamination_vcf string?) +(s/def ::contamination_vcf_index string?) +(s/def ::cram_ref_fasta string?) +(s/def ::cram_ref_fasta_index string?) +(s/def ::timestamp (s/or :instant inst? :datetime util/datetime-string?)) +(s/def ::created ::timestamp) +(s/def ::cromwell string?) +(s/def ::dataset string?) +(s/def ::dbsnp_vcf string?) +(s/def ::dbsnp_vcf_index string?) +(s/def ::environment string?) +(s/def ::finished ::timestamp) +(s/def ::input string?) +(s/def ::input_bam #(str/ends-with? % ".bam")) +(s/def ::input_cram #(str/ends-with? % ".cram")) +(s/def ::output string?) +(s/def ::pipeline string?) +(s/def ::project string?) +(s/def ::release string?) +(s/def ::status cromwell/status?) +(s/def ::started ::timestamp) +(s/def ::stopped ::timestamp) +(s/def ::table string?) +(s/def ::updated ::timestamp) +(s/def ::uuid util/uuid-string?) +(s/def ::uuid-kv (s/keys :req-un [::uuid])) +(s/def ::version string?) +(s/def ::wdl string?) +(s/def ::options map?) +(s/def ::common map?) + +(s/def ::entityType string?) +(s/def ::fromSource string?) +(s/def ::labels (s/* util/label?)) +(s/def ::name string?) +(s/def ::methodConfiguration (s/and string? util/terra-namespaced-name?)) +(s/def ::methodConfigurationVersion integer?) +(s/def ::watchers (s/* util/email-address?)) +(s/def ::workspace (s/and string? util/terra-namespaced-name?)) diff --git a/api/src/wfl/module/aou.clj b/api/src/wfl/module/aou.clj index 245c2628d..57cc750dc 100644 --- a/api/src/wfl/module/aou.clj +++ b/api/src/wfl/module/aou.clj @@ -1,13 +1,16 @@ (ns wfl.module.aou "Process Arrays for the All Of Us project." (:require [clojure.string :as str] - [clojure.tools.logging :as log] + [clojure.spec.alpha :as s] [wfl.api.workloads :as workloads :refer [defoverload]] [wfl.jdbc :as jdbc] + [wfl.log :as log] + [wfl.module.all :as all] [wfl.module.batch :as batch] [wfl.references :as references] [wfl.service.cromwell :as cromwell] [wfl.service.google.storage :as gcs] + [wfl.service.postgres :as postgres] [wfl.util :as util] [wfl.wfl :as wfl]) (:import [java.sql Timestamp] @@ -16,6 +19,18 @@ (def pipeline "AllOfUsArrays") +;; specs +(s/def ::analysis_version_number integer?) +(s/def ::chip_well_barcode string?) +(s/def ::append-to-aou-request (s/keys :req-un [::notifications ::all/uuid])) +(s/def ::append-to-aou-response (s/* ::workflow-inputs)) +(s/def ::workflow-inputs (s/keys :req-un [::analysis_version_number + ::chip_well_barcode])) + +(s/def ::notifications (s/* ::sample)) +(s/def ::sample (s/keys :req-un [::analysis_version_number + ::chip_well_barcode])) + (def workflow-wdl "The top-level WDL file and its version." {:release "Arrays_v2.3.0" @@ -157,7 +172,7 @@ Due to the continuous nature of the AoU dataflow, this function will only create a new workload table if it does not exist otherwise append records to the existing one." - [tx {:keys [creator executor pipeline project output] :as request}] + [tx {:keys [creator executor pipeline project output] :as _request}] (gcs/parse-gs-url output) (let [slashified-output (util/slashify output) {:keys [release path]} workflow-wdl @@ -266,11 +281,21 @@ (jdbc/insert-multi! tx items submitted-samples) submitted-samples))) +(defn ^:private aou-workflows + [tx {:keys [items] :as _workload}] + (batch/tag-workflows + (batch/pre-v0_4_0-deserialize-workflows (postgres/get-table tx items)))) + +(defn ^:private aou-workflows-by-status + [tx {:keys [items] :as _workload} status] + (batch/tag-workflows + (batch/pre-v0_4_0-deserialize-workflows + (batch/query-workflows-with-status tx items status)))) + (defmethod workloads/create-workload! pipeline [tx request] - (->> (add-aou-workload! tx request) - (workloads/load-workload-for-id tx))) + (workloads/load-workload-for-id tx (add-aou-workload! tx request))) (defoverload workloads/start-workload! pipeline start-aou-workload!) (defoverload workloads/stop-workload! pipeline batch/stop-workload!) @@ -285,6 +310,8 @@ (workloads/load-workload-for-id tx id))] (if (and started (not finished)) (update! workload) workload))) -(defoverload workloads/workflows pipeline batch/pre-v0_4_0-load-workflows) -(defoverload workloads/load-workload-impl pipeline batch/load-batch-workload-impl) -(defoverload workloads/to-edn pipeline batch/workload-to-edn) +(defoverload workloads/workflows pipeline aou-workflows) +(defoverload workloads/workflows-by-status pipeline aou-workflows-by-status) +(defoverload workloads/retry pipeline batch/retry-unsupported) +(defoverload workloads/load-workload-impl pipeline batch/load-batch-workload-impl) +(defoverload workloads/to-edn pipeline batch/workload-to-edn) diff --git a/api/src/wfl/module/arrays.clj b/api/src/wfl/module/arrays.clj deleted file mode 100644 index 7aed59d01..000000000 --- a/api/src/wfl/module/arrays.clj +++ /dev/null @@ -1,166 +0,0 @@ -(ns wfl.module.arrays - "Process Arrays for the Broad Genomics Platform." - (:require [clojure.data.json :as json] - [clojure.string :as str] - [wfl.api.workloads :as workloads :refer [defoverload]] - [wfl.jdbc :as jdbc] - [wfl.module.batch :as batch] - [wfl.references :as references] - [wfl.service.firecloud :as firecloud] - [wfl.service.postgres :as postgres] - [wfl.util :as util]) - (:import [java.time OffsetDateTime])) - -(def pipeline "GPArrays") - -(def methodconfig-name "Arrays") - -(def workflow-wdl - "The top-level WDL file and its version." - {:release "Arrays_v2.3.0" - :path "pipelines/broad/arrays/single_sample/Arrays.wdl"}) - -(def primary-keys - "An arrays workflow can be uniquely identified by its `chip_well_barcode` and - `analysis_version_number`. Consequently, these are the primary keys in the - database." - [:chip_well_barcode :analysis_version_number]) - -(def fingerprinting - "Fingerprinting inputs for arrays." - {:haplotype_database_file "gs://gcp-public-data--broad-references/hg19/v0/Homo_sapiens_assembly19.haplotype_database.txt" - :variant_rsids_file "gs://broad-references-private/hg19/v0/Homo_sapiens_assembly19.haplotype_database.snps.list"}) - -(def other-inputs - "Miscellaneous inputs for arrays." - {:contamination_controls_vcf nil - :subsampled_metrics_interval_list nil - :disk_size 100 - :preemptible_tries 3}) - -(def ^:private known-cromwells - ["https://cromwell-gotc-auth.gotc-dev.broadinstitute.org" - "https://cromwell-aou.gotc-prod.broadinstitute.org"]) - -(def ^:private inputs+options - [{:environment "dev" - :vault_token_path "gs://broad-dsp-gotc-arrays-dev-tokens/arrayswdl.token"} - {:environment "prod" - :vault_token_path "gs://broad-dsp-gotc-arrays-prod-tokens/arrayswdl.token"}]) - -;; visible for testing -(defn cromwell->inputs+options - "Map cromwell URL to workflow inputs and options for submitting a GP Arrays workflow. - The returned environment string here is just a default, input file may specify override." - [url] - ((zipmap known-cromwells inputs+options) (util/de-slashify url))) - -(defn get-per-sample-inputs - "Throw or return per-sample INPUTS." - [inputs] - (let [mandatory-keys [:analysis_version_number - :bead_pool_manifest_file - :call_rate_threshold - :chip_well_barcode - :cluster_file - :extended_chip_manifest_file - :fingerprint_genotypes_vcf_file - :fingerprint_genotypes_vcf_index_file - :green_idat_cloud_path - :params_file - :red_idat_cloud_path - :reported_gender - :sample_alias - :sample_lsid] - optional-keys [;; genotype concordance inputs - :control_sample_vcf_file - :control_sample_vcf_index_file - :control_sample_intervals_file - :control_sample_name - :genotype_concordance_threshold - ;; cloud path of a thresholds file to be used with zCall - :zcall_thresholds_file - ;; cloud path of the Illumina gender cluster file - :gender_cluster_file - ;; arbitrary path to be used by BAFRegress - :minor_allele_frequency_file] - mandatory (select-keys inputs mandatory-keys) - optional (select-keys inputs optional-keys) - missing (vec (keep (fn [k] (when (nil? (k mandatory)) k)) mandatory-keys))] - (when (seq missing) - (throw (Exception. (format "Missing per-sample inputs: %s" missing)))) - (merge optional mandatory))) - -(defn make-inputs - "Return inputs for arrays processing in Cromwell given URL from PER-SAMPLE-INPUTS." - [url per-sample-inputs] - (-> (merge references/hg19-arrays-references - fingerprinting - other-inputs - (cromwell->inputs+options url) - (get-per-sample-inputs per-sample-inputs)) - (util/prefix-keys :Arrays.))) - -;; The table is named with the id generated by the jdbc/insert! -;; so this needs to update the workload table inline after creating the -;; GPArrays table, so far we cannot find a better way to bypass -;; https://www.postgresql.org/docs/current/datatype-numeric.html#DATATYPE-SERIAL -;; -(defn add-arrays-workload! - "Use transaction TX to add the workload described by REQUEST." - [tx {:keys [items] :as request}] - (let [[id table] (batch/add-workload-table! tx workflow-wdl request)] - (letfn [(form [m id] (-> m - (update :inputs json/write-str) - (assoc :id id)))] - (jdbc/insert-multi! tx table (map form items (range)))) - id)) - -(defn start-arrays-workload! - "Use transaction TX to start the WORKLOAD." - [tx {:keys [items project uuid] :as workload}] - (let [now (OffsetDateTime/now) - methodconfig-ns (first (str/split project #"/")) - methodconfig (str/join "/" [methodconfig-ns methodconfig-name])] - (letfn [(submit! [{:keys [id inputs] :as _workflow}] - (let [entity (mapv inputs [:entity-type :entity-name])] - [id (firecloud/create-submission project methodconfig entity)])) - (update! [tx [id {:keys [submissionId]}]] - (jdbc/update! tx items - {:updated now :uuid submissionId :status "Submitted"} - ["id = ?" id]))] - (let [ids-uuids (map submit! (workloads/workflows tx workload))] - (run! (partial update! tx) ids-uuids) - (jdbc/update! tx :workload {:started now} ["uuid = ?" uuid]))))) - -(def update-terra-workflow-statuses! - "Use `tx` to update `status` of Terra `workflows` in a `workload`." - (letfn [(get-terra-status [{:keys [project]} workflow] - (firecloud/get-workflow-status-by-entity project workflow))] - (batch/make-update-workflows get-terra-status))) - -(defmethod workloads/create-workload! - pipeline - [tx request] - (->> (add-arrays-workload! tx request) - (workloads/load-workload-for-id tx))) - -(defmethod workloads/start-workload! - pipeline - [tx {:keys [id] :as workload}] - (start-arrays-workload! tx workload) - (workloads/load-workload-for-id tx id)) - -(defmethod workloads/update-workload! - pipeline - [tx {:keys [started finished] :as workload}] - (letfn [(update! [{:keys [id] :as workload}] - (update-terra-workflow-statuses! tx workload) - (batch/update-workload-status! tx workload) - (workloads/load-workload-for-id tx id))] - (if (and started (not finished)) (update! workload) workload))) - -(defoverload workloads/load-workload-impl pipeline batch/load-batch-workload-impl) -(defoverload workloads/stop-workload! pipeline batch/stop-workload!) -(defoverload workloads/workflows pipeline batch/workflows) -(defoverload workloads/to-edn pipeline batch/workload-to-edn) diff --git a/api/src/wfl/module/batch.clj b/api/src/wfl/module/batch.clj index b65a24517..71f7bf692 100644 --- a/api/src/wfl/module/batch.clj +++ b/api/src/wfl/module/batch.clj @@ -1,18 +1,60 @@ (ns wfl.module.batch "Some utilities shared between batch workloads in cromwell." (:require [clj-http.client :as http] + [clojure.spec.alpha :as s] [clojure.string :as str] [wfl.api.workloads :as workloads] [wfl.auth :as auth] [wfl.jdbc :as jdbc] + [wfl.module.all :as all] [wfl.service.cromwell :as cromwell] [wfl.service.postgres :as postgres] + [wfl.sink :as sink] + [wfl.source :as source] [wfl.util :as util] [wfl.wfl :as wfl]) (:import [java.time OffsetDateTime] [java.util UUID] [wfl.util UserException])) +;;specs +(s/def ::executor string?) +(s/def ::creator string?) + +;; This is the wrong thing to do. See [1] for more information. +;; As a consequence, I've included the keys for a covid pipeline as optional +;; inputs for batch workloads so that these keys are not removed during +;; coercion. +;; [1]: https://github.com/metosin/reitit/issues/494 +(s/def ::workload-request + (s/keys :opt-un [::all/common + ::all/input + :wfl.api.spec/items + ::all/labels + ::all/output + ::sink/sink + ::source/source + ::all/watchers] + :req-un [(or ::all/cromwell ::executor) + ::all/pipeline + ::all/project])) + +(s/def ::workload-response (s/keys :opt-un [::all/finished + ::all/input + ::all/started + ::all/stopped + ::all/wdl] + :req-un [::all/commit + ::all/created + ::creator + ::executor + ::all/output + ::all/pipeline + ::all/project + ::all/release + ::all/uuid + ::all/version])) + (defn ^:private cromwell-status "`status` of the workflow with `uuid` in `cromwell`." [cromwell uuid] @@ -22,11 +64,9 @@ util/parse-json :status)) -(def ^:private finished? - "Test if a workflow `:status` is in a terminal state." - (set (conj cromwell/final-statuses "skipped"))) - -(defn make-update-workflows [get-status!] +(defn make-update-workflows + "Call `get-status!` under `tx` to update workflow statuses in `workload`." + [get-status!] (fn [tx {:keys [items] :as workload}] (letfn [(update! [{:keys [id uuid]} status] (jdbc/update! tx items @@ -36,21 +76,21 @@ ["id = ?" id]))] (->> (workloads/workflows tx workload) (remove (comp nil? :uuid)) - (remove (comp finished? :status)) + (remove (comp cromwell/final? :status)) (run! #(update! % (get-status! workload %))))))) (def update-workflow-statuses! - "Use `tx` to update `status` of Cromwell `workflows` in a `workload`." - (letfn [(get-cromwell-status [{:keys [executor]} {:keys [uuid]}] - (if (util/uuid-nil? uuid) - "skipped" - (cromwell-status executor uuid)))] + "Update the status of `_workflow` in `workload`." + (letfn [(get-cromwell-status [{:keys [executor] :as _workload} + {:keys [uuid] :as _workflow}] + (cromwell-status executor uuid))] (make-update-workflows get-cromwell-status))) (defn batch-update-workflow-statuses! "Use `tx` to update the `status` of the workflows in `_workload`." [tx {:keys [executor uuid items] :as _workoad}] - (let [uuid->status (->> {:label (str "workload:" uuid) :includeSubworkflows "false"} + (let [uuid->status (->> {:includeSubworkflows "false" + :label (str "workload:" uuid)} (cromwell/query executor) (map (juxt :id :status)))] (letfn [(update! [[uuid status]] @@ -61,10 +101,10 @@ (defn active-workflows "Use `tx` to query all the workflows in `_workload` whose :status is not in - `finished?`" + `final?`" [tx {:keys [items] :as _workload}] (let [query "SELECT id FROM %s WHERE status IS NULL OR status NOT IN %s"] - (->> (util/to-quoted-comma-separated-list finished?) + (->> (util/to-quoted-comma-separated-list cromwell/final?) (format query items) (jdbc/query tx)))) @@ -100,24 +140,6 @@ [_ workload] (into {:type :workload} (filter second workload))) -(defn pre-v0_4_0-load-workflows - [tx workload] - (letfn [(split-inputs [m] - (let [keep [:id :finished :status :updated :uuid :options]] - (assoc (select-keys m keep) :inputs (apply dissoc m keep)))) - (load-options [m] (update m :options (fnil util/parse-json "null")))] - (->> (postgres/get-table tx (:items workload)) - (mapv (comp util/unnilify split-inputs load-options))))) - -(defn ^:private load-batch-workflows - "Use transaction `tx` to load the workflows in the `_workload` stored in a - CromwellWorkflow table." - [tx {:keys [items] :as _workload}] - (letfn [(load-inputs [m] (update m :inputs (fnil util/parse-json "null"))) - (load-options [m] (update m :options (fnil util/parse-json "null")))] - (->> (postgres/get-table tx items) - (mapv (comp util/unnilify load-options load-inputs))))) - (defn submit-workload! "Submit the `workflows` to Cromwell with `url`." [{:keys [uuid labels] :as _workload} @@ -142,7 +164,9 @@ (merge cromwell-label {:workload uuid} - (into {} (map #(-> (str/split % #":" 2) (update 0 keyword)) labels))))))] + (->> labels + (map #(-> % (str/split #":" 2) (update 0 keyword))) + (into {}))))))] (->> workflows (group-by :options) (mapcat submit-batch!)))) @@ -170,14 +194,57 @@ {:workload workload}))) (if-not (or stopped finished) (stop! workload) workload))) +(defn pre-v0_4_0-deserialize-workflows + [workflows] + (letfn [(split-inputs [m] + (let [keep [:id :finished :status :updated :uuid :options]] + (assoc (select-keys m keep) :inputs (apply dissoc m keep)))) + (load-options [m] (update m :options (fnil util/parse-json "null")))] + (mapv (comp util/unnilify split-inputs load-options) workflows))) + +(defn ^:private post-v0_4_0-deserialize-workflows + [workflows] + (letfn [(load-inputs [m] (update m :inputs (fnil util/parse-json "null"))) + (load-options [m] (update m :options (fnil util/parse-json "null")))] + (mapv (comp util/unnilify load-options load-inputs) workflows))) + +(defn ^:private deserialize-workflows + [workload records] + (if (workloads/saved-before? "0.4.0" workload) + (pre-v0_4_0-deserialize-workflows records) + (post-v0_4_0-deserialize-workflows records))) + +(defn tag-workflows + "Associate the :batch-workflow :type in all `workflows`." + [workflows] + (map #(assoc % :type :batch-workflow) workflows)) + +(defn query-workflows-with-status + "Return the workflows in the items `table` that match `status`." + [tx table status] + (postgres/throw-unless-table-exists tx table) + (let [query-str "SELECT * FROM %s WHERE status = ? ORDER BY id ASC"] + (jdbc/query tx [(format query-str table) status]))) + (defn workflows "Return the workflows managed by the `workload`." - [tx workload] - (map - #(assoc % :type :batch-workflow) - (if (workloads/saved-before? "0.4.0" workload) - (pre-v0_4_0-load-workflows tx workload) - (load-batch-workflows tx workload)))) + [tx {:keys [items] :as workload}] + (tag-workflows + (deserialize-workflows workload (postgres/get-table tx items)))) + +(defn workflows-by-status + "Return the workflows managed by the `workload` matching `status`." + [tx {:keys [items] :as workload} status] + (tag-workflows + (deserialize-workflows + workload + (query-workflows-with-status tx items status)))) + +(defn retry-unsupported + [workload _] + (throw (UserException. "Cannot retry workflows - operation unsupported." + {:workload (util/to-edn workload) + :status 501}))) (defmethod util/to-edn :batch-workflow [workflow] (dissoc workflow :id :type)) diff --git a/api/src/wfl/module/copyfile.clj b/api/src/wfl/module/copyfile.clj index eb8939db4..b4663eb17 100644 --- a/api/src/wfl/module/copyfile.clj +++ b/api/src/wfl/module/copyfile.clj @@ -1,6 +1,7 @@ (ns wfl.module.copyfile "A dummy module for smoke testing wfl/cromwell auth." (:require [clojure.data.json :as json] + [clojure.spec.alpha :as s] [clojure.string :as str] [wfl.api.workloads :as workloads :refer [defoverload]] [wfl.jdbc :as jdbc] @@ -11,6 +12,11 @@ (def pipeline "copyfile") +;; specs +(s/def ::workflow-inputs (s/keys :req-un [::dst ::src])) +(s/def ::dst string?) +(s/def ::src string?) + (def workflow-wdl {:repo "wfl" :release "v0.4.2" @@ -22,7 +28,7 @@ (cromwell/submit-workflow url workflow-wdl - (-> inputs (util/prefix-keys (str pipeline "."))) + (util/prefix-keys inputs (str pipeline ".")) options labels)) @@ -101,9 +107,8 @@ (defn create-copyfile-workload! "Use transaction TX to add the workload described by REQUEST." [tx {:keys [items common] :as request}] - (letfn [(nil-if-empty [x] (if (empty? x) nil x)) - (merge-to-json [shared specific] - (json/write-str (nil-if-empty (util/deep-merge shared specific)))) + (letfn [(merge-to-json [shared specific] + (json/write-str (not-empty (util/deep-merge shared specific)))) (serialize [workflow id] (-> workflow (assoc :id id) @@ -141,8 +146,10 @@ (start-copyfile-workload! tx workload) (workloads/load-workload-for-id tx id))) -(defoverload workloads/update-workload! pipeline batch/update-workload!) -(defoverload workloads/stop-workload! pipeline batch/stop-workload!) -(defoverload workloads/load-workload-impl pipeline batch/load-batch-workload-impl) -(defoverload workloads/workflows pipeline batch/workflows) -(defoverload workloads/to-edn pipeline batch/workload-to-edn) +(defoverload workloads/update-workload! pipeline batch/update-workload!) +(defoverload workloads/stop-workload! pipeline batch/stop-workload!) +(defoverload workloads/load-workload-impl pipeline batch/load-batch-workload-impl) +(defoverload workloads/workflows pipeline batch/workflows) +(defoverload workloads/workflows-by-status pipeline batch/workflows-by-status) +(defoverload workloads/retry pipeline batch/retry-unsupported) +(defoverload workloads/to-edn pipeline batch/workload-to-edn) diff --git a/api/src/wfl/module/covid.clj b/api/src/wfl/module/covid.clj index 83eb1e75c..f8c060767 100644 --- a/api/src/wfl/module/covid.clj +++ b/api/src/wfl/module/covid.clj @@ -1,125 +1,49 @@ (ns wfl.module.covid "Manage the Sarscov2IlluminaFull pipeline." - (:require [clojure.data :as data] - [clojure.edn :as edn] - [clojure.set :as set] - [clojure.string :as str] - [clojure.tools.logging :as log] - [wfl.api.workloads :as workloads :refer [defoverload]] - [wfl.jdbc :as jdbc] - [wfl.service.datarepo :as datarepo] - [wfl.service.firecloud :as firecloud] + (:require [clojure.spec.alpha :as s] + [wfl.api.workloads :as workloads :refer [defoverload]] + [wfl.executor :as executor] + [wfl.jdbc :as jdbc] + [wfl.module.all :as all] [wfl.service.postgres :as postgres] - [wfl.service.rawls :as rawls] - [wfl.util :as util :refer [do-or-nil]] - [wfl.wfl :as wfl]) - (:import [clojure.lang ExceptionInfo] - [java.sql Timestamp] - [java.time OffsetDateTime ZoneId] - [java.time.format DateTimeFormatter] - [java.util UUID] + [wfl.sink :as sink] + [wfl.source :as source] + [wfl.stage :as stage] + [wfl.util :as util :refer [utc-now]] + [wfl.wfl :as wfl]) + (:import [java.util UUID] [wfl.util UserException])) (def pipeline nil) -;; interfaces -;; queue operations -(defmulti peek-queue! - "Peek the first object from the `queue`, if one exists." - (fn [queue] (:type queue))) - -(defmulti pop-queue! - "Pop the first object from the `queue`. Throws if none exists." - (fn [queue] (:type queue))) - -(defmulti queue-length! - "Return the number of objects in the queue." - (fn [queue] (:type queue))) - -;; validation operations -(defmulti validate-or-throw - "Validate the `request` request." - (fn [request] (:name request))) - -(defmethod validate-or-throw :default - [{:keys [name] :as request}] - (throw (UserException. "Invalid request - unknown name" - (util/make-map name request)))) - -;; source operations -(defmulti create-source! - "Use `tx` and workload `id` to write the source to persisted storage and - return a [type item] pair to be written into the parent table." - (fn [tx id source-request] (:name source-request))) - -(defmulti load-source! - "Use `tx` to load the workload source with `source_type`." - (fn [tx workload] (:source_type workload))) - -(defmulti start-source! - "Use `tx` to start accepting data from the `source`." - (fn [tx source] (:type source))) - -(defmulti update-source! - "Update the source." - (fn [source] (:type source))) - -(defmulti stop-source! - "Use `tx` to stop accepting new data from the `source`." - (fn [tx source] (:type source))) - -;; executor operations -(defmulti create-executor! - "Use `tx` and workload `id` to write the executor to persisted storage and - return a [type item] pair to be written into the parent table." - (fn [tx id executor-request] (:name executor-request))) - -(defmulti update-executor! - "Update the executor with the `source`" - (fn [source executor] (:type executor))) - -(defmulti executor-workflows - "Use `tx` to return the workflows created by the `executor" - (fn [tx executor] (:type executor))) - -(defmulti load-executor! - "Use `tx` to load the workload executor with `executor_type`." - (fn [tx workload] (:executor_type workload))) - -;; sink operations -(defmulti create-sink! - "Use `tx` and workload `id` to write the sink to persisted storage and - return a [type item] pair to be written into the parent table." - (fn [tx id sink-request] (:name sink-request))) - -(defmulti update-sink! - "Update the sink with the `executor`" - (fn [executor sink] (:type sink))) - -(defmulti load-sink! - "Use `tx` to load the workload sink with `sink_type`." - (fn [tx workload] (:sink_type workload))) - -;; Processing "stage" operations -(defmulti done? - "Test if the processing stage is complete and will not process any more data" - (fn [stage] (:type stage))) - -;; Generic helpers -(defn ^:private utc-now - "Return OffsetDateTime/now in UTC." - [] - (OffsetDateTime/now (ZoneId/of "UTC"))) - -(defn ^:private load-record-by-id! [tx table id] - (let [query "SELECT * FROM %s WHERE id = ? LIMIT 1" - [record & _] (jdbc/query tx [(format query table) id])] - (when-not record - (throw (ex-info (str "No such record") {:id id :table table}))) - record)) - +;; specs +(s/def ::executor (s/keys :req-un [::all/name + ::all/fromSource + ::all/methodConfiguration + ::all/methodConfigurationVersion + ::all/workspace])) +(s/def ::creator util/email-address?) +(s/def ::workload-request (s/keys :req-un [::executor + ::all/project + ::sink/sink + ::source/source] + :opt-un [::all/labels + ::all/watchers])) + +(s/def ::workload-response (s/keys :req-un [::all/created + ::creator + ::executor + ::all/labels + ::sink/sink + ::source/source + ::all/uuid + ::all/version + ::all/watchers] + :opt-un [::all/finished + ::all/started + ::all/stopped + ::all/updated])) ;; Workload - (defn ^:private patch-workload [tx {:keys [id]} colls] (jdbc/update! tx :workload colls ["id = ?" id])) @@ -171,21 +95,20 @@ (defn ^:private create-covid-workload [tx {:keys [source executor sink] :as request}] - (let [[source executor sink] (mapv validate-or-throw [source executor sink]) - id (add-workload-metadata tx request)] + (let [id (add-workload-metadata tx request)] (jdbc/execute! tx (concat [update-workload-query] - (create-source! tx id source) - (create-executor! tx id executor) - (create-sink! tx id sink) + (source/create-source! tx id source) + (executor/create-executor! tx id executor) + (sink/create-sink! tx id sink) [id])) (workloads/load-workload-for-id tx id))) (defn ^:private load-covid-workload-impl [tx {:keys [id] :as workload}] - (let [src-exc-sink {:source (load-source! tx workload) - :executor (load-executor! tx workload) - :sink (load-sink! tx workload)}] + (let [src-exc-sink {:source (source/load-source! tx workload) + :executor (executor/load-executor! tx workload) + :sink (sink/load-sink! tx workload)}] (as-> workload $ (select-keys $ workload-metadata-keys) (merge $ src-exc-sink) @@ -196,7 +119,7 @@ "Start creating and managing workflows from the source." [tx {:keys [started] :as workload}] (letfn [(start [{:keys [id source] :as workload} now] - (start-source! tx source) + (source/start-source! tx source) (patch-workload tx workload {:started now :updated now}) (workloads/load-workload-for-id tx id))] (if-not started (start workload (utc-now)) workload))) @@ -205,11 +128,11 @@ "Use transaction `tx` to update `workload` statuses." [tx {:keys [started finished] :as workload}] (letfn [(update! [{:keys [id source executor sink] :as workload} now] - (-> (update-source! source) - (update-executor! executor) - (update-sink! sink)) + (-> (source/update-source! source) + (executor/update-executor! executor) + (sink/update-sink! sink)) (patch-workload tx workload {:updated now}) - (when (every? done? [source executor sink]) + (when (every? stage/done? [source executor sink]) (patch-workload tx workload {:finished now})) (workloads/load-workload-for-id tx id))] (if (and started (not finished)) (update! workload (utc-now)) workload))) @@ -218,7 +141,7 @@ "Use transaction `tx` to stop the `workload` looking for new data." [tx {:keys [started stopped finished] :as workload}] (letfn [(stop! [{:keys [id source] :as workload} now] - (stop-source! tx source) + (source/stop-source! tx source) (patch-workload tx workload {:stopped now :updated now}) (when-not (:started workload) (patch-workload tx workload {:finished now})) @@ -228,6 +151,21 @@ {:workload workload}))) (if-not (or stopped finished) (stop! workload (utc-now)) workload))) +(defn ^:private retry-covid-workload + "Retry/resubmit the `workflows` managed by the `workload` and return the + workload that manages the new workflows." + [{:keys [started id executor] :as workload} workflows] + (when-not started + (throw (UserException. "Cannot retry workload before it's been started." + {:workload workload}))) + ;; TODO: validate workload's executor and sink objects. + ;; https://broadinstitute.atlassian.net/browse/GH-1421 + (executor/executor-retry-workflows! executor workflows) + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (when-not (stage/done? executor) + (patch-workload tx workload {:finished nil :updated (utc-now)})) + (workloads/load-workload-for-id tx id))) + (defn ^:private workload-to-edn [workload] (-> workload (util/select-non-nil-keys workload-metadata-keys) @@ -236,818 +174,16 @@ (update :executor util/to-edn) (update :sink util/to-edn))) -(defoverload workloads/create-workload! pipeline create-covid-workload) -(defoverload workloads/start-workload! pipeline start-covid-workload) -(defoverload workloads/update-workload! pipeline update-covid-workload) -(defoverload workloads/stop-workload! pipeline stop-covid-workload) -(defoverload workloads/load-workload-impl pipeline load-covid-workload-impl) -(defmethod workloads/workflows pipeline +(defoverload workloads/create-workload! pipeline create-covid-workload) +(defoverload workloads/start-workload! pipeline start-covid-workload) +(defoverload workloads/update-workload! pipeline update-covid-workload) +(defoverload workloads/stop-workload! pipeline stop-covid-workload) +(defoverload workloads/load-workload-impl pipeline load-covid-workload-impl) +(defmethod workloads/workflows pipeline [tx {:keys [executor] :as _workload}] - (executor-workflows tx executor)) + (executor/executor-workflows tx executor)) +(defmethod workloads/workflows-by-status pipeline + [tx {:keys [executor] :as _workload} status] + (executor/executor-workflows-by-status tx executor status)) +(defoverload workloads/retry pipeline retry-covid-workload) (defoverload workloads/to-edn pipeline workload-to-edn) - -;; Terra Data Repository Source -(def ^:private tdr-source-name "Terra DataRepo") -(def ^:private tdr-source-type "TerraDataRepoSource") -(def ^:private tdr-source-table "TerraDataRepoSource") -(def ^:private tdr-source-serialized-fields - {:dataset :dataset - :table :dataset_table - :column :table_column_name - :snapshotReaders :snapshot_readers}) - -(defn ^:private create-tdr-source [tx id request] - (let [create "CREATE TABLE %s OF TerraDataRepoSourceDetails (PRIMARY KEY (id))" - alter "ALTER TABLE %s ALTER COLUMN id ADD GENERATED ALWAYS AS IDENTITY" - details (format "%s_%09d" tdr-source-type id)] - (jdbc/db-do-commands tx [(format create details) (format alter details)]) - [tdr-source-type - (-> (select-keys request (keys tdr-source-serialized-fields)) - (update :dataset pr-str) - (set/rename-keys tdr-source-serialized-fields) - (assoc :details details) - (->> (jdbc/insert! tx tdr-source-table) first :id str))])) - -(defn ^:private load-tdr-source [tx {:keys [source_items] :as workload}] - (if-let [id (util/parse-int source_items)] - (-> (load-record-by-id! tx tdr-source-table id) - (set/rename-keys (set/map-invert tdr-source-serialized-fields)) - (assoc :type tdr-source-type) - (update :dataset edn/read-string)) - (throw (ex-info "source_items is not an integer" {:workload workload})))) - -(defn ^:private id-and-name [dataset] - (select-keys dataset [:id :name])) - -(defn ^:private throw-unless-column-exists - "Throw if `table` does not have `column` in `dataset`." - [table column dataset] - (when (->> table :columns (filter (comp #{column} :name)) empty?) - (throw (UserException. "Column not found" - {:column column - :table table - :dataset (id-and-name dataset)})))) - -(defn ^:private get-table-or-throw - "Throw or return the table from `dataset`" - [table-name dataset] - (let [[table & _] (->> (get-in dataset [:schema :tables]) - (filter (comp #{table-name} :name)))] - (when-not table - (throw (UserException. "Table not found" - {:table table-name - :dataset (id-and-name dataset)}))) - table)) - -(defn ^:private get-dataset-or-throw - "Return the dataset with `dataset-id` or throw" - [dataset-id] - (try - (datarepo/dataset dataset-id) - (catch ExceptionInfo e - (throw - (UserException. "Cannot access dataset" - {:dataset dataset-id :status (-> e ex-data :status)} - e))))) - -(defn verify-data-repo-source! - "Verify that the `dataset` exists and that WFL has the necessary permissions - to read it." - [{:keys [dataset table column skipValidation] :as source}] - (if skipValidation - source - (let [dataset (get-dataset-or-throw dataset)] - (-> (get-table-or-throw table dataset) - (throw-unless-column-exists column dataset)) - (assoc source :dataset dataset)))) - -(defn ^:private find-new-rows - "Find new rows in TDR by querying the dataset between the `interval`." - [{:keys [dataset table column] :as _source} interval] - (-> dataset - (datarepo/query-table-between table column interval [:datarepo_row_id]) - :rows - flatten)) - -(defn ^:private go-create-snapshot! - "Create snapshot in TDR from `dataset` body, `table` and `row-ids` then - write job info as well as rows into `source-details-name` table. - Snapshots will be readable by members of the `snapshotReaders` list. - `suffix` will be appended to the snapshot names." - [suffix {:keys [dataset table snapshotReaders] :as _source} row-ids] - (let [columns (->> (datarepo/all-columns dataset table) - (mapv :name) - (cons "datarepo_row_id"))] - (-> (datarepo/make-snapshot-request dataset columns table row-ids) - (update :name #(str % suffix)) - (assoc :readers snapshotReaders) - datarepo/create-snapshot-job))) - -(defn ^:private create-snapshots - "Create uniquely named snapshots in TDR with max partition size of 500, - using the frozen `now-obj`, from `row-ids`, return shards and TDR job-ids." - [source now-obj row-ids] - (let [dt-format (DateTimeFormatter/ofPattern "YYYYMMdd'T'HHmmss") - compact-now (.format now-obj dt-format)] - (letfn [(create-snapshot [idx shard] - [shard (-> (format "_%s_%s" compact-now idx) - (go-create-snapshot! source shard))])] - (->> row-ids - (partition-all 500) - (map vec) - (map-indexed create-snapshot))))) - -(defn ^:private get-pending-tdr-jobs [{:keys [details] :as _source}] - (let [query "SELECT id, snapshot_creation_job_id FROM %s - WHERE snapshot_creation_job_status = 'running' - ORDER BY id ASC"] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> (format query details) - (jdbc/query tx) - (map (juxt :id :snapshot_creation_job_id)))))) - -(defn ^:private check-tdr-job - "Check TDR job status for `job-id`, return a map with job-id, - snapshot_id and job_status if job has failed or succeeded, otherwise nil." - [job-id] - (let [{:keys [job_status] :as result} (datarepo/get-job-metadata job-id)] - (case job_status - "running" result - "succeeded" (assoc result :snapshot_id (:id (datarepo/get-job-result job-id))) - (do (log/warnf "Snapshot creation job %s failed!" job-id) - result)))) - -(defn ^:private write-snapshot-id - "Write `snapshot_id` and `job_status` into source `details` table - from the `_tdr-job-metadata` map, update timestamp with real now." - [{:keys [details] :as _source} - [id {:keys [job_status snapshot_id] :as _tdr-job-metadata}]] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (jdbc/update! tx details {:snapshot_creation_job_status job_status - :snapshot_id snapshot_id - :updated (utc-now)} - ["id = ?" id]))) - -(defn ^:private write-snapshots-creation-jobs - "Write the shards and corresponding snapshot creation jobs from - `shards->snapshot-jobs` into source `details` table, with the frozen `now`. - Also initialize all jobs statuses to running." - [{:keys [last_checked details] :as _source} now shards->snapshot-jobs] - (letfn [(make-record [[shard id]] - {:snapshot_creation_job_id id - :snapshot_creation_job_status "running" - :datarepo_row_ids shard - :start_time last_checked - :end_time now})] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> (map make-record shards->snapshot-jobs) - (jdbc/insert-multi! tx details))))) - -(defn ^:private update-last-checked - "Update the `last_checked` field in source table with - the frozen `now`." - ([tx {:keys [id] :as _source} now] - (jdbc/update! tx tdr-source-table {:last_checked now} ["id = ?" id])) - ([source now] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (update-last-checked tx source now)))) - -(defn ^:private timestamp-to-offsetdatetime [^Timestamp t] - "Parse the Timestamp `t` into an `OffsetDateTime`." - (OffsetDateTime/ofInstant (.toInstant t) (ZoneId/of "UTC"))) - -(def ^:private bigquery-datetime-format - (DateTimeFormatter/ofPattern "yyyy-MM-dd'T'HH:mm:ss")) - -(defn ^:private find-and-snapshot-new-rows - "Create and enqueue snapshots from new rows in the `source` dataset." - [{:keys [last_checked] :as source} utc-now] - (let [shards->jobs (->> [(timestamp-to-offsetdatetime last_checked) utc-now] - (mapv #(.format % bigquery-datetime-format)) - (find-new-rows source) - (create-snapshots source utc-now))] - (when (seq shards->jobs) - (write-snapshots-creation-jobs source utc-now shards->jobs) - (update-last-checked source utc-now)))) - -(defn ^:private update-pending-snapshot-jobs - "Update the status of TDR snapshot jobs that are still 'running'." - [source] - (->> (get-pending-tdr-jobs source) - (map #(update % 1 check-tdr-job)) - (run! #(write-snapshot-id source %)))) - -(defn ^:private update-tdr-source - "Check for new data in TDR from `source`, create new snapshots, - insert resulting job creation ids into database and update the - timestamp for next time." - [{:keys [stopped] :as source}] - (when-not stopped - (find-and-snapshot-new-rows source (utc-now))) - (update-pending-snapshot-jobs source) - ;; load and return the source table - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (load-tdr-source tx {:source_items (str (:id source))}))) - -(defn ^:private start-tdr-source [tx source] - (update-last-checked tx source (utc-now))) - -(defn ^:private stop-tdr-source [tx {:keys [id] :as _source}] - (jdbc/update! tx tdr-source-table {:stopped (utc-now)} ["id = ?" id])) - -(defn ^:private peek-tdr-source-details - "Get first unconsumed snapshot record from `details` table." - [{:keys [details] :as _source}] - (let [query "SELECT * FROM %s - WHERE consumed IS NULL - AND snapshot_id IS NOT NULL - ORDER BY id ASC - LIMIT 1"] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> (format query details) - (jdbc/query tx) - first)))) - -(defn ^:private peek-tdr-source-queue - "Get first unconsumed snapshot from `source` queue." - [source] - (if-let [{:keys [snapshot_id] :as _record} (peek-tdr-source-details source)] - (datarepo/snapshot snapshot_id))) - -(defn ^:private tdr-source-queue-length - "Return the number of unconsumed snapshot records from `details` table." - [{:keys [details] :as _source}] - (let [query "SELECT COUNT(*) FROM %s - WHERE consumed IS NULL - AND snapshot_creation_job_status <> 'failed'"] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> (format query details) - (jdbc/query tx) - first - :count)))) - -(defn ^:private pop-tdr-source-queue - "Consume first unconsumed snapshot record in `details` table, or throw if none." - [{:keys [details] :as source}] - (if-let [{:keys [id] :as _record} (peek-tdr-source-details source)] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (let [now (utc-now)] - (jdbc/update! tx details {:consumed now :updated now} ["id = ?" id]))) - (throw (ex-info "No snapshots in queue" {:source source})))) - -(defn ^:private tdr-source-done? [{:keys [stopped] :as source}] - (and stopped (zero? (queue-length! source)))) - -(defn ^:private tdr-source-to-edn [source] - (-> source - (util/select-non-nil-keys (keys tdr-source-serialized-fields)) - (update :dataset :id) - (assoc :name tdr-source-name))) - -(defoverload validate-or-throw tdr-source-name verify-data-repo-source!) - -(defoverload create-source! tdr-source-name create-tdr-source) -(defoverload start-source! tdr-source-type start-tdr-source) -(defoverload update-source! tdr-source-type update-tdr-source) -(defoverload stop-source! tdr-source-type stop-tdr-source) - -(defoverload load-source! tdr-source-type load-tdr-source) -(defoverload peek-queue! tdr-source-type peek-tdr-source-queue) -(defoverload pop-queue! tdr-source-type pop-tdr-source-queue) -(defoverload queue-length! tdr-source-type tdr-source-queue-length) - -(defoverload done? tdr-source-type tdr-source-done?) - -(defoverload util/to-edn tdr-source-type tdr-source-to-edn) - -;; TDR Snapshot List Source -(def ^:private tdr-snapshot-list-name "TDR Snapshots") -(def ^:private tdr-snapshot-list-type "TDRSnapshotListSource") - -(defn ^:private validate-tdr-snapshot-list - [{:keys [skipValidation] :as source}] - (letfn [(snapshot-or-throw [snapshot-id] - (try - (datarepo/snapshot snapshot-id) - (catch ExceptionInfo e - (throw (UserException. "Cannot access snapshot" - {:snapshot snapshot-id - :status (-> e ex-data :status)} - e)))))] - (if skipValidation - source - (update source :snapshots #(mapv snapshot-or-throw %))))) - -(defn ^:private create-tdr-snapshot-list [tx id {:keys [snapshots] :as _request}] - (let [create "CREATE TABLE %s OF ListSource (PRIMARY KEY (id))" - alter "ALTER TABLE %s ALTER COLUMN id ADD GENERATED ALWAYS AS IDENTITY" - details (format "%s_%09d" tdr-snapshot-list-type id)] - (jdbc/db-do-commands tx [(format create details) (format alter details)]) - (jdbc/insert-multi! tx details (map #(-> {:item (pr-str %)}) snapshots)) - [tdr-snapshot-list-type details])) - -(defn ^:private load-tdr-snapshot-list - [tx {:keys [source_items] :as _workload}] - (when-not (postgres/table-exists? tx source_items) - (throw (ex-info "Failed to load tdr-snapshot-list: no such table" - {:table source_items}))) - {:type tdr-snapshot-list-type - :items source_items - :snapshots (postgres/get-table tx source_items)}) - -(defn ^:private start-tdr-snapshot-list [_ source] source) -(defn ^:private stop-tdr-snapshot-list [_ source] source) -(defn ^:private update-tdr-snapshot-list [source] source) - -(defn ^:private peek-tdr-snapshot-list [{:keys [items] :as _source}] - (let [query "SELECT * FROM %s - WHERE consumed IS NULL - ORDER BY id ASC - LIMIT 1"] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> (format query items) - (jdbc/query tx) - first)))) - -(defn ^:private tdr-snapshot-list-queue-length [{:keys [items] :as _source}] - (let [query "SELECT COUNT (*) FROM %s WHERE consumed IS NULL"] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> (format query items) - (jdbc/query tx) - first - :count)))) - -(defn ^:private pop-tdr-snapshot-list [{:keys [items] :as source}] - (if-let [{:keys [id]} (peek-tdr-snapshot-list source)] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (jdbc/update! tx items {:consumed (utc-now)} ["id = ?" id])) - (throw (ex-info "Attempt to pop empty queue" {:source source})))) - -(defn ^:private tdr-snapshot-list-done? [source] - (zero? (queue-length! source))) - -(defn ^:private tdr-snapshot-list-to-edn [source] - (let [read-snapshot-id (comp :id edn/read-string :item)] - (-> (select-keys source [:snapshots]) - (assoc :name tdr-snapshot-list-name) - (update :snapshots #(map read-snapshot-id %))))) - -(defoverload validate-or-throw tdr-snapshot-list-name validate-tdr-snapshot-list) - -(defoverload create-source! tdr-snapshot-list-name create-tdr-snapshot-list) -(defoverload start-source! tdr-snapshot-list-type start-tdr-snapshot-list) -(defoverload stop-source! tdr-snapshot-list-type stop-tdr-snapshot-list) -(defoverload update-source! tdr-snapshot-list-type update-tdr-snapshot-list) -(defoverload load-source! tdr-snapshot-list-type load-tdr-snapshot-list) - -(defoverload peek-queue! tdr-snapshot-list-type (comp edn/read-string :item peek-tdr-snapshot-list)) -(defoverload queue-length! tdr-snapshot-list-type tdr-snapshot-list-queue-length) -(defoverload pop-queue! tdr-snapshot-list-type pop-tdr-snapshot-list) - -(defoverload done? tdr-snapshot-list-type tdr-snapshot-list-done?) - -(defoverload util/to-edn tdr-snapshot-list-type tdr-snapshot-list-to-edn) - -;; Terra Executor -(def ^:private terra-executor-name "Terra") -(def ^:private terra-executor-type "TerraExecutor") -(def ^:private terra-executor-table "TerraExecutor") -(def ^:private terra-executor-serialized-fields - {:workspace :workspace - :methodConfiguration :method_configuration - :methodConfigurationVersion :method_configuration_version - :fromSource :from_source}) - -(defn ^:private create-terra-executor [tx id request] - (let [create "CREATE TABLE %s OF TerraExecutorDetails (PRIMARY KEY (id))" - alter "ALTER TABLE %s ALTER COLUMN id ADD GENERATED ALWAYS AS IDENTITY" - details (format "%s_%09d" terra-executor-type id)] - (jdbc/db-do-commands tx [(format create details) (format alter details)]) - [terra-executor-type - (-> (select-keys request (keys terra-executor-serialized-fields)) - (update :fromSource pr-str) - (set/rename-keys terra-executor-serialized-fields) - (assoc :details details) - (->> (jdbc/insert! tx terra-executor-table) first :id str))])) - -(defn ^:private load-terra-executor [tx {:keys [executor_items] :as workload}] - (if-let [id (util/parse-int executor_items)] - (-> (load-record-by-id! tx terra-executor-table id) - (assoc :type terra-executor-type) - (set/rename-keys (set/map-invert terra-executor-serialized-fields)) - (update :fromSource edn/read-string)) - (throw (ex-info "Invalid executor_items" {:workload workload})))) - -(defn ^:private workspace-or-throw [workspace] - (try - (firecloud/workspace workspace) - (catch ExceptionInfo cause - (throw (UserException. - "Cannot access workspace" - {:workspace workspace - :status (-> cause ex-data :status)} - cause))))) - -(defn ^:private method-config-or-throw [workspace methodconfig] - (try - (firecloud/get-method-configuration workspace methodconfig) - (catch ExceptionInfo cause - (throw (UserException. - "Cannot access method configuration in workspace" - {:workspace workspace - :methodConfiguration methodconfig - :status (-> cause ex-data :status)} - cause))))) - -(defn ^:private throw-on-method-config-version-mismatch - [{:keys [methodConfigVersion] :as methodconfig} expected] - (when-not (== expected methodConfigVersion) - (throw (UserException. - "Unexpected method configuration version" - {:methodConfiguration methodconfig - :expected expected - :actual methodConfigVersion})))) - -(defn verify-terra-executor - "Verify the method-configuration exists." - [{:keys [skipValidation - workspace - methodConfiguration - methodConfigurationVersion - fromSource] :as executor}] - (when-not skipValidation - (workspace-or-throw workspace) - (when-not (= "importSnapshot" fromSource) - (throw - (UserException. "Unsupported coercion" (util/make-map fromSource)))) - (-> (method-config-or-throw workspace methodConfiguration) - (throw-on-method-config-version-mismatch methodConfigurationVersion))) - executor) - -(defn ^:private from-source - "Coerce `source-item` to form understood by `executor` via `fromSource`." - [{:keys [workspace fromSource] :as executor} - {:keys [name id] :as _source-item}] - (cond (= "importSnapshot" fromSource) - (rawls/create-or-get-snapshot-reference workspace id name) - :else - (throw (ex-info "Unknown fromSource" {:executor executor})))) - -(defn ^:private update-method-configuration! - "Update `methodConfiguration` in `workspace` with snapshot reference `name` - as :dataReferenceName via Firecloud. - Update executor table record ID with incremented `methodConfigurationVersion`." - [{:keys [id - workspace - methodConfiguration - methodConfigurationVersion] :as _executor} - {:keys [name] :as _reference}] - (let [current (method-config-or-throw workspace methodConfiguration) - _ (throw-on-method-config-version-mismatch - current methodConfigurationVersion) - inc'd (inc methodConfigurationVersion)] - (->> (assoc current :dataReferenceName name :methodConfigVersion inc'd) - (firecloud/update-method-configuration workspace methodConfiguration)) - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (jdbc/update! tx terra-executor-table - {:method_configuration_version inc'd} - ["id = ?" id])))) - -(defn ^:private create-submission! - "Update `methodConfiguration` to use `reference`. - Create and return submission in `workspace` for `methodConfiguration` via Firecloud." - [{:keys [workspace methodConfiguration] :as executor} reference] - (update-method-configuration! executor reference) - (firecloud/submit-method workspace methodConfiguration)) - -(defn ^:private allocate-submission - "Write or allocate workflow records for `submission` in `details` table." - [{:keys [details] :as _executor} - {:keys [referenceId] :as _reference} - {:keys [submissionId workflows] :as _submission}] - (letfn [(to-row [now {:keys [status workflowId entityName] :as _workflow}] - {:reference referenceId - :submission submissionId - :workflow workflowId - :entity entityName - :status status - :updated now})] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> (map (partial to-row (utc-now)) workflows) - (jdbc/insert-multi! tx details))))) - -;; Workflows in newly created firecloud submissions may not have been scheduled -;; yet and thus do not have a workflow uuid. Thus, we first "allocate" the -;; workflow in the database and then later assign workflow uuids. -(defn ^:private update-unassigned-workflow-uuids! - "Assign workflow uuids from previous submissions" - [{:keys [workspace details] :as executor}] - (letfn [(read-a-submission-without-workflows [] - (let [query "SELECT id, submission, entity FROM %s - WHERE submission IN ( - SELECT submission FROM %s WHERE workflow IS NULL - LIMIT 1 - )"] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (let [records (jdbc/query tx (format query details details))] - (when-first [{:keys [submission]} records] - [submission records]))))) - (zip-record [{:keys [entity] :as record} - {:keys [workflowId workflowEntity status]}] - (when-not (= entity workflowEntity) - (throw (ex-info "Failed to write workflow uuid: entity did not match" - {:expected entity - :actual workflowEntity - :executor executor}))) - (assoc record :workflow workflowId :status status)) - (write-workflow-statuses [now records] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (run! - (fn [{:keys [id workflow status]}] - (jdbc/update! tx details - {:status status :workflow workflow :updated now} - ["id = ?" id])) - records)))] - (when-let [[submission records] (read-a-submission-without-workflows)] - (let [{:keys [workflows]} (firecloud/get-submission workspace submission)] - (when-not (== (count records) (count workflows)) - (throw (ex-info "Allocated more records than created workflows" - {:submission submission :executor executor}))) - (->> workflows - (map #(update % :workflowEntity :entityName)) - (sort-by :workflowEntity) - (map zip-record (sort-by :entity records)) - (write-workflow-statuses (utc-now))))))) - -(defn ^:private update-terra-workflow-statuses! - "Update statuses in DETAILS table for active or failed WORKSPACE workflows. - Return EXECUTOR." - [{:keys [workspace details] :as _executor}] - (letfn [(read-active-or-failed-workflows [] - (let [query "SELECT * FROM %s - WHERE submission IS NOT NULL - AND workflow IS NOT NULL - AND status NOT IN ('Succeeded', 'Aborted') - ORDER BY id ASC"] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (jdbc/query tx (format query details))))) - (update-status-from-firecloud - [{:keys [submission workflow] :as record}] - (->> (firecloud/get-workflow workspace submission workflow) - :status - (assoc record :status))) - (write-workflow-statuses [now records] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (run! - (fn [{:keys [id status] :as _record}] - (jdbc/update! tx details {:status status :updated now} - ["id = ?" id])) - (sort-by :entity records))))] - (->> (read-active-or-failed-workflows) - (mapv update-status-from-firecloud) - (write-workflow-statuses (utc-now))))) - -(defn ^:private update-terra-executor - "Create new submission from new `source` snapshot if available, - writing its workflows to `details` table. - Update statuses for active or failed workflows in `details` table. - Return `executor`." - [source executor] - (when-let [snapshot (peek-queue! source)] - (let [reference (from-source executor snapshot) - submission (create-submission! executor reference)] - (allocate-submission executor reference submission) - (pop-queue! source))) - (update-unassigned-workflow-uuids! executor) - (update-terra-workflow-statuses! executor) - executor) - -(defn ^:private combine-record-workflow-and-outputs - [{:keys [updated] :as _record} - {:keys [workflowName] :as workflow} - firecloud-outputs] - (let [prefix (str workflowName ".") - outputs (-> firecloud-outputs - (get-in [:tasks (keyword workflowName) :outputs]) - (util/unprefix-keys prefix))] - (-> (assoc workflow :updated updated :outputs outputs) - (update :inputs #(util/unprefix-keys % prefix)) - (set/rename-keys {:id :uuid}) - (util/select-non-nil-keys [:inputs :uuid :status :outputs :updated])))) - -(defn ^:private peek-terra-executor-details - "Get first unconsumed successful workflow record from `details` table." - [{:keys [details] :as _executor}] - (let [query "SELECT * FROM %s - WHERE consumed IS NULL - AND status = 'Succeeded' - ORDER BY id ASC - LIMIT 1"] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> (format query details) - (jdbc/query tx) - first)))) - -(defn ^:private peek-terra-executor-queue - "Get first unconsumed successful workflow from `executor` queue." - [{:keys [workspace] :as executor}] - (when-let [{:keys [submission workflow] :as record} - (peek-terra-executor-details executor)] - (combine-record-workflow-and-outputs - record - (firecloud/get-workflow workspace submission workflow) - (firecloud/get-workflow-outputs workspace submission workflow)))) - -(defn ^:private pop-terra-executor-queue - "Consume first unconsumed successful workflow record in `details` table, - or throw if none." - [{:keys [details] :as executor}] - (if-let [{:keys [id] :as _record} (peek-terra-executor-details executor)] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (let [now (utc-now)] - (jdbc/update! tx details {:consumed now :updated now} ["id = ?" id]))) - (throw (ex-info "No successful workflows in queue" {:executor executor})))) - -(defn ^:private terra-executor-queue-length - "Return the number workflows in the `_executor` queue that are yet to be - consumed." - [{:keys [details] :as _executor}] - (let [query "SELECT COUNT(*) FROM %s - WHERE consumed IS NULL - AND status NOT IN ('Failed', 'Aborted')"] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> (format query details) - (jdbc/query tx) - first - :count)))) - -(defn ^:private terra-executor-workflows - [tx {:keys [workspace details] :as _executor}] - (when-not (postgres/table-exists? tx details) - (throw (ex-info "Missing executor details table" {:table details}))) - (letfn [(from-record [{:keys [workflow submission status] :as record}] - (combine-record-workflow-and-outputs - record - (firecloud/get-workflow workspace submission workflow) - (when (= "Succeeded" status) - (firecloud/get-workflow-outputs workspace submission workflow))))] - (let [query "SELECT * FROM %s WHERE workflow IS NOT NULL ORDER BY id ASC"] - (map from-record (jdbc/query tx (format query details)))))) - -(defn ^:private terra-executor-done? [executor] - (zero? (queue-length! executor))) - -(defn ^:private terra-executor-to-edn [executor] - (-> executor - (util/select-non-nil-keys (keys terra-executor-serialized-fields)) - (assoc :name terra-executor-name))) - -(defoverload validate-or-throw terra-executor-name verify-terra-executor) - -(defoverload create-executor! terra-executor-name create-terra-executor) -(defoverload update-executor! terra-executor-type update-terra-executor) -(defoverload load-executor! terra-executor-type load-terra-executor) -(defoverload executor-workflows terra-executor-type terra-executor-workflows) - -(defoverload peek-queue! terra-executor-type peek-terra-executor-queue) -(defoverload pop-queue! terra-executor-type pop-terra-executor-queue) -(defoverload queue-length! terra-executor-type terra-executor-queue-length) - -(defoverload done? terra-executor-type terra-executor-done?) - -(defoverload util/to-edn terra-executor-type terra-executor-to-edn) - -;; Terra Workspace Sink -(def ^:private terra-workspace-sink-name "Terra Workspace") -(def ^:private terra-workspace-sink-type "TerraWorkspaceSink") -(def ^:private terra-workspace-sink-table "TerraWorkspaceSink") -(def ^:private terra-workspace-sink-serialized-fields - {:workspace :workspace - :entityType :entity_type - :fromOutputs :from_outputs - :identifier :identifier}) - -(defn ^:private create-terra-workspace-sink [tx id request] - (let [create "CREATE TABLE %s OF TerraWorkspaceSinkDetails (PRIMARY KEY (id))" - alter "ALTER TABLE %s ALTER COLUMN id ADD GENERATED ALWAYS AS IDENTITY" - details (format "%s_%09d" terra-workspace-sink-type id)] - (jdbc/db-do-commands tx [(format create details) (format alter details)]) - [terra-workspace-sink-type - (-> (select-keys request (keys terra-workspace-sink-serialized-fields)) - (update :fromOutputs pr-str) - (set/rename-keys terra-workspace-sink-serialized-fields) - (assoc :details details) - (->> (jdbc/insert! tx terra-workspace-sink-table) first :id str))])) - -(defn ^:private load-terra-workspace-sink [tx {:keys [sink_items] :as workload}] - (if-let [id (util/parse-int sink_items)] - (-> (load-record-by-id! tx terra-workspace-sink-table id) - (set/rename-keys (set/map-invert terra-workspace-sink-serialized-fields)) - (update :fromOutputs edn/read-string) - (assoc :type terra-workspace-sink-type)) - (throw (ex-info "Invalid sink_items" {:workload workload})))) - -(def unknown-entity-type-error-message - "The entityType was not found in workspace.") - -(def malformed-from-outputs-error-message - (str/join " " ["fromOutputs must define a mapping from workflow outputs" - "to the attributes of entityType."])) - -(def unknown-attributes-error-message - (str/join " " ["Found additional attributes in fromOutputs that are not" - "present in the entityType."])) - -(defn ^:private verify-terra-sink! - "Verify that the WFL has access the `workspace`." - [{:keys [entityType fromOutputs skipValidation workspace] :as sink}] - (when-not skipValidation - (workspace-or-throw workspace) - (let [entity-type (keyword entityType) - entity-types (firecloud/list-entity-types workspace) - types (-> entity-types keys set)] - (when-not (types entity-type) - (throw (UserException. unknown-entity-type-error-message - (util/make-map entityType types workspace)))) - (when-not (map? fromOutputs) - (throw (UserException. malformed-from-outputs-error-message - (util/make-map entityType fromOutputs)))) - (let [attributes (->> (get-in entity-types [entity-type :attributeNames]) - (cons (str entityType "_id")) - (mapv keyword)) - [missing _ _] (data/diff (set (keys fromOutputs)) (set attributes))] - (when (seq missing) - (throw (UserException. unknown-attributes-error-message - {:entityType entityType - :attributes (sort attributes) - :missing (sort missing) - :fromOutputs fromOutputs})))))) - sink) - -;; visible for testing -(defn rename-gather - "Transform the `values` using the transformation defined in `mapping`." - [values mapping] - (letfn [(literal? [x] (str/starts-with? x "$")) - (go! [v] - (cond (literal? v) (subs v 1 (count v)) - (string? v) (values (keyword v)) - (map? v) (rename-gather values v) - (coll? v) (keep go! v) - :else (throw (ex-info "Unknown operation" - {:operation v}))))] - (into {} (for [[k v] mapping] [k (go! v)])))) - -(defn ^:private terra-workspace-sink-to-attributes - [{:keys [outputs] :as workflow} fromOutputs] - (when-not (map? fromOutputs) - (throw (IllegalStateException. "fromOutputs is malformed"))) - (try - (rename-gather outputs fromOutputs) - (catch Exception cause - (throw (ex-info "Failed to coerce workflow outputs to attribute values" - {:fromOutputs fromOutputs :workflow workflow} - cause))))) - -(defn ^:private entity-exists? - "True when the `entity` exists in the `workspace`." - [workspace entity] - (try - (firecloud/get-entity workspace entity) - (catch ExceptionInfo ex - (when (not= (-> ex ex-data :status) 404) - (throw ex))))) - -(defn ^:private update-terra-workspace-sink - [executor {:keys [fromOutputs workspace entityType identifier details] :as _sink}] - (when-let [{:keys [uuid outputs] :as workflow} (peek-queue! executor)] - (log/debug "coercing workflow" uuid "outputs to" entityType) - (let [attributes (terra-workspace-sink-to-attributes workflow fromOutputs) - [_ name :as entity] [entityType (outputs (keyword identifier))]] - (when (entity-exists? workspace entity) - (log/debug "entity" name "already exists - deleting previous entity.") - (firecloud/delete-entities workspace [entity])) - (log/debug "upserting workflow" uuid "outputs as" name) - (rawls/batch-upsert workspace [(conj entity attributes)]) - (pop-queue! executor) - (log/info "sunk workflow" uuid "to" workspace "as" name) - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> {:entity name :workflow uuid :updated (utc-now)} - (jdbc/insert! tx details)))))) - -(defn ^:private terra-workspace-sink-done? [_sink] true) - -(defn ^:private terra-workspace-sink-to-edn [sink] - (-> sink - (util/select-non-nil-keys (keys terra-workspace-sink-serialized-fields)) - (assoc :name terra-workspace-sink-name))) - -(defoverload validate-or-throw terra-workspace-sink-name verify-terra-sink!) - -(defoverload create-sink! terra-workspace-sink-name create-terra-workspace-sink) -(defoverload load-sink! terra-workspace-sink-type load-terra-workspace-sink) -(defoverload update-sink! terra-workspace-sink-type update-terra-workspace-sink) - -(defoverload done? terra-workspace-sink-type terra-workspace-sink-done?) - -(defoverload util/to-edn terra-workspace-sink-type terra-workspace-sink-to-edn) diff --git a/api/src/wfl/module/sg.clj b/api/src/wfl/module/sg.clj index 0a1e7ebf1..c8b7d3dfe 100644 --- a/api/src/wfl/module/sg.clj +++ b/api/src/wfl/module/sg.clj @@ -1,11 +1,13 @@ (ns wfl.module.sg "Handle Somatic Genomes." (:require [clojure.data.json :as json] + [clojure.spec.alpha :as s] [clojure.set :as set] [clojure.string :as str] - [clojure.tools.logging.readable :as log] [wfl.api.workloads :as workloads :refer [defoverload]] [wfl.jdbc :as jdbc] + [wfl.log :as log] + [wfl.module.all :as all] [wfl.module.batch :as batch] [wfl.references :as references] [wfl.service.clio :as clio] @@ -17,6 +19,15 @@ (def pipeline "GDCWholeGenomeSomaticSingleSample") +;; specs +(s/def ::workflow-inputs (s/keys :req-un [::all/base_file_name + ::all/contamination_vcf + ::all/contamination_vcf_index + ::all/cram_ref_fasta + ::all/cram_ref_fasta_index + ::all/dbsnp_vcf + ::all/dbsnp_vcf_index + ::all/input_cram])) (def workflow-wdl "The top-level WDL file and its version." {:release "GDCWholeGenomeSomaticSingleSample_v1.1.0" @@ -52,17 +63,17 @@ repo "broad-gotc-prod" image "genomes-in-the-cloud:2.4.3-1564508330" {:keys [google_project jes_gcs_root]} (cromwell->strings url)] - (-> {:backend "PAPIv2" - :final_workflow_outputs_dir output - :google_project google_project - :jes_gcs_root jes_gcs_root - :read_from_cache true - :write_to_cache true - :default_runtime_attributes - {:docker (str/join "/" [gcr repo image]) - :maxRetries 1 - :noAddress false - :zones util/google-cloud-zones}}))) + {:backend "PAPIv2" + :final_workflow_outputs_dir output + :google_project google_project + :jes_gcs_root jes_gcs_root + :read_from_cache true + :write_to_cache true + :default_runtime_attributes + {:docker (str/join "/" [gcr repo image]) + :maxRetries 1 + :noAddress false + :zones util/google-cloud-zones}})) (defn create-sg-workload! [tx {:keys [common items] :as request}] @@ -146,8 +157,7 @@ [clio bam] (try (clio/add-bam clio bam) (catch Throwable x - (log/error x "Add BAM to Clio failed" {:bam bam - :x x})))) + (log/error {:bam bam :x x})))) (defn maybe-update-clio-and-write-final-files "Maybe update `clio-url` with `final` and write files and `metadata`." @@ -169,7 +179,7 @@ (defn ^:private register-workflow-in-clio "Ensure Clio knows the `workflow` outputs of `executor`." - [executor output {:keys [status uuid] :as workflow}] + [executor output {:keys [status uuid] :as _workflow}] (when (= "Succeeded" status) (let [finalize (partial final_workflow_outputs_dir_hack output) clio-url (-> executor cromwell->strings :clio-url) @@ -204,15 +214,17 @@ (if (and started (not finished)) (let [workload' (update! workload)] (when (:finished workload') - (->> (workloads/workflows tx workload') - (register-workload-in-clio workload'))) + (register-workload-in-clio workload' + (workloads/workflows tx workload'))) workload') workload))) -(defoverload workloads/create-workload! pipeline create-sg-workload!) -(defoverload workloads/start-workload! pipeline start-sg-workload!) -(defoverload workloads/update-workload! pipeline update-sg-workload!) -(defoverload workloads/stop-workload! pipeline batch/stop-workload!) -(defoverload workloads/load-workload-impl pipeline batch/load-batch-workload-impl) -(defoverload workloads/workflows pipeline batch/workflows) -(defoverload workloads/to-edn pipeline batch/workload-to-edn) +(defoverload workloads/create-workload! pipeline create-sg-workload!) +(defoverload workloads/start-workload! pipeline start-sg-workload!) +(defoverload workloads/update-workload! pipeline update-sg-workload!) +(defoverload workloads/stop-workload! pipeline batch/stop-workload!) +(defoverload workloads/load-workload-impl pipeline batch/load-batch-workload-impl) +(defoverload workloads/workflows pipeline batch/workflows) +(defoverload workloads/workflows-by-status pipeline batch/workflows-by-status) +(defoverload workloads/retry pipeline batch/retry-unsupported) +(defoverload workloads/to-edn pipeline batch/workload-to-edn) diff --git a/api/src/wfl/module/wgs.clj b/api/src/wfl/module/wgs.clj index 01565ca3a..7ebf90e55 100644 --- a/api/src/wfl/module/wgs.clj +++ b/api/src/wfl/module/wgs.clj @@ -1,6 +1,7 @@ (ns wfl.module.wgs "Reprocess (External) Whole Genomes." (:require [clojure.data.json :as json] + [clojure.spec.alpha :as s] [clojure.string :as str] [wfl.api.workloads :as workloads :refer [defoverload]] [wfl.jdbc :as jdbc] @@ -8,11 +9,15 @@ [wfl.references :as references] [wfl.service.google.storage :as gcs] [wfl.util :as util] - [wfl.wfl :as wfl]) + [wfl.wfl :as wfl] + [wfl.module.all :as all]) (:import [java.time OffsetDateTime])) (def pipeline "ExternalWholeGenomeReprocessing") +;; specs +(s/def ::workflow-inputs (s/keys :req-un [(or ::all/input_bam ::all/input_cram)])) + (def workflow-wdl "The top-level WDL file and its version." {:release "c1f20c46ad61aa3b87ce9d88fd9facc871ae6d4b" @@ -103,7 +108,8 @@ (defn ^:private normalize-reference-fasta [inputs] (if-let [prefix (:reference_fasta_prefix inputs)] - (-> (update-in inputs [:references :reference_fasta] + (-> inputs + (update-in [:references :reference_fasta] #(util/deep-merge (references/reference_fasta prefix) %)) (dissoc :reference_fasta_prefix)) inputs)) @@ -127,12 +133,13 @@ (defn ^:private make-workflow-inputs "Make the final pipeline inputs from Cromwell URL." [url {:keys [inputs]}] - (-> (util/deep-merge cram-ref - hack-task-level-values - {:references default-references} - (static-inputs url) - inputs) - (util/prefix-keys (keyword (str pipeline "."))))) + (util/prefix-keys + (util/deep-merge cram-ref + hack-task-level-values + {:references default-references} + (static-inputs url) + inputs) + (keyword (str pipeline ".")))) ;; visible for testing (defn make-workflow-options @@ -159,12 +166,11 @@ (defn create-wgs-workload! "Use transaction TX to add the workload described by REQUEST." [tx {:keys [items output common] :as request}] - (letfn [(nil-if-empty [x] (if (empty? x) nil x)) - (serialize [workflow id] + (letfn [(serialize [workflow id] (-> (assoc workflow :id id) (update :options #(json/write-str - (nil-if-empty (util/deep-merge (:options common) %)))) + (not-empty (util/deep-merge (:options common) %)))) (update :inputs #(json/write-str (normalize-reference-fasta @@ -198,8 +204,10 @@ (jdbc/update! tx :workload {:started now} ["id = ?" id])) (workloads/load-workload-for-id tx id))) -(defoverload workloads/update-workload! pipeline batch/update-workload!) -(defoverload workloads/stop-workload! pipeline batch/stop-workload!) -(defoverload workloads/load-workload-impl pipeline batch/load-batch-workload-impl) -(defoverload workloads/workflows pipeline batch/workflows) -(defoverload workloads/to-edn pipeline batch/workload-to-edn) +(defoverload workloads/update-workload! pipeline batch/update-workload!) +(defoverload workloads/stop-workload! pipeline batch/stop-workload!) +(defoverload workloads/load-workload-impl pipeline batch/load-batch-workload-impl) +(defoverload workloads/workflows pipeline batch/workflows) +(defoverload workloads/workflows-by-status pipeline batch/workflows-by-status) +(defoverload workloads/retry pipeline batch/retry-unsupported) +(defoverload workloads/to-edn pipeline batch/workload-to-edn) diff --git a/api/src/wfl/module/xx.clj b/api/src/wfl/module/xx.clj index d128f80a3..3028ed689 100644 --- a/api/src/wfl/module/xx.clj +++ b/api/src/wfl/module/xx.clj @@ -1,19 +1,23 @@ (ns wfl.module.xx "Reprocess eXternal eXomes." (:require [clojure.data.json :as json] + [clojure.spec.alpha :as s] [clojure.string :as str] - [wfl.api.workloads :refer [defoverload]] - [wfl.api.workloads :as workloads] + [wfl.api.workloads :as workloads :refer [defoverload]] [wfl.jdbc :as jdbc] [wfl.module.batch :as batch] [wfl.references :as references] [wfl.service.google.storage :as gcs] [wfl.util :as util] - [wfl.wfl :as wfl]) + [wfl.wfl :as wfl] + [wfl.module.all :as all]) (:import [java.time OffsetDateTime])) (def pipeline "ExternalExomeReprocessing") +;; specs +(s/def ::workflow-inputs (s/keys :req-un [(or ::all/input_bam ::all/input_cram)])) + (def ^:private cromwell-label "The WDL label applied to Cromwell metadata." {(keyword wfl/the-name) pipeline}) @@ -142,9 +146,8 @@ (defn create-xx-workload! [tx {:keys [common items output] :as request}] - (letfn [(nil-if-empty [x] (if (empty? x) nil x)) - (merge-to-json [shared specific] - (json/write-str (nil-if-empty (util/deep-merge shared specific)))) + (letfn [(merge-to-json [shared specific] + (json/write-str (not-empty (util/deep-merge shared specific)))) (serialize [item id] (-> item (assoc :id id) @@ -174,10 +177,12 @@ (jdbc/update! tx :workload {:started now} ["id = ?" id])) (workloads/load-workload-for-id tx id))) -(defoverload workloads/create-workload! pipeline create-xx-workload!) -(defoverload workloads/start-workload! pipeline start-xx-workload!) -(defoverload workloads/update-workload! pipeline batch/update-workload!) -(defoverload workloads/stop-workload! pipeline batch/stop-workload!) -(defoverload workloads/load-workload-impl pipeline batch/load-batch-workload-impl) -(defoverload workloads/workflows pipeline batch/workflows) -(defoverload workloads/to-edn pipeline batch/workload-to-edn) +(defoverload workloads/create-workload! pipeline create-xx-workload!) +(defoverload workloads/start-workload! pipeline start-xx-workload!) +(defoverload workloads/update-workload! pipeline batch/update-workload!) +(defoverload workloads/stop-workload! pipeline batch/stop-workload!) +(defoverload workloads/load-workload-impl pipeline batch/load-batch-workload-impl) +(defoverload workloads/workflows pipeline batch/workflows) +(defoverload workloads/workflows-by-status pipeline batch/workflows-by-status) +(defoverload workloads/retry pipeline batch/retry-unsupported) +(defoverload workloads/to-edn pipeline batch/workload-to-edn) diff --git a/api/src/wfl/server.clj b/api/src/wfl/server.clj index 8f0dc883f..f5d4aab8b 100644 --- a/api/src/wfl/server.clj +++ b/api/src/wfl/server.clj @@ -1,9 +1,6 @@ (ns wfl.server "An HTTP API server." - (:require [clojure.pprint :refer [pprint]] - [clojure.stacktrace :refer [print-throwable]] - [clojure.string :as str] - [clojure.tools.logging :as log] + (:require [clojure.string :as str] [clj-time.coerce :as tc] [ring.adapter.jetty :as jetty] [ring.middleware.defaults :as defaults] @@ -13,8 +10,10 @@ [ring.middleware.session.cookie :as cookie] [wfl.api.routes :as routes] [wfl.api.workloads :as workloads] + [wfl.configuration :as config] [wfl.environment :as env] [wfl.jdbc :as jdbc] + [wfl.log :as log] [wfl.service.postgres :as postgres] [wfl.util :as util] [wfl.wfl :as wfl]) @@ -59,7 +58,7 @@ (try (handler request) (catch Throwable t - (log/error t))))) + (log/error (str t)))))) ;; See https://stackoverflow.com/a/43075132 ;; @@ -78,9 +77,9 @@ wrap-internal-error (wrap-json-response {:pretty true}))) -(defn notify-watchers [watchers uuid exception] +(defn notify-watchers [watchers _uuid _exception] {:pre [(some? watchers)]} - (log/info "notifying: " watchers)) + (log/info (str/join " " ["notifying: " watchers]))) (defn ^:private start-workload-manager "Update the workload database, then start a `future` to manage the @@ -91,21 +90,22 @@ (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] (let [{:keys [watchers] :as workload} (workloads/load-workload-for-id tx id)] + (log/info (format "Updating workload %s" uuid)) (try (workloads/update-workload! tx workload) (catch UserException e - (log/warnf "Error updating workload %s" uuid) + (log/warn (format "Error updating workload %s" uuid)) (log/warn e) (notify-watchers watchers uuid e)))))) (try-update [{:keys [uuid] :as workload}] (try (do-update! workload) (catch Throwable t - (log/error "Failed to update workload %s" uuid) - (log/error t)))) + (log/error (format "Failed to update workload %s" uuid)) + (log/error (str t))))) (update-workloads [] (try - (log/info "updating workloads") + (log/info "Finding workloads to update...") (run! try-update (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] (jdbc/query tx "SELECT id,uuid FROM workload @@ -113,7 +113,7 @@ AND finished IS NULL"))) (catch Throwable t (log/error "Failed to update workloads") - (log/error t))))] + (log/error (str t)))))] (log/info "starting workload update loop") (update-workloads) (future @@ -121,12 +121,27 @@ (update-workloads) (.sleep TimeUnit/SECONDS 20))))) +(defn ^:private start-logging-polling + "Start polling for changes to the log level." + [] + (letfn [(get-logging-level [] (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (let [config (config/get-config tx "LOGGING_LEVEL")] + (reset! log/logging-level + (if (empty? config) + :info + (-> config str/lower-case keyword))))))] + (get-logging-level) + (future + (while true + (get-logging-level) + (.sleep TimeUnit/SECONDS 60))))) + (defn ^:private start-webserver "Start the jetty webserver asynchronously to serve http requests on the specified port. Returns a java.util.concurrent.Future that, when de- referenced, blocks until the server ends." [port] - (log/infof "starting jetty webserver on port %s" port) + (log/info (format "starting jetty webserver on port %s" port)) (let [server (jetty/run-jetty (app) {:port port :join? false})] (reify Future (cancel [_ _] (throw (UnsupportedOperationException.))) @@ -146,9 +161,10 @@ (recur))))) (defn run - "Run child server in ENVIRONMENT on PORT." + "Run server in ENVIRONMENT on PORT." [& args] - (log/info "Run:" wfl/the-name "server" args) + (log/info (str/join " " ["Run:" wfl/the-name "server" args])) (let [port (util/is-non-negative! (first args)) - manager (start-workload-manager)] - (await-some manager (start-webserver port)))) + manager (start-workload-manager) + logger (start-logging-polling)] + (await-some manager logger (start-webserver port)))) diff --git a/api/src/wfl/server_debug.clj b/api/src/wfl/server_debug.clj index f2ce1d941..620124793 100644 --- a/api/src/wfl/server_debug.clj +++ b/api/src/wfl/server_debug.clj @@ -2,7 +2,7 @@ "Debug the HTTP server (wfl.server)." (:require [clojure.pprint :refer [pprint]] [clojure.string :as str] - [clojure.tools.logging :as log])) + [wfl.log :as log])) (def ignored-keys "Ignore these keys when tracing a request or response map." diff --git a/api/src/wfl/service/clio.clj b/api/src/wfl/service/clio.clj index 68bcc5eee..8018794f6 100644 --- a/api/src/wfl/service/clio.clj +++ b/api/src/wfl/service/clio.clj @@ -1,7 +1,6 @@ (ns wfl.service.clio "Manage Clio's BAM and CRAM indexes." (:require [clojure.data.json :as json] - [clojure.pprint :refer [pprint]] [clojure.string :as str] [clj-http.client :as http] [wfl.auth :as auth])) diff --git a/api/src/wfl/service/cromwell.clj b/api/src/wfl/service/cromwell.clj index d69daf466..8adf760af 100644 --- a/api/src/wfl/service/cromwell.clj +++ b/api/src/wfl/service/cromwell.clj @@ -2,30 +2,28 @@ "Common utilities and clients to talk to Cromwell." (:require [clojure.data.json :as json] [clojure.string :as str] - [clojure.tools.logging :as log] [clojure.walk :as walk] [clj-http.client :as http] - [wfl.debug :as debug] [wfl.auth :as auth] + [wfl.debug :as debug] [wfl.util :as util] [wfl.wfl :as wfl])) -(def final-statuses +(def retry-status? + "Cromwell workflow statuses eligible for retry." + #{"Aborted" "Failed" "Succeeded"}) + +(def final? "The final statuses a Cromwell workflow can have." - ["Aborted" - "Failed" - "Succeeded"]) + retry-status?) -(def active-statuses +(def active? "The statuses an active Cromwell workflow can have." - ["Aborting" - "On Hold" - "Running" - "Submitted"]) + #{"Aborting" "On Hold" "Running" "Submitted"}) -(def statuses +(def status? "All the statuses a Cromwell workflow can have." - (into active-statuses final-statuses)) + (into active? final?)) (defn ^:private api "Get the api url given Cromwell URL." @@ -46,8 +44,7 @@ (defn ^:private request-json "Response to REQUEST with :body parsed as JSON." [request] - (-> (http/request request) - (update :body (fnil util/parse-json "null")))) + (update (http/request request) :body (fnil util/parse-json "null"))) (def ^:private bogus-key-character-map "Map bogus characters in metadata keys to replacements." @@ -206,26 +203,6 @@ [url id] (:status (get-thing "status" url id))) -;; HACK: (into (array-map) ...) is egregious. -;; -(defn status-counts - "Map status to workflow counts on Cromwell given URL with PARAMS - map and AUTH-HEADER." - [url params] - (letfn [(each [status] - (let [form-params (-> {:pagesize 1 :status status} - (merge params) - cromwellify-json-form)] - [status (-> {:method :post ;; :debug true :debug-body true - :url (str (api url) "/query") - :form-params form-params - :content-type :application/json - :headers (auth/get-auth-header)} - request-json :body :totalResultsCount)]))] - (let [counts (into (array-map) (map each statuses)) - total (apply + (map counts statuses))] - (into counts [[:total total]])))) - (defn submit-workflow "Submit a workflow to run WDL with INPUTS, OPTIONS, and LABELS on the Cromwell URL and return its ID. INPUTS, @@ -261,8 +238,8 @@ (mapv :id))) (defn wait-for-workflow-complete - "Return status of workflow named by ID when it completes, given Cromwell URL." + "Return status of workflow ID from URL when it completes." [url id] - (let [finished? (comp (set final-statuses) #(status url id))] + (let [finished? (comp final? #(status url id))] (work-around-cromwell-fail-bug 9 url id) (util/poll finished? 15 (Integer/MAX_VALUE)))) diff --git a/api/src/wfl/service/datarepo.clj b/api/src/wfl/service/datarepo.clj index 80c4d768f..c5cc983be 100644 --- a/api/src/wfl/service/datarepo.clj +++ b/api/src/wfl/service/datarepo.clj @@ -8,8 +8,17 @@ [wfl.mime-type :as mime-type] [wfl.service.google.bigquery :as bigquery] [wfl.util :as util]) - (:import (java.time Instant) - (java.util.concurrent TimeUnit))) + (:import [clojure.lang ExceptionInfo] + [java.time Instant] + [wfl.util UserException])) + +(def final? + "The final statuses a data repo job can have." + #{"succeeded" "failed"}) + +(def active? + "The statuses an active data repo job can have." + #{"running"}) (defn ^:private datarepo-url [& parts] (let [url (util/de-slashify (env/getenv "WFL_TDR_URL"))] @@ -28,7 +37,13 @@ "Query the DataRepo for the Dataset with `dataset-id`." [dataset-id] {:pre [(some? dataset-id)]} - (get-repository-json "datasets" dataset-id)) + (try + (get-repository-json "datasets" dataset-id) + (catch ExceptionInfo e + (throw + (UserException. "Cannot access dataset" + {:dataset dataset-id :status (-> e ex-data :status)} + e))))) (defn ^:private ingest "Ingest THING to DATASET-ID according to BODY." @@ -86,18 +101,13 @@ (defn poll-job "Poll the job with `job-id` every `seconds` [default: 5] and return its - result." - ([job-id seconds] - (let [result #(get-repository-json "jobs" job-id "result") - running? #(-> (get-repository-json "jobs" job-id) - :job_status - #{"running"})] - (while (running?) (.sleep TimeUnit/SECONDS seconds)) - (result))) - ([job-id] - (poll-job job-id 5))) - -(defn get-job-metadata + result with `max-attempts` [default: 20]." + [job-id & [seconds max-attempts]] + (let [done? #(-> (get-repository-json "jobs" job-id) :job_status final?)] + (util/poll done? (or seconds 5) (or max-attempts 20)) + (get-repository-json "jobs" job-id "result"))) + +(defn job-metadata "Return the metadata of job with `job-id` when done." [job-id] {:pre [(some? job-id)]} @@ -175,11 +185,11 @@ (list-snapshots \"48a51f71-6bab-483d-a270-3f9ebfb241cd\")" [& dataset-ids] (letfn [(maybe-merge [m k v] (if (seq v) (assoc m k {:datasetIds v}) m))] - (-> (http/get (repository "snapshots") - (maybe-merge {:headers (auth/get-service-account-header) - :query-params {:limit 999}} - :query-params dataset-ids)) - util/response-body-json))) + (util/response-body-json + (http/get (repository "snapshots") + (maybe-merge {:headers (auth/get-service-account-header) + :query-params {:limit 999}} + :query-params dataset-ids))))) (defn delete-snapshot "Delete the Snapshot with `snapshot-id`." @@ -231,8 +241,9 @@ (defn ^:private query-table-impl ([{:keys [dataProject] :as dataset} table col-spec] (let [bq-name (bigquery-name dataset)] - (->> (format "SELECT %s FROM `%s.%s.%s`" col-spec dataProject bq-name table) - (bigquery/query-sync dataProject))))) + (bigquery/query-sync + dataProject + (format "SELECT %s FROM `%s.%s.%s`" col-spec dataProject bq-name table))))) (defn query-table "Query everything or optionally the `columns` in `table` in the Terra DataRepo @@ -240,8 +251,8 @@ ([dataset table] (query-table-impl dataset table "*")) ([dataset table columns] - (->> (util/to-comma-separated-list (map name columns)) - (query-table-impl dataset table)))) + (query-table-impl dataset table + (util/to-comma-separated-list (map name columns))))) (defn ^:private query-table-between-impl [{:keys [dataProject] :as dataset} table between [start end] col-spec] @@ -265,3 +276,29 @@ (->> (map name columns) util/to-comma-separated-list (query-table-between-impl dataset table between interval)))) + + +;; utilities + + +(defn ^:private id-and-name [{:keys [id name] :as _dataset}] + (util/make-map id name)) + +(defn throw-unless-column-exists + "Throw if `table` does not have `column` in `dataset`." + [table column dataset] + (when (->> table :columns (filter (comp #{column} :name)) empty?) + (throw (UserException. "Column not found" + {:column column + :table table + :dataset (id-and-name dataset)})))) + +(defn table-or-throw + "Throw or return the table with `table-name` in `dataset`." + [table-name {:keys [schema] :as dataset}] + (let [[table & _] (filter (comp #{table-name} :name) (:tables schema))] + (when-not table + (throw (UserException. "Table not found" + {:table table-name + :dataset (id-and-name dataset)}))) + table)) diff --git a/api/src/wfl/service/dockstore.clj b/api/src/wfl/service/dockstore.clj new file mode 100644 index 000000000..3480ae593 --- /dev/null +++ b/api/src/wfl/service/dockstore.clj @@ -0,0 +1,15 @@ +(ns wfl.service.dockstore + "Wrappers for Dockstore HTTP APIs." + (:require [clj-http.client :as http] + [clojure.string :as str] + [wfl.environment :as env] + [wfl.util :as util])) + +(defn ^:private dockstore-url [& parts] + (let [url (util/de-slashify (env/getenv "WFL_DOCKSTORE_URL"))] + (str/join "/" (cons url parts)))) + +(defn ga4gh-tool-descriptor [id version type] + (-> (dockstore-url "api/api/ga4gh/v2/tools" id "versions" version type "descriptor") + http/get + util/response-body-json)) diff --git a/api/src/wfl/service/firecloud.clj b/api/src/wfl/service/firecloud.clj index 2a4eb4cba..8bc06b97b 100644 --- a/api/src/wfl/service/firecloud.clj +++ b/api/src/wfl/service/firecloud.clj @@ -6,7 +6,9 @@ [wfl.auth :as auth] [wfl.environment :as env] [wfl.util :as util]) - (:import [java.util UUID])) + (:import [clojure.lang ExceptionInfo] + [java.util UUID] + [wfl.util UserException])) (defn ^:private firecloud-url [& parts] (let [url (util/de-slashify (env/getenv "WFL_FIRECLOUD_URL"))] @@ -20,15 +22,25 @@ (http/get {:headers (auth/get-auth-header)}) util/response-body-json)) -(defn workspace [workspace] +(defn workspace-or-throw + "Return the `workspace` or throw a UserException." + [workspace] {:pre [(some? workspace)]} - (get-workspace-json workspace)) + (try + (get-workspace-json workspace) + (catch ExceptionInfo cause + (throw (UserException. + "Cannot access workspace" + {:workspace workspace + :status (-> cause ex-data :status)} + cause))))) (defn abort-submission "Abort the submission with `submission-id` in the Terra `workspace`." [workspace submission-id] - (-> (workspace-api-url workspace "submissions" submission-id) - (http/delete {:headers (auth/get-auth-header)}))) + (http/delete + (workspace-api-url workspace "submissions" submission-id) + {:headers (auth/get-auth-header)})) (defn create-submission "Submit samples in a workspace for analysis with a method configuration in Terra." @@ -162,11 +174,12 @@ ------- (import-entities \"workspace-namespace/workspace-name\" \"./samples.tsv\")" [workspace file] - (-> (workspace-api-url workspace "flexibleImportEntities") - (http/post {:headers (auth/get-auth-header) - :multipart (util/multipart-body - {:Content/type "text/tab-separated-values" - :entities (slurp file)})}))) + (http/post + (workspace-api-url workspace "flexibleImportEntities") + {:headers (auth/get-auth-header) + :multipart (util/multipart-body + {:Content/type "text/tab-separated-values" + :entities (slurp file)})})) (defn import-entity-set " @@ -225,11 +238,19 @@ [workspace] (get-workspace-json workspace "methodconfigs?allRepos=true")) -(defn get-method-configuration +(defn method-configuration "Return the `methodconfig` in the `workspace`." [workspace methodconfig] {:pre [(every? some? [workspace methodconfig])]} - (get-workspace-json workspace "method_configs" methodconfig)) + (try + (get-workspace-json workspace "method_configs" methodconfig) + (catch ExceptionInfo cause + (throw (UserException. + "Cannot access method configuration in workspace" + {:workspace workspace + :methodConfiguration methodconfig + :status (-> cause ex-data :status)} + cause))))) (defn update-method-configuration "Update the method-configuration `method-config-name` to be `methodconfig` in @@ -263,17 +284,3 @@ :workflowSource) workflow})}) util/response-body-json))) - -(defn ^:private get-groups - "Return the groups caller is in." - [] - (-> (str/join "/" [(firecloud-url) "api" "groups"]) - (http/get {:headers (auth/get-auth-header)}) - util/response-body-json)) - -(defn ^:private get-group-members - "Return the members of group." - [group] - (-> (str/join "/" [(firecloud-url) "api" "groups" group]) - (http/get {:headers (auth/get-auth-header)}) - util/response-body-json)) diff --git a/api/src/wfl/service/google/pubsub.clj b/api/src/wfl/service/google/pubsub.clj index 06279edb3..cb92188b1 100644 --- a/api/src/wfl/service/google/pubsub.clj +++ b/api/src/wfl/service/google/pubsub.clj @@ -187,5 +187,5 @@ (letfn [(make-binding [[role members]] [{:role role :members members}])] (set-iam-policy resource - (-> (get-iam-policy resource) - (update :bindings #(concat % (map make-binding role->members))))))) + (update (get-iam-policy resource) + :bindings #(concat % (map make-binding role->members)))))) diff --git a/api/src/wfl/service/google/storage.clj b/api/src/wfl/service/google/storage.clj index c95bd6dd9..5cf6ce258 100644 --- a/api/src/wfl/service/google/storage.clj +++ b/api/src/wfl/service/google/storage.clj @@ -8,7 +8,7 @@ [clojure.pprint :refer [pprint]] [clojure.spec.alpha :as s] [clojure.string :as str] - [clojure.tools.logging.readable :as logr] + [wfl.log :as logr] [wfl.auth :as auth] [wfl.util :as util]) (:import [org.apache.tika Tika])) diff --git a/api/src/wfl/service/postgres.clj b/api/src/wfl/service/postgres.clj index 930db803a..24363238f 100644 --- a/api/src/wfl/service/postgres.clj +++ b/api/src/wfl/service/postgres.clj @@ -33,18 +33,21 @@ (count) (not= 0))) +(defn throw-unless-table-exists + [tx table-name] + (when-not (and table-name (table-exists? tx table-name)) + (throw (ex-info "Table not found" {:table table-name})))) + (defn get-table - "Return TABLE using transaction TX." + "Return TABLE using transaction TX sorted by row id." [tx table] - (if (and table (table-exists? tx table)) - (jdbc/query tx (format "SELECT * FROM %s" table)) - (throw (ex-info (format "Table %s does not exist" table) {:cause "no-such-table"})))) + (throw-unless-table-exists tx table) + (jdbc/query tx (format "SELECT * FROM %s ORDER BY id ASC" table))) (defn table-length "Use `tx` to return the number of records in `table-name`." [tx table-name] - (when-not (table-exists? tx table-name) - (throw (ex-info "No such table" {:table table-name}))) + (throw-unless-table-exists tx table-name) (->> (format "SELECT COUNT(*) FROM %s" table-name) (jdbc/query tx) first @@ -53,10 +56,16 @@ (defn table-max "Use `tx` to return the maximum value of `column` in `table-name`." [tx table-name column] - (when-not (table-exists? tx table-name) - (throw (ex-info "No such table" {:table table-name}))) + (throw-unless-table-exists tx table-name) (-> (format "SELECT MAX(%s) FROM %s" (name column) (name table-name)) (->> (jdbc/query tx)) first :max (or 0))) + +(defn load-record-by-id! [tx table id] + (let [query "SELECT * FROM %s WHERE id = ? LIMIT 1" + [record & _] (jdbc/query tx [(format query table) id])] + (when-not record + (throw (ex-info (str "No such record") {:id id :table table}))) + record)) diff --git a/api/src/wfl/service/rawls.clj b/api/src/wfl/service/rawls.clj index 7fd81bc92..f6a79c046 100644 --- a/api/src/wfl/service/rawls.clj +++ b/api/src/wfl/service/rawls.clj @@ -9,6 +9,25 @@ [wfl.util :as util]) (:import [clojure.lang ExceptionInfo])) +(def final-statuses + "The final statuses a Rawls workflow can have." + ["Aborted" + "Failed" + "Succeeded"]) + +(def active-statuses + "The active statuses the Rawls workflow can have." + ["Aborting" + "Launching" + "Queued" + "Running" + "Submitted" + "Unknown"]) + +(def statuses + "All the statuses the Rawls workflow can have." + (into final-statuses active-statuses)) + (defn ^:private rawls-url [& parts] (let [url (util/de-slashify (env/getenv "WFL_RAWLS_URL"))] (str/join "/" (cons url parts)))) @@ -21,8 +40,7 @@ (http/get {:headers (auth/get-auth-header)}) util/response-body-json)) -(def ^:private snapshot-endpoint - "snapshots") +(def ^:private snapshot-endpoint "snapshots/v2") (defn create-snapshot-reference "Link `snapshot-id` to `workspace` as `name` with `description`." @@ -43,30 +61,30 @@ [workspace reference-id] (get-workspace-json workspace snapshot-endpoint reference-id)) -(defn get-snapshot-references - "Lazily returns the snapshot references in `workspace` +(defn get-snapshot-references-for-snapshot-id + "Lazily returns the snapshot references for `snapshot-id` in `workspace` with `limit` resources per page (default: 100)." - ([workspace limit] + ([workspace snapshot-id limit] (letfn [(page [offset] - (let [{:keys [resources] :as _response} + (let [{:keys [gcpDataRepoSnapshots] :as _response} (-> (workspace-api-url workspace snapshot-endpoint) (http/get {:headers (auth/get-auth-header) - :query-params {:offset offset - :limit limit}}) + :query-params {:offset offset + :limit limit + :referencedSnapshotId snapshot-id}}) (util/response-body-json)) - total (+ offset (count resources))] - (lazy-cat resources (when (seq resources) (page total)))))] + total (+ offset (count gcpDataRepoSnapshots))] + (lazy-cat gcpDataRepoSnapshots + (when (seq gcpDataRepoSnapshots) (page total)))))] (util/lazy-unchunk (page 0)))) - ([workspace] - (get-snapshot-references workspace 100))) + ([workspace snapshot-id] + (get-snapshot-references-for-snapshot-id workspace snapshot-id 100))) (defn ^:private get-reference-for-snapshot-id "Return first snapshot reference for `snapshot-id` in `workspace`." [workspace snapshot-id] - (->> (get-snapshot-references workspace) - (filter #(= (get-in % [:reference :snapshot]) snapshot-id)) - first)) + (first (get-snapshot-references-for-snapshot-id workspace snapshot-id))) (def ^:private reference-creation-failed-message (str/join " " ["Could not create snapshot reference" diff --git a/api/src/wfl/sink.clj b/api/src/wfl/sink.clj new file mode 100644 index 000000000..a37636139 --- /dev/null +++ b/api/src/wfl/sink.clj @@ -0,0 +1,393 @@ +(ns wfl.sink + "Workload sink interface and its implementations." + (:require [clojure.data :as data] + [clojure.data.json :as json] + [clojure.edn :as edn] + [clojure.set :as set] + [clojure.spec.alpha :as s] + [clojure.string :as str] + [wfl.api.workloads :refer [defoverload]] + [wfl.jdbc :as jdbc] + [wfl.log :as log] + [wfl.module.all :as all] + [wfl.service.datarepo :as datarepo] + [wfl.service.firecloud :as firecloud] + [wfl.service.google.storage :as storage] + [wfl.service.postgres :as postgres] + [wfl.service.rawls :as rawls] + [wfl.stage :as stage] + [wfl.util :as util :refer [utc-now]]) + (:import [clojure.lang ExceptionInfo] + [wfl.util UserException])) + +(defmulti create-sink! + "Create a `Sink` instance using the database `transaction` and configuration + in the sink `request` and return a `[type items]` pair to be written to a + workload record as `sink_type` and `sink_items`. + Notes: + - This is a factory method registered for workload creation. + - The `Sink` type string must match a value of the `sink` enum in the + database schema. + - This multimethod is type-dispatched on the `:name` association in the + `request`." + (fn [_transaction _workload-id request] (:name request))) + +;; Interface +(defmulti load-sink! + "Return the `Sink` implementation associated with the `sink_type` and + `sink_items` fields of the `workload` row in the database. + Note that this multimethod is type-dispatched on the `:sink_type` + association in the `workload`." + (fn [_transaction workload] (:sink_type workload))) + +(defmulti update-sink! + "Update the internal state of the `sink`, consuming objects from the + Queue `upstream-queue`, performing any external effects as required. + Implementations should avoid maintaining in-memory state and making long- + running external calls, favouring internal queues to manage such tasks + asynchronously between invocations. + Note that the `Sink` and `Queue` are parameterised types + and the `Queue`'s parameterisation must be convertible to the `Sink`s." + (fn [_upstream-queue sink] (:type sink))) + +(defmethod create-sink! :default + [_ _ {:keys [name] :as request}] + (throw (UserException. + "Invalid sink name" + {:name name + :request request + :status 400 + :sources (-> create-sink! methods (dissoc :default) keys)}))) + +;; Terra Workspace Sink +(def ^:private ^:const terra-workspace-sink-name "Terra Workspace") +(def ^:private ^:const terra-workspace-sink-type "TerraWorkspaceSink") +(def ^:private ^:const terra-workspace-sink-table "TerraWorkspaceSink") +(def ^:private ^:const terra-workspace-sink-serialized-fields + {:workspace :workspace + :entityType :entity_type + :fromOutputs :from_outputs + :identifier :identifier}) + +(s/def ::identifier string?) +(s/def ::fromOutputs map?) + +;; reitit coercion spec +(s/def ::terra-workspace-sink + (s/and (all/has? :name #(= terra-workspace-sink-name %)) + (s/keys :req-un [::all/workspace + ::all/entityType + ::identifier + ::fromOutputs]))) + +(defn ^:private write-terra-workspace-sink [tx id request] + (let [create "CREATE TABLE %s OF TerraWorkspaceSinkDetails (PRIMARY KEY (id))" + alter "ALTER TABLE %s ALTER COLUMN id ADD GENERATED ALWAYS AS IDENTITY" + details (format "%s_%09d" terra-workspace-sink-type id)] + (jdbc/db-do-commands tx [(format create details) (format alter details)]) + [terra-workspace-sink-type + (-> (select-keys request (keys terra-workspace-sink-serialized-fields)) + (update :fromOutputs pr-str) + (set/rename-keys terra-workspace-sink-serialized-fields) + (assoc :details details) + (->> (jdbc/insert! tx terra-workspace-sink-table) first :id str))])) + +(defn ^:private load-terra-workspace-sink [tx {:keys [sink_items] :as workload}] + (if-let [id (util/parse-int sink_items)] + (-> (postgres/load-record-by-id! tx terra-workspace-sink-table id) + (set/rename-keys (set/map-invert terra-workspace-sink-serialized-fields)) + (update :fromOutputs edn/read-string) + (assoc :type terra-workspace-sink-type)) + (throw (ex-info "Invalid sink_items" {:workload workload})))) + +(def unknown-entity-type-error-message + "The entityType was not found in workspace.") + +(def terra-workspace-malformed-from-outputs-message + (str/join " " ["fromOutputs must define a mapping from workflow outputs" + "to the attributes of entityType."])) + +(def unknown-attributes-error-message + (str/join " " ["Found additional attributes in fromOutputs that are not" + "present in the entityType."])) + +(defn terra-workspace-sink-validate-request-or-throw + "Verify that the WFL has access the `workspace`." + [{:keys [entityType fromOutputs skipValidation workspace] :as sink}] + (when-not skipValidation + (firecloud/workspace-or-throw workspace) + (let [entity-type (keyword entityType) + entity-types (firecloud/list-entity-types workspace) + types (-> entity-types keys set)] + (when-not (types entity-type) + (throw (UserException. unknown-entity-type-error-message + (util/make-map entityType types workspace)))) + (when-not (map? fromOutputs) + (throw (UserException. terra-workspace-malformed-from-outputs-message + (util/make-map entityType fromOutputs)))) + (let [attributes (->> (get-in entity-types [entity-type :attributeNames]) + (cons (str entityType "_id")) + (mapv keyword)) + [missing _ _] (data/diff (set (keys fromOutputs)) (set attributes))] + (when (seq missing) + (throw (UserException. unknown-attributes-error-message + {:entityType entityType + :attributes (sort attributes) + :missing (sort missing) + :fromOutputs fromOutputs})))))) + sink) + +;; visible for testing +(defn rename-gather + "Transform the `values` using the transformation defined in `mapping`." + [values mapping] + (letfn [(literal? [x] (str/starts-with? x "$")) + (go! [v] + (cond (literal? v) (subs v 1 (count v)) + (string? v) (values (keyword v)) + (map? v) (rename-gather values v) + (coll? v) (keep go! v) + :else (throw (ex-info "Unknown operation" + {:operation v}))))] + (into {} (for [[k v] mapping] [k (go! v)])))) + +(defn ^:private terra-workspace-sink-to-attributes + [{:keys [outputs] :as workflow} fromOutputs] + (when-not (map? fromOutputs) + (throw (IllegalStateException. "fromOutputs is malformed"))) + (try + (rename-gather outputs fromOutputs) + (catch Exception cause + (throw (ex-info "Failed to coerce workflow outputs to attribute values" + {:fromOutputs fromOutputs :workflow workflow} + cause))))) + +(defn ^:private entity-exists? + "True when the `entity` exists in the `workspace`." + [workspace entity] + (try + (firecloud/get-entity workspace entity) + (catch ExceptionInfo ex + (when (not= (-> ex ex-data :status) 404) + (throw ex))))) + +(defn ^:private update-terra-workspace-sink + [executor {:keys [fromOutputs workspace entityType identifier details] :as _sink}] + (when-let [[_ {:keys [uuid outputs] :as workflow}] (stage/peek-queue executor)] + (log/debug (str/join " " ["coercing workflow" uuid "outputs to" entityType])) + (let [attributes (terra-workspace-sink-to-attributes workflow fromOutputs) + [_ name :as entity] [entityType (outputs (keyword identifier))]] + (when (entity-exists? workspace entity) + (log/debug (str/join " " ["entity" name "exists - deleting previous entity."])) + (firecloud/delete-entities workspace [entity])) + (log/debug (str/join " " ["upserting workflow" uuid "outputs as" name])) + (rawls/batch-upsert workspace [(conj entity attributes)]) + (stage/pop-queue! executor) + (log/info (str/join " " ["sunk workflow" uuid "to" workspace "as" name])) + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (jdbc/insert! tx details {:entity name + :updated (util/utc-now) + :workflow uuid}))))) + +(defn ^:private terra-workspace-sink-done? [_sink] true) + +(defn ^:private terra-workspace-sink-to-edn [sink] + (-> sink + (util/select-non-nil-keys (keys terra-workspace-sink-serialized-fields)) + (assoc :name terra-workspace-sink-name))) + +(defmethod create-sink! terra-workspace-sink-name + [tx id request] + (write-terra-workspace-sink + tx id (terra-workspace-sink-validate-request-or-throw request))) + +(defoverload load-sink! terra-workspace-sink-type load-terra-workspace-sink) +(defoverload update-sink! terra-workspace-sink-type update-terra-workspace-sink) +(defoverload stage/done? terra-workspace-sink-type terra-workspace-sink-done?) + +(defoverload util/to-edn terra-workspace-sink-type terra-workspace-sink-to-edn) + +;; TerraDataRepo Sink +(def ^:private ^:const datarepo-sink-name "Terra DataRepo") +(def ^:private ^:const datarepo-sink-type "TerraDataRepoSink") +(def ^:private ^:const datarepo-sink-table "TerraDataRepoSink") +(def ^:private ^:const datarepo-sink-serialized-fields + {:dataset :dataset + :table :dataset_table + :fromOutputs :from_outputs}) + +;; reitit coercion spec +(s/def ::terra-datarepo-sink + (s/and (all/has? :name #(= datarepo-sink-name %)) + (s/keys :req-un [::all/dataset ::all/table ::fromOutputs]))) + +(defn ^:private write-datarepo-sink [tx id request] + (let [create "CREATE TABLE %s OF TerraDataRepoSinkDetails (PRIMARY KEY (id))" + alter "ALTER TABLE %s ALTER COLUMN id ADD GENERATED ALWAYS AS IDENTITY" + details (format "%s_%09d" datarepo-sink-type id)] + (jdbc/db-do-commands tx [(format create details) (format alter details)]) + [datarepo-sink-type + (-> (select-keys request (keys datarepo-sink-serialized-fields)) + (update :dataset pr-str) + (update :fromOutputs pr-str) + (set/rename-keys datarepo-sink-serialized-fields) + (assoc :details details) + (->> (jdbc/insert! tx datarepo-sink-table) first :id str))])) + +(defn ^:private load-datarepo-sink [tx {:keys [sink_items] :as workload}] + (if-let [id (util/parse-int sink_items)] + (-> (postgres/load-record-by-id! tx datarepo-sink-table id) + (set/rename-keys (set/map-invert datarepo-sink-serialized-fields)) + (update :dataset edn/read-string) + (update :fromOutputs edn/read-string) + (assoc :type datarepo-sink-type)) + (throw (ex-info "Invalid sink_items" {:workload workload})))) + +(def datarepo-malformed-from-outputs-message + (str/join " " ["fromOutputs must define a mapping from workflow outputs" + "to columns in the table in the dataset."])) + +(def unknown-columns-error-message + (str/join " " ["Found column names in fromOutputs that are not columns of" + "the table in the dataset."])) + +(defn datarepo-sink-validate-request-or-throw + "Throw unless the user's sink `request` yields a valid configuration for a + TerraDataRepoSink by ensuring all resources specified in the request exist." + [{:keys [dataset table fromOutputs] :as request}] + (let [dataset' (datarepo/dataset dataset) + ;; eagerly evaluate for effects + table' (datarepo/table-or-throw table dataset')] + (when-not (map? fromOutputs) + (throw (UserException. datarepo-malformed-from-outputs-message + (util/make-map dataset fromOutputs)))) + (let [columns (map (comp keyword :name) (:columns table')) + [missing _ _] (data/diff (set (keys fromOutputs)) (set columns))] + (when (seq missing) + (throw (UserException. unknown-columns-error-message + {:dataset dataset + :table table + :columns (sort columns) + :missing (sort missing) + :fromOutputs fromOutputs})))) + (assoc request :dataset dataset'))) + +(defn ^:private push-job [{:keys [details] :as _sink} job] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (jdbc/insert! tx details job))) + +(defn ^:private peek-job-queue [{:keys [details] :as _sink}] + (let [query "SELECT * FROM %s + WHERE status = 'succeeded' AND consumed IS NULL + ORDER BY id LIMIT 1"] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (postgres/throw-unless-table-exists tx details) + (first (jdbc/query tx (format query details)))))) + +(defn ^:private pop-job-queue! + [{:keys [details] :as _sink} {:keys [id] :as _job}] + {:pre [(some? id) (integer? id)]} + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (jdbc/update! tx details {:consumed (utc-now)} ["id = ?" id]))) + +(def ^:private active-job-query + (format + "SELECT id, job, workflow FROM %%s WHERE status IN %s ORDER BY id ASC" + (util/to-quoted-comma-separated-list datarepo/active?))) + +(defn ^:private update-datarepo-job-statuses + "Fetch and record the status of all 'running' jobs from tdr created by the + `sink`. Throws `UserException` when any new job status is `failed`." + [{:keys [details] :as _sink}] + (letfn [(read-active-jobs [] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (map (juxt :id :job :workflow) + (jdbc/query tx (format active-job-query details))))) + (write-job-status [id status] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (jdbc/update! tx details + {:status status :updated (utc-now)} + ["id = ?" id])))] + (doseq [[id job-id workflow] (read-active-jobs)] + (let [job (datarepo/job-metadata job-id) + status (-> job :job_status str/lower-case)] + (write-job-status id status) + (when (= "failed" status) + (throw (UserException. "A DataRepo ingest job failed" + {:job job + :workflow workflow}))))))) + +(defn ^:private to-dataset-row + "Use `fromOutputs` to coerce the `workflow` outputs into a row in the dataset + where `fromOutputs` describes a mapping from workflow outputs to columns in + the dataset table." + [fromOutputs {:keys [outputs] :as workflow}] + (when-not (map? fromOutputs) + (throw (IllegalStateException. "fromOutputs is malformed"))) + (try + (rename-gather outputs fromOutputs) + (catch Exception cause + (throw (ex-info "Failed to coerce workflow outputs to dataset columns" + {:fromOutputs fromOutputs :workflow workflow} + cause))))) + +(defn ^:private start-ingesting-outputs + "Start ingesting the `workflow` outputs as a new row in the target dataset + and push the tdr ingest job into the `sink`'s job queue." + [{:keys [dataset table fromOutputs] :as sink} + {:keys [uuid] :as workflow}] + (let [file (storage/gs-url "broad-gotc-dev-wfl-ptc-test-outputs" (str uuid ".json"))] + (-> (to-dataset-row fromOutputs workflow) + (json/write-str :escape-slash false) + (storage/upload-content file)) + (->> (datarepo/ingest-table (:id dataset) file table) + (assoc {:status "running" :workflow uuid} :job) + (push-job sink)))) + +(defn ^:private update-datarepo-sink + "Attempt to a pull a workflow off the upstream `executor` queue and write its + outputs as new rows in a tdr dataset table asynchronously." + [executor sink] + (when-let [[_ workflow] (stage/peek-queue executor)] + (start-ingesting-outputs sink workflow) + (stage/pop-queue! executor)) + (update-datarepo-job-statuses sink) + (when-let [{:keys [workflow job] :as record} (peek-job-queue sink)] + (try + (let [res (datarepo/get-job-result job)] + (log/info "Sunk workflow outputs to dataset")) + (finally + (pop-job-queue! sink record))))) + +(defn ^:private datarepo-sink-done? + "True when all tdr ingest jobs created by the `_sink` have terminated." + [{:keys [details] :as _sink}] + (let [query "SELECT COUNT(*) FROM %s + WHERE status <> 'failed' AND consumed IS NULL"] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (postgres/throw-unless-table-exists tx details) + (-> (jdbc/query tx (format query details)) first :count zero?)))) + +(defn ^:private datarepo-sink-to-edn [sink] + (-> sink + (util/select-non-nil-keys (keys datarepo-sink-serialized-fields)) + (update :dataset :id) + (assoc :name datarepo-sink-name))) + +(defmethod create-sink! datarepo-sink-name + [tx id request] + (write-datarepo-sink + tx id (datarepo-sink-validate-request-or-throw request))) + +(defoverload load-sink! datarepo-sink-type load-datarepo-sink) +(defoverload update-sink! datarepo-sink-type update-datarepo-sink) +(defoverload stage/done? datarepo-sink-type datarepo-sink-done?) + +(defoverload util/to-edn datarepo-sink-type datarepo-sink-to-edn) + +;; reitit http coercion specs for a sink +;; Recall s/or doesn't work (https://github.com/metosin/reitit/issues/494) +(s/def ::sink + #(condp = (:name %) + terra-workspace-sink-name (s/valid? ::terra-workspace-sink %) + datarepo-sink-name (s/valid? ::terra-datarepo-sink %))) diff --git a/api/src/wfl/source.clj b/api/src/wfl/source.clj new file mode 100644 index 000000000..b60aba80f --- /dev/null +++ b/api/src/wfl/source.clj @@ -0,0 +1,459 @@ +(ns wfl.source + (:require [clojure.edn :as edn] + [clojure.instant :as instant] + [clojure.spec.alpha :as s] + [clojure.set :as set] + [clojure.tools.logging :as log] + [wfl.api.workloads :refer [defoverload]] + [wfl.jdbc :as jdbc] + [wfl.module.all :as all] + [wfl.service.datarepo :as datarepo] + [wfl.service.postgres :as postgres] + [wfl.stage :as stage :refer [log-prefix]] + [wfl.util :as util :refer [utc-now]]) + (:import [clojure.lang ExceptionInfo] + [java.sql Timestamp] + [java.time OffsetDateTime ZoneId] + [java.time.format DateTimeFormatter] + [java.time.temporal ChronoUnit] + [wfl.util UserException])) + +;; specs +(s/def ::column string?) +(s/def ::snapshotReaders (s/* util/email-address?)) +(s/def ::snapshots (s/* ::all/uuid)) +(s/def ::tdr-source + (s/keys :req-un [::all/name + ::column + ::all/dataset + ::all/table + ::snapshotReaders] + :opt-un [::snapshots])) + +(s/def ::snapshot-list-source + (s/keys :req-un [::all/name ::snapshots])) + +(s/def ::source (s/or :dataset ::tdr-source + :snapshots ::snapshot-list-source)) + +;; `source` "interface" +(defmulti start-source! + "Start enqueuing items onto the `source`'s queue to be consumed by a later + processing stage. This operation should not perform any long-running + external effects other than database operations via the `transaction`. This + function is called at most once during a workload's operation." + (fn [_transaction source] (:type source))) + +(defmulti stop-source! + "Stop enqueuing inputs onto the `source`'s queue to be consumed by a later + processing stage. This operation should not perform any long-running + external effects other than database operations via the `transaction`. This + function is called at most once during a workload's operation and will only + be called after `start-source!`. Any outstanding items on the `source` + queue may still be consumed by a later processing stage." + (fn [_transaction source] (:type source))) + +(defmulti update-source! + "Enqueue items onto the `source` queue to be consumed by a later processing + stage unless stopped, performing any external effects as necessary. + Implementations should avoid maintaining in-memory state and making long- + running external calls, favouring internal queues to manage such tasks + asynchronously between invocations. This function is called one or more + times after `start-source!` and may be called after `stop-source!`" + :type) + +;; source load/save operations +(defmulti create-source! + "Create a `Source` instance using the database `transaction` and configuration + in the source `request` and return a `[type items]` pair to be written to a + workload record as `source_type` and `source_items`. + Notes: + - This is a factory method registered for workload creation. + - The `Source` type string must match a value of the `source` enum in the + database schema. + - This multimethod is type-dispatched on the `:name` association in the + `request`." + (fn [_transaction _id source-request] (:name source-request))) + +(defmulti load-source! + "Return the `Source` implementation associated with the `source_type` and + `source_items` fields of the `workload` row in the database. Note that this + multimethod is type-dispatched on the `:source_type` association in the + `workload`." + (fn [_transaction workload] (:source_type workload))) + +(defmethod create-source! :default + [_ _ {:keys [name] :as request}] + (throw (UserException. + "Invalid source name" + {:name name + :request request + :status 400 + :sources (-> create-source! methods (dissoc :default) keys)}))) + +;; Terra Data Repository Source +(def ^:private ^:const tdr-source-name "Terra DataRepo") +(def ^:private ^:const tdr-source-type "TerraDataRepoSource") +(def ^:private ^:const tdr-source-table "TerraDataRepoSource") +(def ^:private ^:const tdr-source-serialized-fields + {:dataset :dataset + :table :dataset_table + :column :table_column_name + :snapshotReaders :snapshot_readers}) + +(def ^:private bigquery-datetime-format + (DateTimeFormatter/ofPattern "yyyy-MM-dd'T'HH:mm:ss")) + +(defn ^:private timestamp-to-offsetdatetime + "Parse the Timestamp `t` into an `OffsetDateTime`." + [^Timestamp t] + (OffsetDateTime/ofInstant (.toInstant t) (ZoneId/of "UTC"))) + +(defn ^:private write-tdr-source [tx id source] + (let [create "CREATE TABLE %s OF TerraDataRepoSourceDetails (PRIMARY KEY (id))" + alter "ALTER TABLE %s ALTER COLUMN id ADD GENERATED ALWAYS AS IDENTITY" + details (format "%s_%09d" tdr-source-type id)] + (jdbc/db-do-commands tx [(format create details) (format alter details)]) + [tdr-source-type + (-> (select-keys source (keys tdr-source-serialized-fields)) + (update :dataset pr-str) + (set/rename-keys tdr-source-serialized-fields) + (assoc :details details) + (->> (jdbc/insert! tx tdr-source-table) first :id str))])) + +(defn ^:private load-tdr-source [tx {:keys [source_items] :as workload}] + (if-let [id (util/parse-int source_items)] + (-> (postgres/load-record-by-id! tx tdr-source-table id) + (set/rename-keys (set/map-invert tdr-source-serialized-fields)) + (assoc :type tdr-source-type) + (update :dataset edn/read-string)) + (throw (ex-info "source_items is not an integer" {:workload workload})))) + +(defn datarepo-source-validate-request-or-throw + "Verify that the `dataset` exists and that WFL has the necessary permissions + to read it." + [{:keys [dataset table column skipValidation] :as source}] + (if skipValidation + source + (let [dataset (datarepo/dataset dataset)] + (doto (datarepo/table-or-throw table dataset) + (datarepo/throw-unless-column-exists column dataset)) + (assoc source :dataset dataset)))) + +(defn combine-tdr-source-details + "Reduce to `result` by combining the Terra Data Repo source `_detail`. + Collect `datarepo_row_ids` already seen while preserving the latest + `end_time` and the earliest `start_time`." + [result {:keys [datarepo_row_ids end_time snapshot_creation_job_status + start_time] :as _detail}] + (if (#{"running" "succeeded"} snapshot_creation_job_status) + (-> result + (update :datarepo_row_ids into datarepo_row_ids) + (update :end_time util/latest end_time) + (update :start_time util/earliest start_time)) + result)) + +(defn ^:private find-new-rows + "Query TDR for rows within `_interval` that are new to `source`." + [{:keys [dataset details table column] :as source} + [begin end :as _interval]] + (log/debug (format "%s Looking for rows in %s.%s between [%s, %s]..." + (log-prefix source) (:name dataset) table begin end)) + (let [wfl (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (postgres/get-table tx details)) + old (when (seq wfl) (reduce combine-tdr-source-details wfl)) + start (if-let [start_time (:start_time old)] + (-> start_time + (util/latest (instant/read-instant-timestamp begin)) + timestamp-to-offsetdatetime + (.format bigquery-datetime-format)) + begin) + tdr (-> dataset + (datarepo/query-table-between + table column [start end] [:datarepo_row_id]) + :rows flatten)] + (when (seq tdr) (remove (set (:datarepo_row_ids old)) tdr)))) + +(defn ^:private go-create-snapshot! + "Create snapshot in TDR from `dataset` body, `table` and `row-ids` then + write job info as well as rows into `source-details-name` table. + Snapshots will be readable by members of the `snapshotReaders` list. + `suffix` will be appended to the snapshot names." + [suffix {:keys [dataset table snapshotReaders] :as _source} row-ids] + (let [columns (->> (datarepo/all-columns dataset table) + (mapv :name) + (cons "datarepo_row_id"))] + (-> (datarepo/make-snapshot-request dataset columns table row-ids) + (update :name #(str % suffix)) + (assoc :readers snapshotReaders) + datarepo/create-snapshot-job))) + +(defn ^:private create-snapshots + "Create uniquely named snapshots in TDR with max partition size of 500, + using the frozen `now-obj`, from `row-ids`, return shards and TDR job-ids." + [source now-obj row-ids] + (let [dt-format (DateTimeFormatter/ofPattern "YYYYMMdd'T'HHmmss") + compact-now (.format now-obj dt-format)] + (letfn [(create-snapshot [idx shard] + [shard (go-create-snapshot! (format "_%s_%s" compact-now idx) + source shard)])] + (->> row-ids + (partition-all 500) + (map vec) + (map-indexed create-snapshot))))) + +(defn ^:private get-pending-tdr-jobs [{:keys [details] :as _source}] + (let [query "SELECT id, snapshot_creation_job_id FROM %s + WHERE snapshot_creation_job_status = 'running' + ORDER BY id ASC"] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> (format query details) + (jdbc/query tx) + (map (juxt :id :snapshot_creation_job_id)))))) + +(defn ^:private check-tdr-job + "Check TDR job status for `job-id`, return a map with job-id, + snapshot_id and job_status if job has failed or succeeded, otherwise nil." + [job-id] + (let [{:keys [job_status] :as result} (datarepo/job-metadata job-id)] + (case job_status + "running" result + "succeeded" (assoc result :snapshot_id (:id (datarepo/get-job-result job-id))) + (do (log/warn (format "Snapshot creation job %s failed!" job-id)) + result)))) + +(defn ^:private write-snapshot-id + "Write `snapshot_id` and `job_status` into source `details` table + from the `_tdr-job-metadata` map, update timestamp with real now." + [{:keys [details] :as _source} + [id {:keys [job_status snapshot_id] :as _tdr-job-metadata}]] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (jdbc/update! tx details {:snapshot_creation_job_status job_status + :snapshot_id snapshot_id + :updated (utc-now)} + ["id = ?" id]))) + +(defn ^:private write-snapshots-creation-jobs + "Write the shards and corresponding snapshot creation jobs from + `shards->snapshot-jobs` into source `details` table, with the frozen `now`. + Also initialize all jobs statuses to running." + [{:keys [last_checked details] :as source} now shards->snapshot-jobs] + (letfn [(make-record [[shard id]] + {:snapshot_creation_job_id id + :snapshot_creation_job_status "running" + :datarepo_row_ids shard + :start_time last_checked + :end_time now})] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> shards->snapshot-jobs + (map make-record) + (jdbc/insert-multi! tx details))) + (log/debug (format "%s Snapshot creation jobs written." (log-prefix source))))) + +(defn ^:private update-last-checked + "Update the `last_checked` field in source table with + the frozen `now`." + ([tx {:keys [id] :as _source} now] + (jdbc/update! tx tdr-source-table {:last_checked now} ["id = ?" id])) + ([source now] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (update-last-checked tx source now)))) + +(defn ^:private find-and-snapshot-new-rows + "Create and enqueue snapshots from new rows in the `source` dataset." + [{:keys [dataset table last_checked] :as source} utc-now] + (let [checked (timestamp-to-offsetdatetime last_checked) + hours-ago (* 2 (max 1 (.between ChronoUnit/HOURS checked utc-now))) + then (.minusHours utc-now hours-ago) + shards->jobs (->> [then utc-now] + (mapv #(.format % bigquery-datetime-format)) + (find-new-rows source) + (create-snapshots source utc-now))] + (when (seq shards->jobs) + (log/info (format "%s Snapshots created from new rows in %s.%s." (log-prefix source) (:name dataset) table)) + (write-snapshots-creation-jobs source utc-now shards->jobs) + (update-last-checked source utc-now)))) + +(defn ^:private update-pending-snapshot-jobs + "Update the status of TDR snapshot jobs that are still 'running'." + [source] + (log/debug (format "%s Looking for running snapshot jobs..." (log-prefix source))) + (let [pending-tdr-jobs (get-pending-tdr-jobs source)] + (when (seq pending-tdr-jobs) + (->> pending-tdr-jobs + (map #(update % 1 check-tdr-job)) + (run! #(write-snapshot-id source %))) + (log/debug (format "%s Running snapshot jobs updated." (log-prefix source)))))) + +(defn ^:private update-tdr-source + "Check for new data in TDR from `source`, create new snapshots, + insert resulting job creation ids into database and update the + timestamp for next time." + [{:keys [stopped] :as source}] + (when-not stopped + (find-and-snapshot-new-rows source (utc-now))) + (update-pending-snapshot-jobs source) + ;; load and return the source table + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (load-tdr-source tx {:source_items (str (:id source))}))) + +(defn ^:private start-tdr-source [tx source] + (update-last-checked tx source (utc-now))) + +(defn ^:private stop-tdr-source [tx {:keys [id] :as _source}] + (jdbc/update! tx tdr-source-table {:stopped (utc-now)} ["id = ?" id])) + +(defn ^:private peek-tdr-source-details + "Get first unconsumed snapshot record from `details` table." + [{:keys [details] :as _source}] + (let [query "SELECT * FROM %s + WHERE consumed IS NULL + AND snapshot_id IS NOT NULL + ORDER BY id ASC + LIMIT 1"] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> (format query details) + (jdbc/query tx) + first)))) + +(defn ^:private peek-tdr-source-queue + "Get first unconsumed snapshot from `source` queue." + [source] + (when-let [{:keys [snapshot_id] :as _record} (peek-tdr-source-details source)] + [:datarepo/snapshot (datarepo/snapshot snapshot_id)])) + +(defn ^:private tdr-source-queue-length + "Return the number of unconsumed snapshot records from `details` table." + [{:keys [details] :as _source}] + (let [query "SELECT COUNT(*) FROM %s + WHERE consumed IS NULL + AND snapshot_creation_job_status <> 'failed'"] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> (format query details) + (jdbc/query tx) + first + :count)))) + +(defn ^:private pop-tdr-source-queue + "Consume first unconsumed snapshot record in `details` table, or throw if none." + [{:keys [details] :as source}] + (if-let [{:keys [id] :as _record} (peek-tdr-source-details source)] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (let [now (utc-now)] + (jdbc/update! tx details {:consumed now :updated now} ["id = ?" id]))) + (throw (ex-info "No snapshots in queue" {:source source})))) + +(defn ^:private tdr-source-done? [{:keys [stopped] :as source}] + (and stopped (zero? (stage/queue-length source)))) + +(defn ^:private tdr-source-to-edn [source] + (-> source + (util/select-non-nil-keys (keys tdr-source-serialized-fields)) + (update :dataset :id) + (assoc :name tdr-source-name))) + +(defmethod create-source! tdr-source-name + [tx id request] + (write-tdr-source tx id (datarepo-source-validate-request-or-throw request))) + +(defoverload load-source! tdr-source-type load-tdr-source) +(defoverload start-source! tdr-source-type start-tdr-source) +(defoverload update-source! tdr-source-type update-tdr-source) +(defoverload stop-source! tdr-source-type stop-tdr-source) + +(defoverload stage/peek-queue tdr-source-type peek-tdr-source-queue) +(defoverload stage/pop-queue! tdr-source-type pop-tdr-source-queue) +(defoverload stage/queue-length tdr-source-type tdr-source-queue-length) +(defoverload stage/done? tdr-source-type tdr-source-done?) + +(defoverload util/to-edn tdr-source-type tdr-source-to-edn) + +;; TDR Snapshot List Source +(def ^:private ^:const tdr-snapshot-list-name "TDR Snapshots") +(def ^:private ^:const tdr-snapshot-list-type "TDRSnapshotListSource") + +(defn tdr-snappshot-list-validate-request-or-throw + [{:keys [skipValidation] :as source}] + (letfn [(snapshot-or-throw [snapshot-id] + (try + (datarepo/snapshot snapshot-id) + (catch ExceptionInfo e + (throw (UserException. "Cannot access snapshot" + {:snapshot snapshot-id + :status (-> e ex-data :status)} + e)))))] + (if skipValidation + source + (update source :snapshots #(mapv snapshot-or-throw %))))) + +(defn ^:private write-tdr-snapshot-list [tx id {:keys [snapshots] :as _request}] + (let [create "CREATE TABLE %s OF ListSource (PRIMARY KEY (id))" + alter "ALTER TABLE %s ALTER COLUMN id ADD GENERATED ALWAYS AS IDENTITY" + details (format "%s_%09d" tdr-snapshot-list-type id)] + (jdbc/db-do-commands tx [(format create details) (format alter details)]) + (jdbc/insert-multi! tx details (map #(hash-map :item (pr-str %)) snapshots)) + [tdr-snapshot-list-type details])) + +(defn ^:private load-tdr-snapshot-list + [tx {:keys [source_items] :as _workload}] + {:type tdr-snapshot-list-type + :items source_items + :snapshots (postgres/get-table tx source_items)}) + +(defn ^:private start-tdr-snapshot-list [_ source] source) +(defn ^:private stop-tdr-snapshot-list [_ source] source) +(defn ^:private update-tdr-snapshot-list [source] source) + +(defn ^:private peek-tdr-snapshot-details-table [{:keys [items] :as _source}] + (let [query "SELECT * FROM %s + WHERE consumed IS NULL + ORDER BY id ASC + LIMIT 1"] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> (format query items) + (jdbc/query tx) + first)))) + +(defn ^:private peek-tdr-snapshot-list [source] + (when-let [{:keys [item]} (peek-tdr-snapshot-details-table source)] + [:datarepo/snapshot (edn/read-string item)])) + +(defn ^:private tdr-snapshot-list-queue-length [{:keys [items] :as _source}] + (let [query "SELECT COUNT (*) FROM %s WHERE consumed IS NULL"] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> (format query items) + (jdbc/query tx) + first + :count)))) + +(defn ^:private pop-tdr-snapshot-list [{:keys [items] :as source}] + (if-let [{:keys [id]} (peek-tdr-snapshot-details-table source)] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (jdbc/update! tx items {:consumed (utc-now)} ["id = ?" id])) + (throw (ex-info "Attempt to pop empty queue" {:source source})))) + +(defn ^:private tdr-snapshot-list-done? [source] + (zero? (tdr-snapshot-list-queue-length source))) + +(defn ^:private tdr-snapshot-list-to-edn [source] + (let [read-snapshot-id (comp :id edn/read-string :item)] + (-> (select-keys source [:snapshots]) + (assoc :name tdr-snapshot-list-name) + (update :snapshots #(map read-snapshot-id %))))) + +(defmethod create-source! tdr-snapshot-list-name + [tx id request] + (write-tdr-snapshot-list + tx id (tdr-snappshot-list-validate-request-or-throw request))) + +(defoverload load-source! tdr-snapshot-list-type load-tdr-snapshot-list) +(defoverload start-source! tdr-snapshot-list-type start-tdr-snapshot-list) +(defoverload stop-source! tdr-snapshot-list-type stop-tdr-snapshot-list) +(defoverload update-source! tdr-snapshot-list-type update-tdr-snapshot-list) + +(defoverload stage/peek-queue tdr-snapshot-list-type peek-tdr-snapshot-list) +(defoverload stage/pop-queue! tdr-snapshot-list-type pop-tdr-snapshot-list) +(defoverload stage/queue-length tdr-snapshot-list-type tdr-snapshot-list-queue-length) +(defoverload stage/done? tdr-snapshot-list-type tdr-snapshot-list-done?) + +(defoverload util/to-edn tdr-snapshot-list-type tdr-snapshot-list-to-edn) diff --git a/api/src/wfl/stage.clj b/api/src/wfl/stage.clj new file mode 100644 index 000000000..83b768d42 --- /dev/null +++ b/api/src/wfl/stage.clj @@ -0,0 +1,24 @@ +(ns wfl.stage + "An interface for operations on a queue-based pipeline processing stage, + e.g. source, executor, or sink.") + +(defmulti peek-queue + "Peek the first object from the `queue`, if one exists." + :type) + +(defmulti pop-queue! + "Pop the first object from the `queue`. Throws if none exists." + :type) + +(defmulti queue-length + "Return the number of objects in the `queue`." + :type) + +(defmulti done? + "Test if the processing `stage` is complete and will not process any more data." + :type) + +(defn log-prefix + "Prefix string for `stage` logs indicating the `type` (table) and row `id`." + [{:keys [type id] :as _stage}] + (format "[%s id=%s]" type id)) diff --git a/api/src/wfl/tsv.clj b/api/src/wfl/tsv.clj index 2f6755dd8..b958a8db3 100644 --- a/api/src/wfl/tsv.clj +++ b/api/src/wfl/tsv.clj @@ -77,7 +77,7 @@ [table] (let [writer (StringWriter.)] (write table writer) - (.toString writer))) + (str writer))) (defn write-file "Write TABLE, a sequence of .tsv field sequences, to FILE." diff --git a/api/src/wfl/util.clj b/api/src/wfl/util.clj index fc7e259e6..de9dd445a 100644 --- a/api/src/wfl/util.clj +++ b/api/src/wfl/util.clj @@ -1,29 +1,31 @@ (ns wfl.util "Some utilities shared across this program." - (:require [clojure.data.csv :as csv] - [clojure.data.json :as json] - [clojure.java.io :as io] - [clojure.java.shell :as shell] - [clojure.spec.alpha :as s] - [clojure.string :as str] - [clojure.tools.logging :as log] - [wfl.wfl :as wfl]) + (:require [clojure.data.csv :as csv] + [clojure.data.json :as json] + [clojure.java.io :as io] + [clojure.java.shell :as shell] + [clojure.spec.alpha :as s] + [clojure.string :as str] + [wfl.log :as log] + [wfl.wfl :as wfl]) (:import [java.io File IOException StringWriter Writer] [java.nio.file Files] [java.nio.file.attribute FileAttribute] - [java.time OffsetDateTime] + [java.time OffsetDateTime ZoneId] [java.time.temporal ChronoUnit] [java.util ArrayList Collections Random UUID] [java.util.concurrent TimeUnit TimeoutException] - [java.util.zip ZipOutputStream ZipEntry] - [org.apache.commons.io FilenameUtils])) + [javax.mail.internet InternetAddress] + [org.apache.commons.io FilenameUtils]) + (:gen-class)) (defmacro do-or-nil "Value of `body` or `nil` if it throws." [& body] `(try (do ~@body) (catch Exception x# - (log/warn x# "from wfl.util/do-or-nil")))) + (log/warn (str/join " " [(str x#) "from wfl.util/do-or-nil"])) + nil))) ;; Parsers that will not throw. ;; @@ -35,8 +37,9 @@ [^String object] (json/read-str object :key-fn keyword)) -(defn response-body-json [response] +(defn response-body-json "Return the :body of the http `response` as JSON" + [response] (-> response :body (or "null") parse-json)) (defn slurp-json @@ -77,7 +80,7 @@ (defn extension "Return the (last) file extension from `filename`, if one exists." [filename] - (if-let [idx (str/last-index-of filename ".")] + (when-let [idx (str/last-index-of filename ".")] (subs filename (inc idx) (count filename)))) (defn basename @@ -93,7 +96,7 @@ (if (= "/" filename) filename (if-let [idx (str/last-index-of filename "/" (- (count filename) 2))] - (if (= idx 0) "/" (subs filename 0 idx)) + (if (zero? idx) "/" (subs filename 0 idx)) ""))) (defn deep-merge @@ -133,17 +136,6 @@ (io/make-parents target) (io/copy file target)))))) -(defn zip-files - "Return ZIP with named FILES zipped into it." - [^File zip & files] - (with-open [out (ZipOutputStream. (io/output-stream zip))] - (doseq [file files] - (let [import (io/file file)] - (with-open [in (io/reader import)] - (.putNextEntry out (ZipEntry. (.getName import))) - (io/copy in out))))) - zip) - (defn sleep-seconds "Sleep for N seconds." [n] @@ -176,16 +168,18 @@ (defn minutes-between "The number of minutes from START to END." [start end] - (. ChronoUnit/MINUTES between - (OffsetDateTime/parse start) - (OffsetDateTime/parse end))) + (.between + ChronoUnit/SECONDS + (OffsetDateTime/parse start) + (OffsetDateTime/parse end))) (defn seconds-between "The number of seconds from START to END." [start end] - (. ChronoUnit/SECONDS between - (OffsetDateTime/parse start) - (OffsetDateTime/parse end))) + (.between + ChronoUnit/SECONDS + (OffsetDateTime/parse start) + (OffsetDateTime/parse end))) (defn summarize "Summarize COMMANDS in a string vector." @@ -324,12 +318,6 @@ "The nil UUID." (UUID/fromString "00000000-0000-0000-0000-000000000000")) -(defn uuid-nil? - "True when UUID is UUID-NIL or its string representation." - [uuid] - (or (= uuid uuid-nil) - (= uuid (str uuid-nil)))) - (defn extract-resource "Extract the resource given by RESOURCE-NAME to a temporary folder @returns java.io.File to the extracted resource @@ -382,11 +370,11 @@ ---------- acquire - thunk returning newly acquired resource release - function to clean up resource, called before this function returns - use - function that uses the resource" - [acquire release use] + utilize - function that uses the resource" + [acquire release utilize] (let [resource (acquire)] (try - (use resource) + (utilize resource) (finally (release resource))))) @@ -399,7 +387,7 @@ (defn randomize "Append a random suffix to `string`." [string] - (->> (str/replace (UUID/randomUUID) "-" "") (str string))) + (str string (str/replace (UUID/randomUUID) "-" ""))) (defn curry "Curry the function `f` such that its arguments may be supplied across two @@ -421,7 +409,8 @@ result (do (when (<= max-attempts attempt) (throw (TimeoutException. "Max number of attempts exceeded"))) - (log/debugf "Sleeping - attempt #%s of %s" attempt max-attempts) + (log/debug + (format "Sleeping - attempt #%s of %s" attempt max-attempts)) (.sleep TimeUnit/SECONDS seconds) (recur (inc attempt)))))) ([task seconds] @@ -434,19 +423,25 @@ (defn terra-id " - Generate a Terra-compatible primary key column name for the specified TSV-TYPE and base COL. + Generate a Terra-compatible primary key column name for the + specified TSV-TYPE and base COL. The first column of the table must be its primary key, and named accordingly: entity:[entity-type]_id membership:[entity-type]_set_id - For tsv-type :entity, 'entity:sample_id' will upload the .tsv data into a `sample` table - in the workspace (or create one if it does not exist). + For tsv-type :entity, 'entity:sample_id' will upload the .tsv data + into a `sample` table in the workspace (or create one if it does not + exist). + If the table already contains a sample with that id, it will get overwritten. - For tsv-type :membership, 'membership:sample_set_id' will append sample names to a `sample_set` table - in the workspace (or create one if it does not exist). - If the table already contains a sample set with that id, it will be appended to and not overwritten. + For tsv-type :membership, 'membership:sample_set_id' will append + sample names to a `sample_set` table in the workspace (or create one + if it does not exist). + + If the table already contains a sample set with that id, it will be + appended to and not overwritten. Parameters ---------- @@ -460,8 +455,11 @@ " [tsv-type col] {:pre [(s/valid? ::tsv-type tsv-type)]} - (let [stripped (-> (unsuffix col "_id") (unsuffix "_set"))] - (str (name tsv-type) ":" stripped (when (= :membership tsv-type) "_set") "_id"))) + (str/join [(name tsv-type) + ":" + (-> col (unsuffix "_id") (unsuffix "_set")) + (when (= :membership tsv-type) "_set") + "_id"])) (defn columns-rows->tsv " @@ -533,7 +531,7 @@ (defmulti to-edn "Return an EDN representation of the `object` that will be shown to users." - (fn [object] (:type object))) + :type) (defmethod to-edn :default [x] x) @@ -577,3 +575,26 @@ [s] (let [[name value & rest] (str/split s #":" 3)] (and (label-name? name) (label-value? value) (nil? rest)))) + +(defn uuid-string? [s] (uuid? (do-or-nil (UUID/fromString s)))) +(defn datetime-string? [s] (do-or-nil (OffsetDateTime/parse s))) + +(defn email-address? + "True if `s` is an email address." + [s] + (do-or-nil (or (.validate (InternetAddress. s)) true))) + +(defn utc-now + "Return OffsetDateTime/now in UTC." + [] + (OffsetDateTime/now (ZoneId/of "UTC"))) + +(defn earliest + "Return the earliest time of `instants`." + [& instants] + (first (sort instants))) + +(defn latest + "Return the latest time of `instants`." + [& instants] + (last (sort instants))) diff --git a/api/test/resources/datasets/illumina-genotyping-array.json b/api/test/resources/datasets/illumina-genotyping-array.json new file mode 100644 index 000000000..5e79f4613 --- /dev/null +++ b/api/test/resources/datasets/illumina-genotyping-array.json @@ -0,0 +1,176 @@ +{ + "name": "illumina_genotyping_array", + "description": "test inputs and outputs for the illumina_genotyping_array pipeline", + "defaultProfileId": "6370f5a1-d777-4991-8200-ceab83521d43", + "schema": { + "tables": [ + { + "name": "inputs", + "columns": [ + { + "name": "analysis_version_number", + "datatype": "integer" + }, + { + "name": "chip_well_barcode", + "datatype": "string" + }, + { + "name": "green_idat_cloud_path", + "datatype": "fileref" + }, + { + "name": "red_idat_cloud_path", + "datatype": "fileref" + }, + { + "name": "sample_alias", + "datatype": "string" + }, + { + "name": "reported_gender", + "datatype": "string" + }, + { + "name": "ingested", + "datatype": "timestamp" + } + ], + "primaryKey": [ + "analysis_version_number", + "chip_well_barcode", + "green_idat_cloud_path", + "red_idat_cloud_path", + "sample_alias", + "reported_gender", + "ingested" + ], + "partitionMode": "date", + "datePartitionOptions": { + "column": "datarepo_ingest_date" + } + }, + { + "name": "outputs", + "columns": [ + { + "name": "arrays_subset_variant_calling_control_metrics", + "datatype": "fileref" + }, + { + "name": "arrays_subset_variant_calling_detail_metrics", + "datatype": "fileref" + }, + { + "name": "arrays_subset_variant_calling_summary_metrics", + "datatype": "fileref" + }, + { + "name": "arrays_variant_calling_control_metrics", + "datatype": "fileref" + }, + { + "name": "arrays_variant_calling_detail_metrics", + "datatype": "fileref" + }, + { + "name": "arrays_variant_calling_summary_metrics", + "datatype": "fileref" + }, + { + "name": "check_fingerprint_lod", + "datatype": "float" + }, + { + "name": "contamination_metrics", + "datatype": "fileref" + }, + { + "name": "fingerprint_detail_metrics", + "datatype": "fileref" + }, + { + "name": "fingerprint_summary_metrics", + "datatype": "fileref" + }, + { + "name": "genotype_concordance_contingency_metrics", + "datatype": "fileref" + }, + { + "name": "genotype_concordance_detail_metrics", + "datatype": "fileref" + }, + { + "name": "genotype_concordance_failed", + "datatype": "boolean" + }, + { + "name": "genotype_concordance_summary_metrics", + "datatype": "fileref" + }, + { + "name": "green_idat_md5_cloud_path", + "datatype": "fileref" + }, + { + "name": "gtc", + "datatype": "fileref" + }, + { + "name": "output_fingerprint_vcf", + "datatype": "fileref" + }, + { + "name": "output_fingerprint_vcf_index", + "datatype": "fileref" + }, + { + "name": "output_vcf", + "datatype": "fileref" + }, + { + "name": "output_vcf_index", + "datatype": "fileref" + }, + { + "name": "output_vcf_md5_cloud_path", + "datatype": "fileref" + }, + { + "name": "red_idat_md5_cloud_path", + "datatype": "fileref" + } + ], + "primaryKey": [ + "arrays_subset_variant_calling_control_metrics", + "arrays_subset_variant_calling_detail_metrics", + "arrays_subset_variant_calling_summary_metrics", + "arrays_variant_calling_control_metrics", + "arrays_variant_calling_detail_metrics", + "arrays_variant_calling_summary_metrics", + "check_fingerprint_lod", + "contamination_metrics", + "fingerprint_detail_metrics", + "fingerprint_summary_metrics", + "genotype_concordance_contingency_metrics", + "genotype_concordance_detail_metrics", + "genotype_concordance_failed", + "genotype_concordance_summary_metrics", + "green_idat_md5_cloud_path", + "gtc", + "output_fingerprint_vcf", + "output_fingerprint_vcf_index", + "output_vcf", + "output_vcf_index", + "output_vcf_md5_cloud_path", + "red_idat_md5_cloud_path" + ], + "partitionMode": "date", + "datePartitionOptions": { + "column": "datarepo_ingest_date" + } + } + ] + } +} diff --git a/api/test/resources/workflows/illumina_genotyping_array/fromOutputs.edn b/api/test/resources/workflows/illumina_genotyping_array/fromOutputs.edn new file mode 100644 index 000000000..ab88cbeee --- /dev/null +++ b/api/test/resources/workflows/illumina_genotyping_array/fromOutputs.edn @@ -0,0 +1,22 @@ +{:fingerprint_summary_metrics "fingerprint_summary_metrics", + :output_vcf_index "output_vcf_index", + :gtc "gtc", + :arrays_subset_variant_calling_detail_metrics "arrays_subset_variant_calling_detail_metrics", + :arrays_variant_calling_detail_metrics "arrays_variant_calling_detail_metrics", + :check_fingerprint_lod "check_fingerprint_lod", + :green_idat_md5_cloud_path "green_idat_md5_cloud_path", + :output_fingerprint_vcf_index "output_fingerprint_vcf_index", + :contamination_metrics "contamination_metrics", + :arrays_subset_variant_calling_summary_metrics "arrays_subset_variant_calling_summary_metrics", + :arrays_subset_variant_calling_control_metrics "arrays_subset_variant_calling_control_metrics", + :output_fingerprint_vcf "output_fingerprint_vcf", + :red_idat_md5_cloud_path "red_idat_md5_cloud_path", + :genotype_concordance_failed "genotype_concordance_failed", + :output_vcf "output_vcf", + :genotype_concordance_summary_metrics "genotype_concordance_summary_metrics", + :fingerprint_detail_metrics "fingerprint_detail_metrics", + :arrays_variant_calling_control_metrics "arrays_variant_calling_control_metrics", + :genotype_concordance_detail_metrics "genotype_concordance_detail_metrics", + :output_vcf_md5_cloud_path "output_vcf_md5_cloud_path", + :arrays_variant_calling_summary_metrics "arrays_variant_calling_summary_metrics", + :genotype_concordance_contingency_metrics "genotype_concordance_contingency_metrics"} diff --git a/api/test/resources/workflows/illumina_genotyping_array/inputs.json b/api/test/resources/workflows/illumina_genotyping_array/inputs.json new file mode 100644 index 000000000..1369b4c15 --- /dev/null +++ b/api/test/resources/workflows/illumina_genotyping_array/inputs.json @@ -0,0 +1,8 @@ +{ + "analysis_version_number": 1, + "chip_well_barcode": "7991775143_R01C01", + "green_idat_cloud_path": "gs://broad-gotc-dev-wfl-ptc-test-inputs/illumina-genotyping-array/inputs/7991775143_R01C01_Grn.idat", + "red_idat_cloud_path": "gs://broad-gotc-dev-wfl-ptc-test-inputs/illumina-genotyping-array/inputs/7991775143_R01C01_Red.idat", + "sample_alias": "NA12878", + "reported_gender": "Female" +} diff --git a/api/test/wfl/integration/datarepo_test.clj b/api/test/wfl/integration/datarepo_test.clj index d880aa471..f025c6205 100644 --- a/api/test/wfl/integration/datarepo_test.clj +++ b/api/test/wfl/integration/datarepo_test.clj @@ -2,11 +2,11 @@ (:require [clojure.data.json :as json] [clojure.test :refer [deftest is testing]] [wfl.environment :as env] - [wfl.module.covid :as covid] [wfl.service.datarepo :as datarepo] [wfl.service.firecloud :as firecloud] [wfl.service.google.storage :as gcs] [wfl.service.google.bigquery :as bigquery] + [wfl.sink :as sink] [wfl.tools.datasets :as datasets] [wfl.tools.fixtures :as fixtures] [wfl.tools.snapshots :as snapshots] @@ -15,6 +15,12 @@ [wfl.util :as util :refer [>>>]]) (:import [java.util UUID])) +(def ^:private testing-dataset {:id "4a5d30fe-1f99-42cd-998b-a979885dea00" + :name "workflow_launcher_testing_dataset"}) +(def ^:private testing-snapshot + {:id "0ef4bc30-b8a0-4782-b178-e6145b777404" + :name "workflow_launcher_testing_dataset7561609c9bb54ca6b34a12156dc947c1"}) + (deftest test-create-dataset ;; To test that your dataset json file is valid, add its path to the list! (let [tdr-profile (env/getenv "WFL_TDR_DEFAULT_PROFILE")] @@ -24,17 +30,18 @@ (testing (str "creating dataset " (util/basename definition)) (fixtures/with-temporary-dataset (datasets/unique-dataset-request tdr-profile definition) - #(let [dataset (datarepo/dataset %)] - (is (= % (:id dataset))))))))) + ;; wait for 3 seconds to avoid random 404 transient issues from TDR + #(do (util/sleep-seconds 3) + (let [dataset (datarepo/dataset %)] + (is (= % (:id dataset)))))))))) (defn ^:private replace-urls-with-file-ids - [file->fileid type value] - (-> (fn [type value] - (case type - ("Boolean" "Float" "Int" "Number" "String") value - "File" (file->fileid value) - (throw (ex-info "Unknown type" {:type type :value value})))) - (workflows/traverse type value))) + [file->fileid object] + (letfn [(f [[type value]] + (case type + "File" (file->fileid value) + value))] + (workflows/traverse f object))) (def ^:private pi (* 4 (Math/atan 1))) @@ -66,10 +73,10 @@ (datasets/unique-dataset-request tdr-profile dataset-json))] (fn [[temp dataset]] (let [table-url (str temp workflow-id "/table.json")] - (-> (->> (workflows/get-files outputs-type outputs) + (-> (->> (workflows/get-files [outputs-type outputs]) (datasets/ingest-files tdr-profile dataset workflow-id)) - (replace-urls-with-file-ids outputs-type outputs) - (covid/rename-gather from-outputs) + (replace-urls-with-file-ids [outputs-type outputs]) + (sink/rename-gather from-outputs) (json/write-str :escape-slash false) (gcs/upload-content table-url)) (let [{:keys [bad_row_count row_count]} @@ -78,19 +85,15 @@ (is (= 1 row_count)) (is (= 0 bad_row_count)))))))) -(def ^:private testing-dataset "85efdfea-52fb-4698-bee6-eef76104a7f4") - -;; Get row-ids from BigQuery and use them to create a snapshot. -;; excluded, the testing-dataset has been removed from dev-TDR -(deftest ^:excluded test-create-snapshot +(deftest test-create-snapshot (let [tdr-profile (env/getenv "WFL_TDR_DEFAULT_PROFILE") - dataset (datarepo/dataset testing-dataset) - table "sample" + dataset (datarepo/dataset (:id testing-dataset)) + table "flowcells" row-ids (-> (datarepo/query-table-between dataset table - "datarepo_ingest_date" - ["2021-01-05" "2021-01-07"] + "run_date" + ["2021-04-30T04:00:00" "2021-05-01T04:00:00"] [:datarepo_row_id]) :rows flatten)] @@ -99,11 +102,9 @@ #(let [snapshot (datarepo/snapshot %)] (is (= % (:id snapshot))))))) -(def ^:private testing-snapshot-id "7cb392d8-949b-419d-b40b-d039617d2fc7") - (deftest test-flattened-query-result - (let [samplesheets (-> (datarepo/snapshot testing-snapshot-id) - (datarepo/query-table "flowcell" [:samplesheets]) + (let [samplesheets (-> (datarepo/snapshot (:id testing-snapshot)) + (datarepo/query-table "flowcells" [:samplesheet_location]) :rows (->> (mapcat first)))] (is (every? string? samplesheets) "Nested arrays were not normalized."))) @@ -118,13 +119,13 @@ (defn ^:private maps->table "Transform a list of maps into a table with `columns`." [maps columns] - (let [table {:schema {:fields (mapv #(-> {:name (name %)}) columns)}} + (let [table {:schema {:fields (mapv #(hash-map :name (name %)) columns)}} f #(reduce (fn [row attr] (conj row (% attr))) [] columns)] (assoc table :rows (map f maps)))) (defn ^:private make-entity-import-request-tsv [from-dataset columns maps] - (-> (map #(covid/rename-gather % from-dataset) maps) + (-> (map #(sink/rename-gather % from-dataset) maps) (maps->table columns) bigquery/dump-table->tsv)) @@ -146,15 +147,14 @@ #(mapv keyword %))) (deftest test-import-snapshot - (let [dataset-table "flowcell" + (let [dataset-table "flowcells" entity "flowcell" from-dataset (resources/read-resource "entity-from-dataset.edn") - columns (-> (firecloud/list-entity-types "pathogen-genomic-surveillance/CDC_Viral_Sequencing_dev") - :flowcell - entity-columns)] + columns (-> "pathogen-genomic-surveillance/CDC_Viral_Sequencing_dev" + firecloud/list-entity-types :flowcell entity-columns)] (fixtures/with-temporary-workspace (fn [workspace] - (let [entities (-> (datarepo/snapshot testing-snapshot-id) + (let [entities (-> (datarepo/snapshot (:id testing-snapshot)) (datarepo/query-table dataset-table) (import-table workspace columns from-dataset)) names (->> #(firecloud/list-entities workspace entity) diff --git a/api/test/wfl/integration/executor_test.clj b/api/test/wfl/integration/executor_test.clj new file mode 100644 index 000000000..225f47bde --- /dev/null +++ b/api/test/wfl/integration/executor_test.clj @@ -0,0 +1,423 @@ +(ns wfl.integration.executor-test + (:require [clojure.test :refer [deftest is use-fixtures]] + [wfl.executor :as executor] + [wfl.jdbc :as jdbc] + [wfl.service.firecloud :as firecloud] + [wfl.service.postgres :as postgres] + [wfl.service.rawls :as rawls] + [wfl.stage :as stage] + [wfl.tools.fixtures :as fixtures] + [wfl.tools.queues :refer [make-queue-from-list]] + [wfl.util :as util]) + (:import [java.util UUID] + [wfl.util UserException])) + +(def ^:private testing-namespace "wfl-dev") +(def ^:private testing-workspace (str testing-namespace "/" "CDC_Viral_Sequencing")) +(def ^:private testing-method-name "sarscov2_illumina_full") +(def ^:private testing-method-configuration (str testing-namespace "/" testing-method-name)) +(def ^:private testing-method-configuration-version 2) + +(let [new-env {"WFL_FIRECLOUD_URL" "https://api.firecloud.org" + "WFL_RAWLS_URL" "https://rawls.dsde-prod.broadinstitute.org"}] + (use-fixtures :once + (fixtures/temporary-environment new-env) + fixtures/temporary-postgresql-database)) + +(deftest test-validate-terra-executor-with-valid-executor-request + (is (executor/terra-executor-validate-request-or-throw + {:name "Terra" + :workspace testing-workspace + :methodConfiguration testing-method-configuration + :methodConfigurationVersion testing-method-configuration-version + :fromSource "importSnapshot"}))) + +(deftest test-validate-terra-executor-with-invalid-executor-request + (is (thrown-with-msg? + UserException #"Unsupported coercion" + (executor/terra-executor-validate-request-or-throw + {:name "Terra" + :workspace testing-workspace + :methodConfiguration testing-method-configuration + :methodConfigurationVersion testing-method-configuration-version + :fromSource "frobnicate"})))) + +(deftest test-validate-terra-executor-with-wrong-method-configuration-version + (is (thrown-with-msg? + UserException #"Unexpected method configuration version" + (executor/terra-executor-validate-request-or-throw + {:name "Terra" + :workspace testing-workspace + :methodConfiguration testing-method-configuration + :methodConfigurationVersion -1 + :fromSource "importSnapshot"})))) + +(deftest test-validate-terra-executor-with-wrong-method-configuration + (is (thrown-with-msg? + UserException #"Cannot access method configuration" + (executor/terra-executor-validate-request-or-throw + {:name "Terra" + :workspace testing-workspace + :methodConfiguration "no_such/method_configuration" + :fromSource "importSnapshot"})))) + +;; Mocks + +;; Snapshot and snapshot reference mocks +(def ^:private snapshot + {:name "test-snapshot-name" :id (str (UUID/randomUUID))}) + +(def ^:private snapshot-reference-id (str (UUID/randomUUID))) +(def ^:private snapshot-reference-name (str (:name snapshot) "-ref")) +(defn ^:private mock-rawls-snapshot-reference [& _] + {:metadata {:name snapshot-reference-name + :resourceId snapshot-reference-id + :resourceType "DATA_REPO_SNAPSHOT" + :stewardshipType "REFERENCED"}}) + +;; Method configuration +(def ^:private fake-method-name "method-name") +(def ^:private fake-method-config (str "method-namespace/" fake-method-name)) + +(def ^:private method-config-version-init 1) +(def ^:private method-config-version-post-update 2) + +(defn ^:private mock-firecloud-get-method-configuration [method-config-version] + {:methodConfigVersion method-config-version}) + +(defn ^:private mock-firecloud-get-method-configuration-init [& _] + (mock-firecloud-get-method-configuration method-config-version-init)) +(defn ^:private mock-firecloud-get-method-configuration-post-update [& _] + (mock-firecloud-get-method-configuration method-config-version-post-update)) + +(defn ^:private mock-firecloud-update-method-configuration [method-config-version] + (fn [_ _ {:keys [dataReferenceName methodConfigVersion]}] + (is (= dataReferenceName snapshot-reference-name) + "Snapshot reference name should be passed to method config update") + (is (= methodConfigVersion (inc method-config-version)) + "Incremented version should be passed to method config update") + nil)) + +(defn ^:private mock-firecloud-update-method-configuration-init [& _] + (mock-firecloud-update-method-configuration method-config-version-init)) +(defn ^:private mock-firecloud-update-method-configuration-post-update [& _] + (mock-firecloud-update-method-configuration method-config-version-post-update)) + +;; Submissions and workflows + +(defn ^:private workflow-base [entity status] + {:entity entity + :workflow-id (str (UUID/randomUUID)) + :status status}) + +(def ^:private init-submission-id "init-submission-id") +(def ^:private retry-submission-id "retry-submission-id") + +(def ^:private submission-base + (let [running-entity "running-entity" + succeeded-entity "succeeded-entity"] + {init-submission-id {:running (workflow-base running-entity "Running") + :succeeded (workflow-base succeeded-entity "Succeeded")} + retry-submission-id {:running (workflow-base running-entity "Running") + :succeeded (workflow-base succeeded-entity "Succeeded")}})) + +;; Firecloud workflow format differs based on whether it is fetched +;; at the submission level or the workflow level. +(defn ^:private mock-firecloud-get-submission-workflow + [{:keys [entity workflow-id status] :as _workflow-base}] + {:entityName entity + :inputResolutions {:inputName (str fake-method-name ".input") + :value "value"} + :status status + :workflowId workflow-id}) + +(defn ^:private mock-firecloud-get-workflow + [{:keys [workflow-id status] :as _workflow-base}] + {:id workflow-id + :inputs {:input "value"} + :status status + :workflowName fake-method-name}) + +(defn ^:private running-workflow-from-submission [submission-id] + (mock-firecloud-get-submission-workflow (get-in submission-base [submission-id :running]))) + +(defn ^:private succeeded-workflow-from-submission [submission-id] + (mock-firecloud-get-submission-workflow (get-in submission-base [submission-id :succeeded]))) + +;; When we create submissions, workflows have no uuid or status. +(defn ^:private mock-firecloud-create-submission [submission-id] + (fn [& _] + (let [enqueue #(dissoc % :workflowId :status)] + {:submissionId submission-id + :workflows (map enqueue [(running-workflow-from-submission submission-id) + (succeeded-workflow-from-submission submission-id)])}))) + +;; When we get the submission later, the workflows may have a uuid and status assigned. +(defn ^:private mock-firecloud-get-submission [_ submission-id] + (letfn [(add-workflow-entity [{:keys [entityName] :as workflow}] + (-> workflow + (assoc :workflowEntity {:entityType "test" :entityName entityName}) + (dissoc :entityName)))] + {:submissionId submission-id + :workflows (map add-workflow-entity [(running-workflow-from-submission submission-id) + (succeeded-workflow-from-submission submission-id)])})) + +;; Workflow fetch mocks within update-workflow-statuses! +(defn ^:private mock-firecloud-get-running-workflow-update-status [_ submission-id workflow-id] + (let [workflow-base (get-in submission-base [submission-id :running])] + (is (= (:workflow-id workflow-base) workflow-id) + "Expecting to fetch and update status for running workflow") + (assoc (mock-firecloud-get-workflow workflow-base) :status "Succeeded"))) + +(defn ^:private mock-firecloud-get-known-workflow [_ submission-id workflow-id] + (if-let [workflow-base (->> (get submission-base submission-id) + vals + (filter #(= workflow-id (:workflow-id %))) + first)] + (mock-firecloud-get-workflow workflow-base) + (throw + (ex-info "Workflow ID does not match known workflow" + {:known-submissions submission-base + :submission-id submission-id + :workflow-id workflow-id})))) + +(defn ^:private mock-firecloud-get-workflow-outputs [_ submission-id workflow-id] + (is (= (get-in submission-base [submission-id :succeeded :workflow-id]) workflow-id) + "Expecting to fetch outputs for successful workflow") + {:tasks + {:noise + {} + (keyword fake-method-name) + {:outputs + (util/prefix-keys {:output "value"} (str fake-method-name "."))}}}) + +(defn ^:private create-terra-executor [id] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> {:name "Terra" + :workspace "workspace-ns/workspace-name" + :methodConfiguration fake-method-config + :methodConfigurationVersion method-config-version-init + :fromSource "importSnapshot" + :skipValidation true} + (executor/create-executor! tx id) + (zipmap [:executor_type :executor_items]) + (executor/load-executor! tx)))) + +(defn ^:private reload-terra-executor + "Reload an established `executor` object." + [{:keys [type id] :as _executor}] + (let [workload (zipmap [:executor_type :executor_items] [type (str id)])] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (executor/load-executor! tx workload)))) + +(deftest test-update-terra-executor + (let [source (make-queue-from-list [[:datarepo/snapshot snapshot]]) + executor (create-terra-executor (rand-int 1000000))] + (letfn [(verify-record-against-workflow [record workflow idx] + (is (= idx (:id record)) + "The record ID was incorrect given the workflow order in mocked submission") + (is (= (:workflowId workflow) (:workflow record)) + "The workflow ID was incorrect and should match corresponding record"))] + (with-redefs-fn + {#'rawls/create-or-get-snapshot-reference mock-rawls-snapshot-reference + #'firecloud/method-configuration mock-firecloud-get-method-configuration-init + #'firecloud/update-method-configuration mock-firecloud-update-method-configuration-init + #'firecloud/submit-method (mock-firecloud-create-submission init-submission-id) + #'firecloud/get-submission mock-firecloud-get-submission + #'firecloud/get-workflow mock-firecloud-get-running-workflow-update-status} + #(executor/update-executor! source executor)) + (is (zero? (stage/queue-length source)) "The snapshot was not consumed.") + (is (== 2 (stage/queue-length executor)) "Two workflows should be enqueued") + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (let [[running-record succeeded-record & _ :as records] + (->> executor :details (postgres/get-table tx) (sort-by :id)) + executor-record + (#'postgres/load-record-by-id! tx "TerraExecutor" (:id executor)) + running-workflow (running-workflow-from-submission init-submission-id) + succeeded-workflow (succeeded-workflow-from-submission init-submission-id)] + (is (== 2 (count records)) + "Exactly 2 workflows should have been written to the database") + (is (every? #(= snapshot-reference-id (:reference %)) records) + "The snapshot reference ID was incorrect and should match all records") + (is (every? #(= init-submission-id (:submission %)) records) + "The submission ID was incorrect and should match all records") + (is (every? #(= "Succeeded" (:status %)) records) + "Status update mock should have marked running workflow as succeeded") + (is (every? #(nil? (:consumed %)) records) + "All records should be unconsumed") + (is (not (stage/done? executor)) "executor should not have finished processing") + (verify-record-against-workflow running-record running-workflow 1) + (verify-record-against-workflow succeeded-record succeeded-workflow 2) + (is (== method-config-version-post-update (:method_configuration_version executor-record)) + "Method configuration version was not incremented.")))))) + +(deftest test-peek-terra-executor-queue + (let [succeeded? #{"Succeeded"} + source (make-queue-from-list [[:datarepo/snapshot snapshot]]) + executor (create-terra-executor (rand-int 1000000))] + (with-redefs-fn + {#'rawls/create-or-get-snapshot-reference mock-rawls-snapshot-reference + #'firecloud/method-configuration mock-firecloud-get-method-configuration-init + #'firecloud/update-method-configuration mock-firecloud-update-method-configuration-init + #'firecloud/submit-method (mock-firecloud-create-submission init-submission-id) + #'firecloud/get-submission mock-firecloud-get-submission + #'firecloud/get-workflow mock-firecloud-get-known-workflow} + #(executor/update-executor! source executor)) + (with-redefs-fn + {#'executor/describe-method (constantly nil) + #'firecloud/get-workflow mock-firecloud-get-known-workflow + #'firecloud/get-workflow-outputs mock-firecloud-get-workflow-outputs} + #(let [[_ workflow] (stage/peek-queue executor) + succeeded-workflow-id + (get-in submission-base [init-submission-id :succeeded :workflow-id])] + (is (succeeded? (:status workflow))) + (is (= succeeded-workflow-id (:uuid workflow))) + (is (contains? workflow :updated)) + (is (= "value" (-> workflow :inputs :input))) + (is (= "value" (-> workflow :outputs :output))) + (is (not (-> workflow :outputs :noise))) + (stage/pop-queue! executor) + (is (nil? (stage/peek-queue executor))) + (is (== 1 (stage/queue-length executor))) + (is (not (stage/done? executor))))))) + +(deftest test-terra-executor-retry-workflows + (let [source (make-queue-from-list [[:datarepo/snapshot snapshot]]) + executor (create-terra-executor (rand-int 1000000))] + (with-redefs-fn + {#'rawls/create-or-get-snapshot-reference mock-rawls-snapshot-reference + #'firecloud/method-configuration mock-firecloud-get-method-configuration-init + #'firecloud/update-method-configuration mock-firecloud-update-method-configuration-init + #'firecloud/submit-method (mock-firecloud-create-submission init-submission-id) + #'firecloud/get-submission mock-firecloud-get-submission + #'firecloud/get-workflow mock-firecloud-get-known-workflow} + #(executor/update-executor! source executor)) + (is (zero? (stage/queue-length source)) "The snapshot was not consumed.") + (is (== 2 (stage/queue-length executor)) + "Two workflows should be enqueued prior to retry.") + (let [executor (reload-terra-executor executor)] + (is (== 2 (:methodConfigurationVersion executor)) + "Reloaded executor's method config should have version 2 post-update.") + (with-redefs-fn + {#'rawls/get-snapshot-reference mock-rawls-snapshot-reference + #'firecloud/method-configuration mock-firecloud-get-method-configuration-post-update + #'firecloud/update-method-configuration mock-firecloud-update-method-configuration-post-update + #'firecloud/submit-method (mock-firecloud-create-submission retry-submission-id) + #'firecloud/get-submission mock-firecloud-get-submission + #'firecloud/get-workflow mock-firecloud-get-known-workflow} + #(let [workflows-to-retry + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (executor/executor-workflows-by-status tx executor "Running"))] + (is (== 1 (count workflows-to-retry)) + "Should have one running workflow to retry.") + (executor/executor-retry-workflows! executor workflows-to-retry))) + ;; We only specify 1 workflow to retry, + ;; but must retry both workflows from its submission. + (is (== 4 (stage/queue-length executor)) + "Four workflows should be enqueued following retry.") + (let [[running succeeded retry-running retry-succeeded & _ :as records] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> executor :details (postgres/get-table tx) (sort-by :id))) + executor-record + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (#'postgres/load-record-by-id! tx "TerraExecutor" (:id executor))) + compare-original-with-retry + (fn [original retry status-kw] + (is (= (:retry original) (:id retry)) + (str status-kw " - original record should be linked to its retry.")) + (is (= init-submission-id (:submission original)) + (str status-kw " - original record has incorrect submission id.")) + (is (= retry-submission-id (:submission retry)) + (str status-kw " - retry record has incorrect submission id.")) + (is (= (get-in submission-base [init-submission-id + status-kw + :workflow-id]) + (:workflow original)) + (str status-kw " - original record has incorrect workflow id.")) + (is (nil? (:workflow retry)) + (str status-kw " - retry record should not have workflow id " + "populated prior to update loop.")) + (is (every? #(= (get-in submission-base [init-submission-id + status-kw + :entity]) + (:entity %)) [original retry]) + (str status-kw " - original record should have " + "same entity as its retry.")))] + (is (== 4 (count records)) + "Exactly 4 workflows should be visible in the database") + (is (every? #(= snapshot-reference-id (:reference %)) records) + "The snapshot reference ID was incorrect and should match all records") + (compare-original-with-retry running retry-running :running) + (compare-original-with-retry succeeded retry-succeeded :succeeded) + (is (== (inc method-config-version-post-update) (:method_configuration_version executor-record)) + "Method configuration version was not incremented."))))) + +(deftest test-terra-executor-get-retried-workflows + (with-redefs-fn + {#'rawls/create-or-get-snapshot-reference mock-rawls-snapshot-reference + #'firecloud/method-configuration mock-firecloud-get-method-configuration-init + #'firecloud/update-method-configuration mock-firecloud-update-method-configuration-init + #'firecloud/submit-method (mock-firecloud-create-submission init-submission-id) + #'firecloud/get-submission mock-firecloud-get-submission + #'firecloud/get-workflow mock-firecloud-get-known-workflow + #'firecloud/get-workflow-outputs mock-firecloud-get-workflow-outputs} + #(let [source (make-queue-from-list [[:datarepo/snapshot snapshot]]) + executor (create-terra-executor (rand-int 1000000))] + (executor/update-executor! source executor) + (is (== 2 (stage/queue-length executor))) + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (jdbc/update! tx (:details executor) {:retry 2} ["id = ?" 1])) + (is (== 2 (stage/queue-length executor)) + "The retried workflow should remain visible downstream") + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (is (== 1 (count (executor/executor-workflows tx executor))) + "The retried workflow should not be returned"))))) + +(deftest test-terra-executor-queue-length + (with-redefs-fn + {#'rawls/create-or-get-snapshot-reference mock-rawls-snapshot-reference + #'firecloud/method-configuration mock-firecloud-get-method-configuration-init + #'firecloud/update-method-configuration mock-firecloud-update-method-configuration-init + #'firecloud/submit-method (mock-firecloud-create-submission init-submission-id) + #'firecloud/get-submission mock-firecloud-get-submission + #'firecloud/get-workflow mock-firecloud-get-known-workflow + #'firecloud/get-workflow-outputs mock-firecloud-get-workflow-outputs} + #(let [source (make-queue-from-list [[:datarepo/snapshot snapshot]]) + executor (create-terra-executor (rand-int 1000000)) + _ (executor/update-executor! source executor) + record (#'executor/peek-terra-executor-details executor) + succeeded-workflow-id (get-in submission-base [init-submission-id :succeeded :workflow-id])] + (is (= succeeded-workflow-id (:workflow record)) + "Peeked record's workflow uuid should match succeeded workflow's") + (is (= "Succeeded" (:status record)) + "Peeked record's status should match succeeded workflow's") + (is (== 2 (stage/queue-length executor)) + "Both running and succeeded workflows in submission should be counted in queue length") + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (jdbc/update! tx (:details executor) {:status nil} ["id = ?" (:id record)])) + (is (== 2 (stage/queue-length executor)) + "Workflows without status should be counted in queue length") + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (jdbc/update! tx (:details executor) {:workflow nil} ["id = ?" (:id record)])) + (is (== 2 (stage/queue-length executor)) + "Workflows without status or uuid should be counted in queue length")))) + +(deftest test-terra-executor-describe-method + (let [description (executor/describe-method + testing-workspace + testing-method-configuration)] + (is (every? description [:validWorkflow :inputs :outputs])) + (is (= "sarscov2_illumina_full" (:name description))))) + +(deftest test-terra-executor-entity-from-snapshot + (letfn [(throw-if-called [& args] + (throw (ex-info (str "rawls/create-snapshot-reference " + "should not have been called directly") + {:called-with args})))] + (with-redefs-fn + {#'rawls/create-snapshot-reference throw-if-called + #'rawls/create-or-get-snapshot-reference mock-rawls-snapshot-reference} + #(let [executor (create-terra-executor (rand-int 1000000)) + reference (#'executor/entity-from-snapshot executor snapshot)] + (is (and (= snapshot-reference-id (get-in reference [:metadata :resourceId])) + (= snapshot-reference-name (get-in reference [:metadata :name])))))))) diff --git a/api/test/wfl/integration/google/bigquery_test.clj b/api/test/wfl/integration/google/bigquery_test.clj index 27a18e227..69c33ec64 100644 --- a/api/test/wfl/integration/google/bigquery_test.clj +++ b/api/test/wfl/integration/google/bigquery_test.clj @@ -19,4 +19,4 @@ (deftest test-query-table-sync (let [query (format "SELECT * FROM `%s.%s.%s`" google-project dr-dataset dr-view) query-result (bigquery/query-sync google-project query)] - (is (not (empty? (:rows query-result))) "No results found!"))) + (is (seq (:rows query-result)) "No results found!"))) diff --git a/api/test/wfl/integration/jdbc_test.clj b/api/test/wfl/integration/jdbc_test.clj index c8bcb1087..93b8fb5f7 100644 --- a/api/test/wfl/integration/jdbc_test.clj +++ b/api/test/wfl/integration/jdbc_test.clj @@ -1,11 +1,10 @@ (ns wfl.integration.jdbc-test - (:require [clojure.test :refer :all :as clj-test] - [clojure.test] - [wfl.jdbc :as jdbc] + (:require [clojure.test :refer [deftest is testing use-fixtures]] + [wfl.jdbc :as jdbc] [wfl.service.postgres :as postgres] - [wfl.tools.fixtures :as fixtures])) + [wfl.tools.fixtures :as fixtures])) -(clj-test/use-fixtures :once fixtures/temporary-postgresql-database) +(use-fixtures :once fixtures/temporary-postgresql-database) (deftest test-jdbc-protocol-extensions (let [create "CREATE TABLE %s (id SERIAL, arr text[])" diff --git a/api/test/wfl/integration/modules/aou_test.clj b/api/test/wfl/integration/modules/aou_test.clj index 0ce91ec0a..d66e047d5 100644 --- a/api/test/wfl/integration/modules/aou_test.clj +++ b/api/test/wfl/integration/modules/aou_test.clj @@ -1,7 +1,6 @@ (ns wfl.integration.modules.aou-test (:require [clojure.spec.alpha :as s] [clojure.test :refer [testing is deftest use-fixtures]] - [wfl.api.spec] [wfl.integration.modules.shared :as shared] [wfl.jdbc :as jdbc] [wfl.module.aou :as aou] @@ -34,7 +33,7 @@ append-to-workload! (fn [xs] (workloads/append-to-workload! xs workload))] (testing "appending a sample to the workload" (let [response (append-to-workload! [workloads/aou-sample])] - (is (s/valid? :wfl.api.spec/append-to-aou-response response)) + (is (s/valid? ::aou/append-to-aou-response response)) (is (count=1? response)))) (testing "appending the same sample to the workload does nothing" (is (= () (append-to-workload! [workloads/aou-sample])))) @@ -46,7 +45,7 @@ (repeat 5 (inc-version (inc-version workloads/aou-sample))))))) (testing "appending empty workload" (let [response (append-to-workload! [])] - (is (s/valid? :wfl.api.spec/append-to-aou-response response)) + (is (s/valid? ::aou/append-to-aou-response response)) (is (empty? response))))))) (deftest test-append-to-aou-not-started @@ -71,6 +70,9 @@ (deftest test-stop-workload-state-transition (shared/run-stop-workload-state-transition-test! (make-aou-workload-request))) +(deftest test-retry-workflows-unsupported + (shared/run-retry-is-not-supported-test! (make-aou-workload-request))) + (deftest test-aou-workload-not-finished-until-stopped (with-redefs-fn {#'aou/submit-aou-workflow mock-submit-workload #'batch/update-workflow-statuses! mock-update-statuses!} @@ -87,16 +89,16 @@ ;; rr: GH-1071 (deftest test-exec-on-same-workload-request - "executing a workload-request twice should not create a new workload" - (let [request (make-aou-workload-request)] - (is (= (workloads/execute-workload! request) - (workloads/execute-workload! request))))) + (testing "executing a workload-request twice should not create a new workload" + (let [request (make-aou-workload-request)] + (is (= (workloads/execute-workload! request) + (workloads/execute-workload! request)))))) (deftest test-exec-on-similar-workload-request - "output bucket slashes should be standardized to not create new workloads unnecessarily" - (let [request (make-aou-workload-request) - slashified (update request :output util/slashify) - deslashified (update request :output util/de-slashify)] - (is (not (= slashified deslashified))) - (is (= (workloads/execute-workload! slashified) - (workloads/execute-workload! deslashified))))) + (testing "output bucket slashes should be standardized to not create new workloads unnecessarily" + (let [request (make-aou-workload-request) + slashified (update request :output util/slashify) + deslashified (update request :output util/de-slashify)] + (is (not (= slashified deslashified))) + (is (= (workloads/execute-workload! slashified) + (workloads/execute-workload! deslashified)))))) diff --git a/api/test/wfl/integration/modules/arrays_test.clj b/api/test/wfl/integration/modules/arrays_test.clj deleted file mode 100644 index dc4a4d3a1..000000000 --- a/api/test/wfl/integration/modules/arrays_test.clj +++ /dev/null @@ -1,83 +0,0 @@ -(ns wfl.integration.modules.arrays-test - (:require [clojure.test :refer [testing is deftest use-fixtures]] - [wfl.integration.modules.shared :as shared] - [wfl.service.firecloud :as terra] - [wfl.tools.fixtures :as fixtures] - [wfl.tools.workloads :as workloads]) - (:import [java.util UUID])) - -(use-fixtures - :once - fixtures/temporary-postgresql-database - (fixtures/temporary-environment - {"WFL_FIRECLOUD_URL" "https://firecloud-orchestration.dsde-dev.broadinstitute.org"})) - -(defn ^:private mock-terra-create-submission [& _] - {:submissionId (UUID/randomUUID)}) - -(defn ^:private mock-get-workflow-status-by-entity [& _] "Succeeded") - -(defn ^:private make-arrays-workload-request [] - (-> (workloads/arrays-workload-request (UUID/randomUUID)) - (assoc :creator @workloads/email))) - -(defn ^:private check-inputs - [workflow] - (is (contains? (:inputs workflow) :entity-type)) - (is (contains? (:inputs workflow) :entity-name)) - (is (:inputs workflow) "Inputs are under :inputs") - (is - (not-any? (partial contains? workflow) (keys workloads/arrays-sample-terra)) - "Inputs are not at the top-level")) - -(defn ^:private check-workflow - [workflow] - (is (:uuid workflow)) - (is (:status workflow)) - (is (:updated workflow))) - -(deftest test-create-arrays-workload! - (let [workload (-> (make-arrays-workload-request) - workloads/create-workload!)] - (run! check-inputs (workloads/workflows workload)))) - -(deftest test-workload-state-transition - (with-redefs-fn - {#'terra/create-submission mock-terra-create-submission - #'terra/get-workflow-status-by-entity mock-get-workflow-status-by-entity} - #(shared/run-workload-state-transition-test! - (make-arrays-workload-request)))) - -(deftest test-stop-workload-state-transition - (shared/run-stop-workload-state-transition-test! - (make-arrays-workload-request))) - -(deftest test-start-arrays-workload! - (with-redefs-fn {#'terra/create-submission mock-terra-create-submission} - #(let [workload (-> (make-arrays-workload-request) - workloads/create-workload! - workloads/start-workload!)] - (is (:started workload)) - (let [workflows (workloads/workflows workload)] - (run! check-inputs workflows) - (run! check-workflow workflows))))) - -(deftest test-exec-arrays-workload! - (with-redefs-fn {#'terra/create-submission mock-terra-create-submission} - #(let [workload (-> (make-arrays-workload-request) - workloads/execute-workload!)] - (is (:started workload)) - (let [workflows (workloads/workflows workload)] - (run! check-inputs workflows) - (run! check-workflow workflows))))) - -(deftest ^:excluded test-update-arrays-workload! - (letfn [(check-status [status workflow] - (is (= status (:status workflow))))] - (with-redefs-fn {#'terra/get-workflow-status-by-entity mock-get-workflow-status-by-entity} - #(let [workload (-> (make-arrays-workload-request) - workloads/execute-workload!)] - (run! (partial check-status "Submitted") (workloads/workflows workload)) - (let [updated-workload (workloads/update-workload! workload)] - (run! (partial check-status "Succeeded") (workloads/workflows updated-workload)) - (is (:finished updated-workload))))))) diff --git a/api/test/wfl/integration/modules/copyfile_test.clj b/api/test/wfl/integration/modules/copyfile_test.clj index 7e8bf1c74..6bb5599db 100644 --- a/api/test/wfl/integration/modules/copyfile_test.clj +++ b/api/test/wfl/integration/modules/copyfile_test.clj @@ -1,5 +1,5 @@ (ns wfl.integration.modules.copyfile-test - (:require [clojure.test :refer [deftest testing is use-fixtures]] + (:require [clojure.test :refer [deftest is use-fixtures]] [clojure.string :as str] [wfl.integration.modules.shared :as shared] [wfl.jdbc :as jdbc] @@ -93,20 +93,27 @@ workloads/workflows)))) (defn mock-batch-update-workflow-statuses! - [tx {:keys [items] :as workload}] + [status tx {:keys [items] :as workload}] (letfn [(update! [{:keys [id]}] (jdbc/update! tx items - {:status "Succeeded" :updated (OffsetDateTime/now)} + {:status status :updated (OffsetDateTime/now)} ["id = ?" id]))] (run! update! (workloads/workflows workload)))) (deftest test-workload-state-transition (with-redefs-fn - {#'cromwell/submit-workflow (fn [& _] (UUID/randomUUID)) - #'batch/batch-update-workflow-statuses! mock-batch-update-workflow-statuses!} + {#'cromwell/submit-workflow (fn [& _] (UUID/randomUUID)) + #'batch/batch-update-workflow-statuses! (partial mock-batch-update-workflow-statuses! "Succeeded")} #(shared/run-workload-state-transition-test! (make-copyfile-workload-request "gs://b/in" "gs://b/out")))) (deftest test-stop-workload-state-transition (shared/run-stop-workload-state-transition-test! (make-copyfile-workload-request "gs://b/in" "gs://b/out"))) + +(deftest test-retry-failed-workflows + (with-redefs-fn + {#'cromwell/submit-workflow (fn [& _] (UUID/randomUUID)) + #'batch/batch-update-workflow-statuses! (partial mock-batch-update-workflow-statuses! "Failed")} + #(shared/run-retry-is-not-supported-test! + (make-copyfile-workload-request "gs://b/in" "gs://b/out")))) diff --git a/api/test/wfl/integration/modules/covid_test.clj b/api/test/wfl/integration/modules/covid_test.clj index 0b9089363..cdd87b0bf 100644 --- a/api/test/wfl/integration/modules/covid_test.clj +++ b/api/test/wfl/integration/modules/covid_test.clj @@ -1,33 +1,27 @@ (ns wfl.integration.modules.covid-test "Test the Sarscov2IlluminaFull COVID pipeline." - (:require [clojure.test :refer :all] + (:require [clojure.test :refer [deftest is testing + use-fixtures]] [clojure.set :as set] [clojure.spec.alpha :as s] [clojure.string :as str] - [reitit.coercion.spec] - [reitit.ring :as ring] - [reitit.ring.coercion :as coercion] - [wfl.api.spec :as spec] [wfl.api.spec :as spec] [wfl.integration.modules.shared :as shared] - [wfl.jdbc :as jdbc] - [wfl.module.covid :as covid] [wfl.service.firecloud :as firecloud] - [wfl.service.postgres :as postgres] [wfl.service.rawls :as rawls] + [wfl.source :as source] + [wfl.tools.endpoints :refer [coercion-tester]] [wfl.tools.fixtures :as fixtures] [wfl.tools.workloads :as workloads] - [wfl.tools.resources :as resources] [wfl.util :as util]) - (:import [java.lang Math] - [java.time LocalDateTime] - [java.util ArrayDeque UUID] + (:import [java.time LocalDateTime] + [java.util UUID] [wfl.util UserException])) ;; Snapshot creation mock (def ^:private mock-new-rows-size 2021) (defn ^:private mock-find-new-rows [_ interval] - (is (every? #(LocalDateTime/parse % @#'covid/bigquery-datetime-format) interval)) + (is (every? #(LocalDateTime/parse % @#'source/bigquery-datetime-format) interval)) (take mock-new-rows-size (range))) (defn ^:private mock-create-snapshots [_ _ row-ids] (letfn [(f [idx shard] [(vec shard) (format "mock_job_id_%s" idx)])] @@ -42,45 +36,21 @@ (def ^:private testing-dataset "cd25d59e-1451-44d0-8a24-7669edb9a8f8") (def ^:private testing-snapshot "e8f1675e-1e7c-48b4-92ab-3598425c149d") -(def ^:private testing-workspace "wfl-dev/CDC_Viral_Sequencing") +(def ^:private testing-namespace "wfl-dev") +(def ^:private testing-workspace (str testing-namespace "/" "CDC_Viral_Sequencing")) (def ^:private testing-method-name "sarscov2_illumina_full") -(def ^:private testing-method-configuration (str "cdc-covid-surveillance/" testing-method-name)) +(def ^:private testing-method-configuration (str testing-namespace "/" testing-method-name)) (def ^:private testing-method-configuration-version 2) (def ^:private testing-table-name "flowcells") (def ^:private testing-column-name "run_date") -;; Queue mocks -(def ^:private testing-queue-type "TestQueue") -(defn ^:private make-queue-from-list [items] - {:type testing-queue-type :queue (ArrayDeque. items)}) - -(defn ^:private testing-queue-peek [this] - (-> this :queue .getFirst)) - -(defn ^:private testing-queue-pop [this] - (-> this :queue .removeFirst)) - -(defn ^:private testing-queue-length [this] - (-> this :queue .size)) - -(defn ^:private testing-queue-done? [this] - (-> this :queue .empty)) - (let [new-env {"WFL_FIRECLOUD_URL" "https://api.firecloud.org" "WFL_TDR_URL" "https://data.terra.bio" "WFL_RAWLS_URL" "https://rawls.dsde-prod.broadinstitute.org"}] (use-fixtures :once (fixtures/temporary-environment new-env) - fixtures/temporary-postgresql-database - (fixtures/method-overload-fixture - covid/peek-queue! testing-queue-type testing-queue-peek) - (fixtures/method-overload-fixture - covid/pop-queue! testing-queue-type testing-queue-pop) - (fixtures/method-overload-fixture - covid/queue-length! testing-queue-type testing-queue-length) - (fixtures/method-overload-fixture - covid/done? testing-queue-type testing-queue-done?))) + fixtures/temporary-postgresql-database)) (deftest test-create-workload (letfn [(verify-source [{:keys [type last_checked details]}] @@ -113,88 +83,49 @@ (let [request (workloads/covid-workload-request {:skipValidation true} {:skipValidation true} - {:skipValidation true}) - _ (is (s/valid? ::spec/workload-request request) - (s/explain-str ::spec/workload-request request)) - workload (util/to-edn (workloads/create-workload! request))] - (is (not-any? workload [:id - :items - :source_type - :source_items - :executor_type - :executor_items - :sink_type - :sink_items - :type])) - (is (not-any? (:source workload) [:id :details :type :last_checked])) - (is (not-any? (:executor workload) [:id :details :type])) - (is (not-any? (:sink workload) [:id :details :type])))) + {:skipValidation true})] + (is (s/valid? :wfl.api.spec/workload-request request) + (s/explain-str :wfl.api.spec/workload-request request)) + (let [workload (util/to-edn (workloads/create-workload! request))] + (is (not-any? workload [:id + :items + :source_type + :source_items + :executor_type + :executor_items + :sink_type + :sink_items + :type])) + (is (not-any? (:source workload) [:id :details :type :last_checked])) + (is (not-any? (:executor workload) [:id :details :type])) + (is (not-any? (:sink workload) [:id :details :type]))))) (deftest test-create-covid-workload-with-misnamed-source (is (thrown-with-msg? - UserException #"Invalid request" + UserException #"Invalid source" (workloads/create-workload! (workloads/covid-workload-request {:name "bad name"} {:skipValidation true} {:skipValidation true}))))) -(deftest test-create-covid-workload-with-valid-source-request - (is (workloads/create-workload! - (workloads/covid-workload-request - {:dataset testing-dataset - :table testing-table-name - :column testing-column-name} - {:skipValidation true} - {:skipValidation true})))) - -(deftest test-create-covid-workload-with-non-existent-dataset +(deftest test-create-covid-workload-with-misnamed-executor (is (thrown-with-msg? - UserException #"Cannot access dataset" + UserException #"Invalid executor" (workloads/create-workload! (workloads/covid-workload-request - {:dataset util/uuid-nil} {:skipValidation true} + {:name "bad name"} {:skipValidation true}))))) -(deftest test-create-covid-workload-with-invalid-dataset-table +(deftest test-create-covid-workload-with-misnamed-sink (is (thrown-with-msg? - UserException #"Table not found" + UserException #"Invalid sink" (workloads/create-workload! (workloads/covid-workload-request - {:dataset testing-dataset - :table "no_such_table"} {:skipValidation true} - {:skipValidation true}))))) - -(deftest test-create-covid-workload-with-invalid-dataset-column - (is (thrown-with-msg? - UserException #"Column not found" - (workloads/create-workload! - (workloads/covid-workload-request - {:dataset testing-dataset - :table testing-table-name - :column "no_such_column"} {:skipValidation true} - {:skipValidation true}))))) - -(deftest test-create-covid-workload-with-empty-snapshot-list - (is (workloads/create-workload! - (workloads/covid-workload-request - {:name "TDR Snapshots" - :snapshots [testing-snapshot]} - {:skipValidation true} - {:skipValidation true})))) - -(deftest test-create-covid-workload-with-invalid-snapshot - (is (thrown-with-msg? - UserException #"Cannot access snapshot" - (workloads/create-workload! - (workloads/covid-workload-request - {:name "TDR Snapshots" - :snapshots [util/uuid-nil]} - {:skipValidation true} - {:skipValidation true}))))) + {:name "bad name"}))))) (deftest test-create-covid-workload-with-valid-executor-request (is (workloads/create-workload! @@ -206,108 +137,6 @@ :fromSource "importSnapshot"} {:skipValidation true})))) -(deftest test-create-covid-workload-with-misnamed-executor - (is (thrown-with-msg? - UserException #"Invalid request" - (workloads/create-workload! - (workloads/covid-workload-request - {:skipValidation true} - {:name "bad name"} - {:skipValidation true}))))) - -(deftest test-create-covid-workload-with-valid-executor-request - (is (thrown-with-msg? - UserException #"Unsupported coercion" - (workloads/create-workload! - (workloads/covid-workload-request - {:skipValidation true} - {:workspace testing-workspace - :methodConfiguration testing-method-configuration - :methodConfigurationVersion testing-method-configuration-version - :fromSource "frobnicate"} - {:skipValidation true}))))) - -(deftest test-create-covid-workload-with-wrong-method-configuration - (is (thrown-with-msg? - UserException #"Method configuration version mismatch" - (workloads/create-workload! - (workloads/covid-workload-request - {:skipValidation true} - {:workspace testing-workspace - :methodConfiguration testing-method-configuration - :methodConfigurationVersion -1 - :fromSource "importSnapshot"} - {:skipValidation true}))))) - -(deftest test-create-covid-workload-with-wrong-method-configuration - (is (thrown-with-msg? - UserException #"Cannot access method configuration" - (workloads/create-workload! - (workloads/covid-workload-request - {:skipValidation true} - {:workspace testing-workspace - :methodConfiguration "no_such/method_configuration" - :fromSource "importSnapshot"} - {:skipValidation true}))))) - -(deftest test-create-covid-workload-with-valid-sink-request - (is (workloads/create-workload! - (workloads/covid-workload-request - {:skipValidation true} - {:skipValidation true} - {:workspace testing-workspace - :entityType "assemblies" - :identity "Who cares?" - :fromOutputs {:assemblies_id "foo"}})))) - -(deftest test-create-covid-workload-with-invalid-sink-entity-type - (let [request (workloads/covid-workload-request - {:skipValidation true} - {:skipValidation true} - {:workspace testing-workspace - :entityType "does_not_exist" - :identity "Who cares?" - :fromOutputs {}})] - (is (thrown-with-msg? - UserException (re-pattern covid/unknown-entity-type-error-message) - (workloads/create-workload! request))))) - -(deftest test-create-covid-workload-with-malformed-fromOutputs - (let [request (workloads/covid-workload-request - {:skipValidation true} - {:skipValidation true} - {:workspace testing-workspace - :entityType "assemblies" - :identity "Who cares?" - :fromOutputs "geoff"})] - (is (thrown-with-msg? - UserException (re-pattern covid/malformed-from-outputs-error-message) - (workloads/create-workload! request))))) - -(deftest test-create-covid-workload-with-unknown-attributes-listed-in-fromOutputs - (let [request (workloads/covid-workload-request - {:skipValidation true} - {:skipValidation true} - {:workspace testing-workspace - :entityType "assemblies" - :identity "Who cares?" - :fromOutputs {:does_not_exist "genbank_source_table"}})] - (is (thrown-with-msg? - UserException (re-pattern covid/unknown-attributes-error-message) - (workloads/create-workload! request))))) - -(deftest test-create-covid-workload-with-invalid-sink-workspace - (is (thrown-with-msg? - UserException #"Cannot access workspace" - (workloads/create-workload! - (workloads/covid-workload-request - {:skipValidation true} - {:skipValidation true} - {:workspace "moo/moo" - :entityType "moo" - :identity "reads_id" - :fromOutputs {:submission_xml "submission_xml"}}))))) - (deftest test-start-workload (let [workload (workloads/create-workload! (workloads/covid-workload-request @@ -318,16 +147,14 @@ (is (:started (workloads/start-workload! workload))))) ;; Mocks - (def ^:private fake-method-name "method-name") -(def ^:private fake-method-config (str "method-namespace/" fake-method-name)) ;; Snapshot and snapshot reference mocks (def ^:private snapshot {:name "test-snapshot-name" :id (str (UUID/randomUUID))}) (def ^:private snapshot-reference-id (str (UUID/randomUUID))) (def ^:private snapshot-reference-name (str (:name snapshot) "-ref")) -(defn ^:private mock-rawls-create-snapshot-reference [& _] +(defn ^:private mock-rawls-snapshot-reference [& _] {:referenceId snapshot-reference-id :name snapshot-reference-name}) @@ -362,9 +189,10 @@ ;; when we create submissions, workflows have been queued for execution (defn ^:private mock-firecloud-create-submission [& _] - (let [enqueue #(-> % (dissoc :id) (assoc :staus "Queued"))] + (let [enqueue #(-> % (dissoc :id) (assoc :status "Queued"))] {:submissionId submission-id-mock - :workflows (map enqueue [running-workflow-mock succeeded-workflow-mock])})) + :workflows (map enqueue [running-workflow-mock + succeeded-workflow-mock])})) ;; when we get the submission later, the workflows may have a uuid assigned (defn ^:private mock-firecloud-get-submission [& _] @@ -374,282 +202,16 @@ (assoc :workflowEntity {:entityType "test" :entityName entityName}) (dissoc :entityName)))] {:submissionId submission-id-mock - :workflows (map add-workflow-entity [running-workflow-mock succeeded-workflow-mock])})) - -(defn ^:private mock-firecloud-create-failed-submission [& _] - {:submissionId submission-id-mock - :workflows [{:status "Failed" - :uuid (str (UUID/randomUUID)) - :entityName "failed"} - {:status "Aborted" - :uuid (str (UUID/randomUUID)) - :entityName "aborted"}]}) + :workflows (map add-workflow-entity [running-workflow-mock + succeeded-workflow-mock])})) ;; Workflow fetch mocks within update-workflow-statuses! -(defn ^:private mock-workflow-update-status [_ _ workflow-id] - (is (not (= (:workflowId succeeded-workflow-mock) workflow-id)) - "Successful workflow records should be filtered out before firecloud fetch") - {:status "Succeeded" :id workflow-id :workflowName fake-method-name}) (defn ^:private mock-workflow-keep-status [_ _ workflow-id] (is (not (= (:workflowId succeeded-workflow-mock) workflow-id)) "Successful workflow records should be filtered out before firecloud fetch") running-workflow-mock) -(defn ^:private mock-firecloud-get-workflow-outputs [_ _ workflow] - (is (= (:id succeeded-workflow-mock) workflow)) - {:tasks - {:noise - {} - (keyword fake-method-name) - {:outputs - (util/prefix-keys {:output "value"} (str fake-method-name "."))}}}) - -(defn ^:private create-tdr-source [] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> {:name "Terra DataRepo", - :dataset "this" - :table "is" - :column "fun" - :skipValidation true} - (covid/create-source! tx (rand-int 1000000)) - (zipmap [:source_type :source_items]) - (covid/load-source! tx)))) - -(defn ^:private reload-source [tx {:keys [type id] :as _source}] - (covid/load-source! tx {:source_type type :source_items (str id)})) - -(deftest test-start-tdr-source - (let [source (create-tdr-source)] - (is (-> source :last_checked nil?)) - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (covid/start-source! tx source) - (is (:last_checked (reload-source tx source)) - ":last_checked was not updated")))) - -(deftest test-update-tdr-source - (let [source (create-tdr-source) - expected-num-records (int (Math/ceil (/ mock-new-rows-size 500)))] - (with-redefs-fn - {#'covid/create-snapshots mock-create-snapshots - #'covid/find-new-rows mock-find-new-rows - #'covid/check-tdr-job mock-check-tdr-job} - (fn [] - (covid/update-source! - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (covid/start-source! tx source) - (reload-source tx source))) - (is (== expected-num-records (covid/queue-length! source)) - "snapshots should be enqueued") - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (let [records (->> source :details (postgres/get-table tx))] - (letfn [(record-updated? [record] - (and (= "succeeded" (:snapshot_creation_job_status record)) - (not (nil? (:snapshot_creation_job_id record))) - (not (nil? (:snapshot_id record)))))] - (testing "source details got updated with correct number of snapshot jobs" - (is (= expected-num-records (count records)))) - (testing "all snapshot jobs were updated and corresponding snapshot ids were inserted" - (is (every? record-updated? records)))))) - (covid/update-source! - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (covid/stop-source! tx source) - (reload-source tx source))) - (is (== expected-num-records (covid/queue-length! source)) - "no more snapshots should be enqueued") - (is (not (covid/done? source)) "the tdr source was done before snapshots were consumed"))))) - -(deftest test-stop-tdr-sourced - (let [source (create-tdr-source)] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (covid/start-source! tx source) - (covid/stop-source! tx source) - (let [source (reload-source tx source)] - (is (:stopped (reload-source tx source)) ":stopped was not written"))))) - -(defn ^:private create-tdr-snapshot-list [snapshots] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> {:name "TDR Snapshots" - :snapshots snapshots - :skipValidation true} - (covid/create-source! tx (rand-int 1000000)) - (zipmap [:source_type :source_items]) - (covid/load-source! tx)))) - -(defn ^:private create-terra-executor [id] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> {:name "Terra" - :workspace "workspace-ns/workspace-name" - :methodConfiguration fake-method-config - :methodConfigurationVersion method-config-version-mock - :fromSource "importSnapshot" - :skipValidation true} - (covid/create-executor! tx id) - (zipmap [:executor_type :executor_items]) - (covid/load-executor! tx)))) - -(deftest test-update-terra-executor - (let [source (create-tdr-snapshot-list [snapshot]) - executor (create-terra-executor (rand-int 1000000))] - (letfn [(verify-record-against-workflow [record workflow idx] - (is (= idx (:id record)) - "The record ID was incorrect given the workflow order in mocked submission") - (is (= (:id workflow) (:workflow record)) - "The workflow ID was incorrect and should match corresponding record"))] - (with-redefs-fn - {#'rawls/create-snapshot-reference mock-rawls-create-snapshot-reference - #'firecloud/get-method-configuration mock-firecloud-get-method-configuration - #'firecloud/update-method-configuration mock-firecloud-update-method-configuration - #'firecloud/submit-method mock-firecloud-create-submission - #'firecloud/get-submission mock-firecloud-get-submission - #'firecloud/get-workflow mock-workflow-update-status} - #(covid/update-executor! source executor)) - (is (zero? (covid/queue-length! source)) "The snapshot was not consumed.") - (is (== 2 (covid/queue-length! executor)) "Two workflows should be enqueued") - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (let [[running-record succeeded-record & _ :as records] - (->> executor :details (postgres/get-table tx) (sort-by :id)) - executor-record - (#'covid/load-record-by-id! tx "TerraExecutor" (:id executor))] - (is (== 2 (count records)) - "Exactly 2 workflows should have been written to the database") - (is (every? #(= snapshot-reference-id (:reference %)) records) - "The snapshot reference ID was incorrect and should match all records") - (is (every? #(= submission-id-mock (:submission %)) records) - "The submission ID was incorrect and should match all records") - (is (every? #(= "Succeeded" (:status %)) records) - "Status update mock should have marked running workflow as succeeded") - (is (every? #(nil? (:consumed %)) records) - "All records should be unconsumed") - (is (not (covid/done? executor)) "executor should not have finished processing") - (verify-record-against-workflow running-record running-workflow-mock 1) - (verify-record-against-workflow succeeded-record succeeded-workflow-mock 2) - (is (== (inc method-config-version-mock) (:method_configuration_version executor-record)) - "Method configuration version was not incremented.")))))) - -(deftest test-peek-terra-executor-queue - (let [succeeded? #{"Succeeded"} - source (create-tdr-snapshot-list [snapshot]) - executor (create-terra-executor (rand-int 1000000))] - (with-redefs-fn - {#'rawls/create-snapshot-reference mock-rawls-create-snapshot-reference - #'firecloud/get-method-configuration mock-firecloud-get-method-configuration - #'firecloud/update-method-configuration mock-firecloud-update-method-configuration - #'firecloud/submit-method mock-firecloud-create-submission - #'firecloud/get-submission mock-firecloud-get-submission - #'firecloud/get-workflow mock-workflow-keep-status} - #(covid/update-executor! source executor)) - (with-redefs-fn - {#'firecloud/get-workflow (constantly succeeded-workflow-mock) - #'firecloud/get-workflow-outputs mock-firecloud-get-workflow-outputs} - #(let [workflow (covid/peek-queue! executor)] - (is (succeeded? (:status workflow))) - (is (= (:id succeeded-workflow-mock) (:uuid workflow))) - (is (contains? workflow :updated)) - (is (= "value" (-> workflow :inputs :input))) - (is (= "value" (-> workflow :outputs :output))) - (is (not (-> workflow :outputs :noise))) - (covid/pop-queue! executor) - (is (nil? (covid/peek-queue! executor))) - (is (== 1 (covid/queue-length! executor))) - (is (not (covid/done? executor))))))) - -(def ^:private fake-entity-type "flowcell") -(def ^:private fake-entity-name "test") - -(deftest test-update-terra-workspace-sink - (let [workflow {:uuid "2768b29e-c808-4bd6-a46b-6c94fd2a67aa" - :status "Succeeded" - :outputs (-> "sarscov2_illumina_full/outputs.edn" - resources/read-resource - (assoc :flowcell_id fake-entity-name))} - executor (make-queue-from-list [workflow]) - sink (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> {:name "Terra Workspace" - :workspace "workspace-ns/workspace-name" - :entityType fake-entity-type - :fromOutputs (resources/read-resource - "sarscov2_illumina_full/entity-from-outputs.edn") - :identifier "flowcell_id" - :skipValidation true} - (covid/create-sink! tx (rand-int 1000000)) - (zipmap [:sink_type :sink_items]) - (covid/load-sink! tx)))] - (letfn [(verify-upsert-request [workspace [[type name _]]] - (is (= "workspace-ns/workspace-name" workspace)) - (is (= type fake-entity-type)) - (is (= name fake-entity-name))) - (throw-if-called [fname & args] - (throw (ex-info (str fname " should not have been called") - {:called-with args})))] - (with-redefs-fn - {#'rawls/batch-upsert verify-upsert-request - #'covid/entity-exists? (constantly false) - #'firecloud/delete-entities (partial throw-if-called "delete-entities")} - #(covid/update-sink! executor sink)) - (is (zero? (covid/queue-length! executor)) "The workflow was not consumed") - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (let [[record & rest] (->> sink :details (postgres/get-table tx))] - (is record "The record was not written to the database") - (is (empty? rest) "More than one record was written") - (is (= (:uuid workflow) (:workflow record)) - "The workflow UUID was not written") - (is (= fake-entity-name (:entity record)) - "The entity was not correct")))))) - -(deftest test-sinking-resubmitted-workflow - (fixtures/with-temporary-workspace - (fn [workspace] - (let [workflow1 {:uuid "2768b29e-c808-4bd6-a46b-6c94fd2a67aa" - :status "Succeeded" - :outputs {:run_id fake-entity-name - :results ["aligned-thing.cram"]}} - workflow2 {:uuid "2768b29e-c808-4bd6-a46b-6c94fd2a67ab" - :status "Succeeded" - :outputs {:run_id fake-entity-name - :results ["another-aligned-thing.cram"]}} - executor (make-queue-from-list [workflow1 workflow2]) - sink (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (->> {:name "Terra Workspace" - :workspace workspace - :entityType fake-entity-type - :fromOutputs {:aligned_crams "results"} - :identifier "run_id" - :skipValidation true} - (covid/create-sink! tx (rand-int 1000000)) - (zipmap [:sink_type :sink_items]) - (covid/load-sink! tx)))] - (covid/update-sink! executor sink) - (is (== 1 (covid/queue-length! executor)) - "one workflow should have been consumed") - (let [{:keys [entityType name attributes]} - (firecloud/get-entity workspace [fake-entity-type fake-entity-name])] - (is (= fake-entity-type entityType)) - (is (= fake-entity-name name)) - (is (== 1 (count attributes))) - (is (= [:aligned_crams {:itemsType "AttributeValue" :items ["aligned-thing.cram"]}] - (first attributes)))) - (covid/update-sink! executor sink) - (is (zero? (covid/queue-length! executor)) - "one workflow should have been consumed") - (let [entites (firecloud/list-entities workspace fake-entity-type)] - (is (== 1 (count entites)) - "No new entities should have been added")) - (let [{:keys [entityType name attributes]} - (firecloud/get-entity workspace [fake-entity-type fake-entity-name])] - (is (= fake-entity-type entityType)) - (is (= fake-entity-name name)) - (is (== 1 (count attributes))) - (is (= [:aligned_crams {:itemsType "AttributeValue" :items ["another-aligned-thing.cram"]}] - (first attributes)) - "attributes should have been overwritten")))))) - -(deftest test-tdr-snapshot-list-to-edn - (let [source (util/to-edn (create-tdr-snapshot-list [snapshot]))] - (is (not-any? source [:id :type])) - (is (= (:snapshots source) [(:id snapshot)])) - (is (s/valid? ::spec/snapshot-list-source source)))) - (deftest test-get-workflows-empty (let [workload (workloads/create-workload! (workloads/covid-workload-request @@ -660,15 +222,15 @@ (deftest test-workload-state-transition (with-redefs-fn - {#'covid/find-new-rows mock-find-new-rows - #'covid/create-snapshots mock-create-snapshots - #'covid/check-tdr-job mock-check-tdr-job - #'rawls/create-snapshot-reference mock-rawls-create-snapshot-reference - #'firecloud/get-method-configuration mock-firecloud-get-method-configuration - #'firecloud/update-method-configuration mock-firecloud-update-method-configuration - #'firecloud/submit-method mock-firecloud-create-submission - #'firecloud/get-submission mock-firecloud-get-submission - #'firecloud/get-workflow mock-workflow-keep-status} + {#'source/find-new-rows mock-find-new-rows + #'source/create-snapshots mock-create-snapshots + #'source/check-tdr-job mock-check-tdr-job + #'rawls/create-or-get-snapshot-reference mock-rawls-snapshot-reference + #'firecloud/method-configuration mock-firecloud-get-method-configuration + #'firecloud/update-method-configuration mock-firecloud-update-method-configuration + #'firecloud/submit-method mock-firecloud-create-submission + #'firecloud/get-submission mock-firecloud-get-submission + #'firecloud/get-workflow mock-workflow-keep-status} #(shared/run-workload-state-transition-test! (workloads/covid-workload-request {:skipValidation true} @@ -692,60 +254,59 @@ (deftest test-workload-state-transition-with-failed-workflow (with-redefs-fn - {#'covid/find-new-rows mock-find-new-rows - #'covid/create-snapshots mock-create-snapshots - #'covid/check-tdr-job mock-check-tdr-job - #'rawls/create-snapshot-reference mock-rawls-create-snapshot-reference - #'firecloud/get-method-configuration mock-firecloud-get-method-configuration - #'firecloud/update-method-configuration mock-firecloud-update-method-configuration - #'firecloud/submit-method mock-firecloud-create-submission - #'firecloud/get-workflow (constantly {:status "Failed"})} + {#'source/find-new-rows mock-find-new-rows + #'source/create-snapshots mock-create-snapshots + #'source/check-tdr-job mock-check-tdr-job + #'rawls/create-or-get-snapshot-reference mock-rawls-snapshot-reference + #'firecloud/method-configuration mock-firecloud-get-method-configuration + #'firecloud/update-method-configuration mock-firecloud-update-method-configuration + #'firecloud/submit-method mock-firecloud-create-submission + #'firecloud/get-workflow (constantly {:status "Failed"})} #(shared/run-workload-state-transition-test! (workloads/covid-workload-request {:skipValidation true} {:skipValidation true} {:skipValidation true})))) -(defn ^:private create-app [input-spec output-spec handler] - (let [app - (ring/ring-handler - (ring/router - [["/test" {:post {:parameters {:body input-spec} - :responses {200 {:body output-spec}} - :handler (fn [{:keys [body-params]}] - {:status 200 - :body (handler body-params)})}}]] - {:data {:coercion reitit.coercion.spec/coercion - :middleware [coercion/coerce-exceptions-middleware - coercion/coerce-request-middleware - coercion/coerce-response-middleware]}}))] - (fn [request] - (app {:request-method :post - :uri "/test" - :body-params request})))) - (deftest test-create-workload-coercion - (let [app (create-app ::spec/workload-request - ::spec/workload-response - (comp util/to-edn workloads/create-workload!)) + (let [app (coercion-tester + ::spec/workload-request + ::spec/workload-response + (comp util/to-edn workloads/create-workload!)) request (workloads/covid-workload-request {} {:skipValidation true} {:skipValidation true})] (testing "Workload with a TDR Source" - (let [{:keys [status body]} - (->> {:name "Terra DataRepo" - :dataset testing-dataset - :table testing-table-name - :column testing-column-name - :snapshotReaders ["workflow-launcher-dev@firecloud.org"]} - (assoc request :source) - app)] - (is (== 200 status) body))) + (->> {:name "Terra DataRepo" + :dataset testing-dataset + :table testing-table-name + :column testing-column-name + :snapshotReaders ["workflow-launcher-dev@firecloud.org"]} + (assoc request :source) + app)) (testing "Workload with a TDR Snapshots Source" - (let [{:keys [status body]} - (->> {:name "TDR Snapshots" - :snapshots [testing-snapshot]} - (assoc request :source) - app)] - (is (== 200 status) body))))) + (->> {:name "TDR Snapshots" + :snapshots [testing-snapshot]} + (assoc request :source) + app)))) + +(deftest test-retry-workload-throws-when-not-started + (with-redefs-fn + {#'source/find-new-rows mock-find-new-rows + #'source/create-snapshots mock-create-snapshots + #'source/check-tdr-job mock-check-tdr-job + #'rawls/create-or-get-snapshot-reference mock-rawls-snapshot-reference + #'firecloud/method-configuration mock-firecloud-get-method-configuration + #'firecloud/update-method-configuration mock-firecloud-update-method-configuration + #'firecloud/submit-method mock-firecloud-create-submission + #'firecloud/get-workflow (constantly {:status "Failed"})} + #(let [workload-request (workloads/covid-workload-request + {:skipValidation true} + {:skipValidation true} + {:skipValidation true}) + workload (workloads/create-workload! workload-request)] + (is (not (:started workload))) + (is (thrown-with-msg? + UserException #"Cannot retry workload before it's been started." + (workloads/retry workload [])))))) diff --git a/api/test/wfl/integration/modules/sg_test.clj b/api/test/wfl/integration/modules/sg_test.clj index 1b6542e9b..30819f2cf 100644 --- a/api/test/wfl/integration/modules/sg_test.clj +++ b/api/test/wfl/integration/modules/sg_test.clj @@ -1,6 +1,8 @@ (ns wfl.integration.modules.sg-test - (:require [clojure.string :as str] - [clojure.test :refer :all] + (:require [clojure.test :refer [deftest is testing + use-fixtures]] + [clojure.string :as str] + [wfl.api.workloads] ; for mocking [wfl.integration.modules.shared :as shared] [wfl.jdbc :as jdbc] [wfl.module.batch :as batch] @@ -19,8 +21,8 @@ (def ^:private the-uuids (repeatedly #(str (UUID/randomUUID)))) (defn the-sg-workload-request - [] "A request suitable when all external services are mocked." + [] {:executor @workloads/cromwell-url :output "gs://broad-gotc-dev-wfl-sg-test-outputs" :pipeline "GDCWholeGenomeSomaticSingleSample" @@ -304,12 +306,6 @@ (ok? (parse (get-in edn md))) :else false))))) -(def ^:private bam-suffixes - "Map Clio BAM record fields to expected file suffixes." - {:bai_path ".bai" - :bam_path ".bam" - :insert_size_metrics_path ".insert_size_metrics"}) - (defn ^:private test-clio-updates [] (let [{:keys [items] :as request} (the-sg-workload-request)] @@ -320,7 +316,8 @@ (let [{:keys [finished pipeline]} workload] (is finished) (is (= sg/pipeline pipeline)) - (is (= (count items) (-> workload workloads/workflows count)))))))) + (is (= (count items) + (-> workload workloads/workflows count)))))))) (deftest test-clio-updates-bam-found (testing "Clio not updated if outputs already known." @@ -370,10 +367,10 @@ (run! (partial workflow-postcheck output) (workloads/workflows workload))) (defn ^:private mock-batch-update-workflow-statuses! - [tx {:keys [items] :as workload}] + [status tx {:keys [items] :as workload}] (letfn [(update! [{:keys [id]}] (jdbc/update! tx items - {:status "Succeeded" :updated (OffsetDateTime/now)} + {:status status :updated (OffsetDateTime/now)} ["id = ?" id]))] (run! update! (wfl.api.workloads/workflows tx workload)))) @@ -382,10 +379,16 @@ increment-count (fn [& _] (swap! count inc))] (with-redefs-fn {#'cromwell/submit-workflows mock-cromwell-submit-workflows - #'batch/batch-update-workflow-statuses! mock-batch-update-workflow-statuses! + #'batch/batch-update-workflow-statuses! (partial mock-batch-update-workflow-statuses! "Succeeded") #'sg/register-workload-in-clio increment-count} #(shared/run-workload-state-transition-test! (the-sg-workload-request))) (is (== 1 @count) "Clio was updated more than once"))) (deftest test-stop-workload-state-transition (shared/run-stop-workload-state-transition-test! (the-sg-workload-request))) + +(deftest test-retry-workflows-supported + (with-redefs-fn + {#'cromwell/submit-workflows mock-cromwell-submit-workflows + #'batch/batch-update-workflow-statuses! (partial mock-batch-update-workflow-statuses! "Failed")} + #(shared/run-workload-state-transition-test! (the-sg-workload-request)))) diff --git a/api/test/wfl/integration/modules/shared.clj b/api/test/wfl/integration/modules/shared.clj index 576c21ef3..771bfc4d2 100644 --- a/api/test/wfl/integration/modules/shared.clj +++ b/api/test/wfl/integration/modules/shared.clj @@ -1,5 +1,5 @@ (ns wfl.integration.modules.shared - (:require [clojure.test :refer [deftest is]] + (:require [clojure.test :refer [is]] [wfl.tools.workloads :as workloads] [wfl.util :refer [absent?]]) (:import [wfl.util UserException])) @@ -47,3 +47,10 @@ (is (thrown-with-msg? UserException #"Cannot stop workload" (workloads/stop-workload! workload))))) + +(defn run-retry-is-not-supported-test! [workload-request] + (let [workload (workloads/execute-workload! workload-request) + failed (workloads/workflows-by-status workload "Failed")] + (is (thrown-with-msg? + UserException #"Cannot retry workflows" + (workloads/retry workload failed))))) diff --git a/api/test/wfl/integration/modules/wgs_test.clj b/api/test/wfl/integration/modules/wgs_test.clj index f3f9f52df..d8cfa5384 100644 --- a/api/test/wfl/integration/modules/wgs_test.clj +++ b/api/test/wfl/integration/modules/wgs_test.clj @@ -1,7 +1,8 @@ (ns wfl.integration.modules.wgs-test - (:require [clojure.set :refer [rename-keys]] - [clojure.test :refer [deftest testing is] :as clj-test] + (:require [clojure.test :refer [deftest is testing + use-fixtures]] [clojure.string :as str] + [wfl.api.workloads :as api] [wfl.integration.modules.shared :as shared] [wfl.jdbc :as jdbc] [wfl.module.all :as all] @@ -16,7 +17,7 @@ (:import [java.util UUID] [java.time OffsetDateTime])) -(clj-test/use-fixtures :once fixtures/temporary-postgresql-database) +(use-fixtures :once fixtures/temporary-postgresql-database) (defn ^:private mock-submit-workflows [_ _ inputs _ _] (map (fn [_] (UUID/randomUUID)) inputs)) @@ -200,18 +201,24 @@ workloads/workflows)))) (defn mock-batch-update-workflow-statuses! - [tx {:keys [items] :as workload}] + [status tx {:keys [items] :as workload}] (letfn [(update! [{:keys [id]}] (jdbc/update! tx items - {:status "Succeeded" :updated (OffsetDateTime/now)} + {:status status :updated (OffsetDateTime/now)} ["id = ?" id]))] - (run! update! (wfl.api.workloads/workflows tx workload)))) + (run! update! (api/workflows tx workload)))) (deftest test-workload-state-transition (with-redefs-fn {#'cromwell/submit-workflows mock-submit-workflows - #'batch/batch-update-workflow-statuses! mock-batch-update-workflow-statuses!} + #'batch/batch-update-workflow-statuses! (partial mock-batch-update-workflow-statuses! "Succeeded")} #(shared/run-workload-state-transition-test! (make-wgs-workload-request)))) (deftest test-stop-workload-state-transition (shared/run-stop-workload-state-transition-test! (make-wgs-workload-request))) + +(deftest test-retry-failed-workflows + (with-redefs-fn + {#'cromwell/submit-workflow (fn [& _] (UUID/randomUUID)) + #'batch/batch-update-workflow-statuses! (partial mock-batch-update-workflow-statuses! "Failed")} + #(shared/run-retry-is-not-supported-test! (make-wgs-workload-request)))) diff --git a/api/test/wfl/integration/modules/xx_test.clj b/api/test/wfl/integration/modules/xx_test.clj index 6fa4e2eb6..2eb9cfada 100644 --- a/api/test/wfl/integration/modules/xx_test.clj +++ b/api/test/wfl/integration/modules/xx_test.clj @@ -40,7 +40,7 @@ (let [common-inputs {:bait_set_name "Geoff" :bait_interval_list "gs://fake-input-bucket/interval-list"}] (letfn [(go! [inputs] - (letfn [(value-equal? [key] (= (key common-inputs) (key inputs)))] + (letfn [(value-equal? [k] (= (k common-inputs) (k inputs)))] (is (value-equal? :bait_set_name)) (is (value-equal? :bait_interval_list))))] (run! (comp go! :inputs) (-> (make-xx-workload-request) @@ -147,18 +147,24 @@ workloads/workflows)))) (defn mock-batch-update-workflow-statuses! - [tx {:keys [items] :as workload}] + [status tx {:keys [items] :as workload}] (letfn [(update! [{:keys [id]}] (jdbc/update! tx items - {:status "Succeeded" :updated (OffsetDateTime/now)} + {:status status :updated (OffsetDateTime/now)} ["id = ?" id]))] (run! update! (workloads/workflows workload)))) (deftest test-workload-state-transition (with-redefs-fn {#'cromwell/submit-workflows mock-submit-workflows - #'batch/batch-update-workflow-statuses! mock-batch-update-workflow-statuses!} + #'batch/batch-update-workflow-statuses! (partial mock-batch-update-workflow-statuses! "Succeeded")} #(shared/run-workload-state-transition-test! (make-xx-workload-request)))) (deftest test-stop-workload-state-transition (shared/run-stop-workload-state-transition-test! (make-xx-workload-request))) + +(deftest test-retry-failed-workflows + (with-redefs-fn + {#'cromwell/submit-workflow (fn [& _] (UUID/randomUUID)) + #'batch/batch-update-workflow-statuses! (partial mock-batch-update-workflow-statuses! "Failed")} + #(shared/run-retry-is-not-supported-test! (make-xx-workload-request)))) diff --git a/api/test/wfl/integration/rawls_test.clj b/api/test/wfl/integration/rawls_test.clj index 5a33d4c6d..68ccd1192 100644 --- a/api/test/wfl/integration/rawls_test.clj +++ b/api/test/wfl/integration/rawls_test.clj @@ -21,33 +21,36 @@ (fn [workspace] (letfn [(make-reference [snapshot-name] (rawls/create-snapshot-reference workspace snapshot-id snapshot-name)) - (verify-snapshot [[snapshot snapshot-name]] - (is (= "DATA_REPO_SNAPSHOT" (:referenceType snapshot))) - (is (= snapshot-id (get-in snapshot [:reference :snapshot]))) - (is (= snapshot-name (:name snapshot)))) - (verify-snapshots [snapshots snapshot-names] - (->> (map list snapshots snapshot-names) - (run! verify-snapshot)))] + (verify-reference [[{:keys [attributes metadata] :as _reference} + snapshot-names]] + (is (= "DATA_REPO_SNAPSHOT" (:resourceType metadata))) + (is (= snapshot-id (:snapshot attributes))) + (is (= snapshot-names (:name metadata)))) + (verify-references [references snapshot-names] + (->> (map list references snapshot-names) + (run! verify-reference)))] (let [names ["snapshot1" "snapshot2"] reference-ids (testing "Create" - (let [snapshots (map make-reference names)] - (verify-snapshots snapshots names) - (map :referenceId snapshots)))] + (let [references (map make-reference names)] + (verify-references references names) + (map #(get-in % [:metadata :resourceId]) references)))] (testing "Get" - (let [snapshots + (let [references (map #(rawls/get-snapshot-reference workspace %) reference-ids)] - (verify-snapshots snapshots names))) - (testing "Get all" - (let [[_first _second & rest :as snapshots] - (rawls/get-snapshot-references workspace 10)] + (verify-references references names))) + (testing "Get all for snapshot id" + (let [[_first _second & rest :as references] + (rawls/get-snapshot-references-for-snapshot-id workspace + snapshot-id + 10)] (is (empty? rest)) - (verify-snapshots snapshots names))) + (verify-references references names))) (testing "Create or get" - (let [snapshot (rawls/create-or-get-snapshot-reference workspace - snapshot-id - (first names))] - (verify-snapshot [snapshot (first names)]))) + (let [reference (rawls/create-or-get-snapshot-reference workspace + snapshot-id + (first names))] + (verify-reference [reference (first names)]))) (testing "Create already exists" (is (thrown-with-msg? ExceptionInfo #"clj-http: status 409" (make-reference (first names)))))))))) diff --git a/api/test/wfl/integration/sinks/datarepo_sink_test.clj b/api/test/wfl/integration/sinks/datarepo_sink_test.clj new file mode 100644 index 000000000..154cd053f --- /dev/null +++ b/api/test/wfl/integration/sinks/datarepo_sink_test.clj @@ -0,0 +1,131 @@ +(ns wfl.integration.sinks.datarepo-sink-test + "Test validation and operations on the DataRepo sink implementation." + (:require [clojure.test :refer [deftest is use-fixtures]] + [wfl.environment :as env] + [wfl.service.postgres :as postgres] + [wfl.sink :as sink] + [wfl.stage :as stage] + [wfl.tools.datasets :as datasets] + [wfl.tools.fixtures :as fixtures] + [wfl.tools.queues :refer [make-queue-from-list]] + [wfl.tools.resources :as resources] + [wfl.tools.workloads :refer [evalT]] + [wfl.util :as util]) + (:import [java.util UUID] + [wfl.util UserException])) + +(def ^:private ^:dynamic *dataset*) + +(use-fixtures :once + fixtures/temporary-postgresql-database + (fixtures/bind-fixture + *dataset* + fixtures/with-temporary-dataset + (datasets/unique-dataset-request + (env/getenv "WFL_TDR_DEFAULT_PROFILE") "testing-dataset.json"))) + +(def ^:private outputs + {:outbool true + :outfile "gs://broad-gotc-dev-wfl-ptc-test-inputs/external-reprocessing/exome/develop/not-a-real.unmapped.bam" + :outfloat (* 4 (Math/atan 1)) + :outint 27 + :outstring "Hello, World!"}) + +;; Must be a function to capture value of *dataset* after setting up test +;; fixtures. +(defn ^:private datarepo-sink-request + "Return a valid Tera DataRepo sink request." + [] + {:name @#'sink/datarepo-sink-name + :dataset *dataset* + :table "parameters" + :fromOutputs {:fileref "outfile"}}) + +(deftest test-validate-datarepo-sink-with-valid-sink-request + (is (sink/datarepo-sink-validate-request-or-throw (datarepo-sink-request)))) + +(deftest test-validate-datarepo-sink-throws-on-invalid-dataset + (is (thrown-with-msg? + UserException #"Cannot access dataset" + (sink/datarepo-sink-validate-request-or-throw + {:name @#'sink/datarepo-sink-name + :dataset util/uuid-nil + :table "parameters" + :fromOutputs {:fileref "some_output_file"}})))) + +(deftest test-validate-datarepo-sink-throws-on-invalid-table + (is (thrown-with-msg? + UserException #"Table not found" + (sink/datarepo-sink-validate-request-or-throw + {:name @#'sink/datarepo-sink-name + :dataset *dataset* + :table "not-a-table" + :fromOutputs {:fileref "some_output_file"}})))) + +(deftest test-validate-datarepo-sink-throws-on-malformed-fromOutputs + (is (thrown-with-msg? + UserException (re-pattern sink/datarepo-malformed-from-outputs-message) + (sink/datarepo-sink-validate-request-or-throw + {:name @#'sink/datarepo-sink-name + :dataset *dataset* + :table "parameters" + :fromOutputs "bad"})))) + +(deftest test-validate-datarepo-sink-throws-on-unknown-column-name + (is (thrown-with-msg? + UserException (re-pattern sink/unknown-columns-error-message) + (sink/datarepo-sink-validate-request-or-throw + {:name @#'sink/datarepo-sink-name + :dataset *dataset* + :table "parameters" + :fromOutputs {:not-a-column "some_output_file"}})))) + +;; Operation tests +(def ^:private random (partial rand-int 1000000)) + +(deftest test-create-datarepo-sink + (let [[type items] (evalT sink/create-sink! (random) (datarepo-sink-request))] + (is (= @#'sink/datarepo-sink-type type)) + (is (-> items Integer/parseInt pos?)) + (let [sink (evalT sink/load-sink! {:sink_type type :sink_items items})] + (is (= @#'sink/datarepo-sink-type (:type sink))) + (is (every? sink [:dataset :table :fromOutputs :details])) + (is (get-in sink [:dataset :defaultProfileId])) + (is (evalT postgres/table-exists? (:details sink)))))) + +(defn ^:private create-and-load-datarepo-sink [] + (let [[type items] (evalT sink/create-sink! (random) (datarepo-sink-request))] + (evalT sink/load-sink! {:sink_type type :sink_items items}))) + +(deftest test-datarepo-sink-initially-done + (is (stage/done? (create-and-load-datarepo-sink)))) + +(deftest test-data-repo-job-queue-operations + (let [sink (create-and-load-datarepo-sink)] + (is (nil? (#'sink/peek-job-queue sink))) + (is (thrown? AssertionError (#'sink/pop-job-queue! sink {}))))) + +(deftest test-datarepo-sink-to-edn + (let [response (util/to-edn (create-and-load-datarepo-sink))] + (is (= *dataset* (:dataset response))) + (is (not-any? response [:id :details])))) + +(defmacro throws? [exception-type] + (let [task (gensym)] + `(fn [~task] (is ~(list 'thrown? exception-type (list task)))))) + +(defn eventually [assertion task & opts] + (let [{:keys [interval times]} (apply hash-map opts)] + (assertion #(util/poll task (or interval 1) (or times 5))))) + +(deftest test-update-datarepo-sink + (let [description (resources/read-resource "primitive.edn") + workflow {:uuid (UUID/randomUUID) :outputs outputs} + upstream (make-queue-from-list [[description workflow]]) + sink (create-and-load-datarepo-sink)] + (sink/update-sink! upstream sink) + (is (stage/done? upstream)) + (eventually (throws? UserException) #(sink/update-sink! upstream sink) + :interval 5 :times 10) + (is (stage/done? sink) "failed jobs are no longer considered") + (is (or (sink/update-sink! upstream sink) true) "subsequent updates do nothing"))) diff --git a/api/test/wfl/integration/sinks/workspace_sink_test.clj b/api/test/wfl/integration/sinks/workspace_sink_test.clj new file mode 100644 index 000000000..f9162f0a8 --- /dev/null +++ b/api/test/wfl/integration/sinks/workspace_sink_test.clj @@ -0,0 +1,170 @@ +(ns wfl.integration.sinks.workspace-sink-test + "Test validation and operations on the Terra Workspace Sink implementation." + (:require [clojure.test :refer [deftest is use-fixtures]] + [wfl.jdbc :as jdbc] + [wfl.service.firecloud :as firecloud] + [wfl.service.postgres :as postgres] + [wfl.service.rawls :as rawls] + [wfl.sink :as sink] + [wfl.stage :as stage] + [wfl.tools.fixtures :as fixtures] + [wfl.tools.queues :refer [make-queue-from-list]] + [wfl.tools.resources :as resources]) + (:import [wfl.util UserException])) + +;; Workspace +(def ^:private testing-namespace "wfl-dev") +(def ^:private testing-workspace (str testing-namespace "/" "CDC_Viral_Sequencing")) + +;; Entity +(def ^:private testing-entity-type "flowcell") +(def ^:private testing-entity-name "test") + +(let [new-env {"WFL_FIRECLOUD_URL" "https://api.firecloud.org" + "WFL_RAWLS_URL" "https://rawls.dsde-prod.broadinstitute.org"}] + (use-fixtures :once + (fixtures/temporary-environment new-env) + fixtures/temporary-postgresql-database)) + +;; Validation tests + +(deftest test-validate-terra-workspace-sink-with-valid-sink-request + (is (sink/terra-workspace-sink-validate-request-or-throw + {:name @#'sink/terra-workspace-sink-name + :workspace testing-workspace + :entityType "assemblies" + :identity "Who cares?" + :fromOutputs {:assemblies_id "foo"}}))) + +(deftest test-validate-terra-workspace-sink-throws-on-invalid-sink-entity-type + (is (thrown-with-msg? + UserException (re-pattern sink/unknown-entity-type-error-message) + (sink/terra-workspace-sink-validate-request-or-throw + {:name @#'sink/terra-workspace-sink-name + :workspace testing-workspace + :entityType "does_not_exist" + :identity "Who cares?" + :fromOutputs {}})))) + +(deftest test-validate-terra-workspace-sink-throws-on-malformed-fromOutputs + (is (thrown-with-msg? + UserException (re-pattern sink/terra-workspace-malformed-from-outputs-message) + (sink/terra-workspace-sink-validate-request-or-throw + {:name @#'sink/terra-workspace-sink-name + :workspace testing-workspace + :entityType "assemblies" + :identity "Who cares?" + :fromOutputs "geoff"})))) + +(deftest test-validate-terra-workspace-sink-throws-on-unknown-fromOutputs-attributes + (is (thrown-with-msg? + UserException (re-pattern sink/unknown-attributes-error-message) + (sink/terra-workspace-sink-validate-request-or-throw + {:name @#'sink/terra-workspace-sink-name + :workspace testing-workspace + :entityType "assemblies" + :identity "Who cares?" + :fromOutputs {:does_not_exist "genbank_source_table"}})))) + +(deftest test-validate-terra-workspace-sink-throws-on-invalid-sink-workspace + (is (thrown-with-msg? + UserException #"Cannot access workspace" + (sink/terra-workspace-sink-validate-request-or-throw + {:name @#'sink/terra-workspace-sink-name + :workspace "moo/moo" + :entityType "moo" + :identity "reads_id" + :fromOutputs {:submission_xml "submission_xml"}})))) + +;; Operation tests + +(deftest test-update-terra-workspace-sink + (let [workflow {:uuid "2768b29e-c808-4bd6-a46b-6c94fd2a67aa" + :status "Succeeded" + :outputs (-> "sarscov2_illumina_full/outputs.edn" + resources/read-resource + (assoc :flowcell_id testing-entity-name))} + executor (make-queue-from-list [[nil workflow]]) + sink (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> {:name "Terra Workspace" + :workspace "workspace-ns/workspace-name" + :entityType testing-entity-type + :fromOutputs (resources/read-resource + "sarscov2_illumina_full/entity-from-outputs.edn") + :identifier "flowcell_id" + :skipValidation true} + (sink/create-sink! tx (rand-int 1000000)) + (zipmap [:sink_type :sink_items]) + (sink/load-sink! tx)))] + (letfn [(verify-upsert-request [workspace [[type name _]]] + (is (= "workspace-ns/workspace-name" workspace)) + (is (= type testing-entity-type)) + (is (= name testing-entity-name))) + (throw-if-called [fname & args] + (throw (ex-info (str fname " should not have been called") + {:called-with args})))] + (with-redefs-fn + {#'rawls/batch-upsert verify-upsert-request + #'sink/entity-exists? (constantly false) + #'firecloud/delete-entities (partial throw-if-called "delete-entities")} + #(sink/update-sink! executor sink)) + (is (zero? (stage/queue-length executor)) "The workflow was not consumed") + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (let [[record & rest] (->> sink :details (postgres/get-table tx))] + (is record "The record was not written to the database") + (is (empty? rest) "More than one record was written") + (is (= (:uuid workflow) (:workflow record)) + "The workflow UUID was not written") + (is (= testing-entity-name (:entity record)) + "The entity was not correct")))))) + +(deftest test-sinking-resubmitted-workflow + (fixtures/with-temporary-workspace + (fn [workspace] + (let [workflow1 {:uuid "2768b29e-c808-4bd6-a46b-6c94fd2a67aa" + :status "Succeeded" + :outputs {:run_id testing-entity-name + :results ["aligned-thing.cram"]}} + workflow2 {:uuid "2768b29e-c808-4bd6-a46b-6c94fd2a67ab" + :status "Succeeded" + :outputs {:run_id testing-entity-name + :results ["another-aligned-thing.cram"]}} + executor (make-queue-from-list [[nil workflow1] [nil workflow2]]) + sink (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> {:name "Terra Workspace" + :workspace workspace + :entityType testing-entity-type + :fromOutputs {:aligned_crams "results"} + :identifier "run_id" + :skipValidation true} + (sink/create-sink! tx (rand-int 1000000)) + (zipmap [:sink_type :sink_items]) + (sink/load-sink! tx)))] + (sink/update-sink! executor sink) + (is (== 1 (stage/queue-length executor)) + "one workflow should have been consumed") + (let [{:keys [entityType name attributes]} + (firecloud/get-entity + workspace [testing-entity-type testing-entity-name])] + (is (= testing-entity-type entityType)) + (is (= testing-entity-name name)) + (is (== 1 (count attributes))) + (is (= [:aligned_crams {:itemsType "AttributeValue" + :items ["aligned-thing.cram"]}] + (first attributes)))) + (sink/update-sink! executor sink) + (is (zero? (stage/queue-length executor)) + "one workflow should have been consumed") + (let [entites (firecloud/list-entities workspace testing-entity-type)] + (is (== 1 (count entites)) + "No new entities should have been added")) + (let [{:keys [entityType name attributes]} + (firecloud/get-entity + workspace [testing-entity-type testing-entity-name])] + (is (= testing-entity-type entityType)) + (is (= testing-entity-name name)) + (is (== 1 (count attributes))) + (is (= [:aligned_crams {:itemsType "AttributeValue" + :items ["another-aligned-thing.cram"]}] + (first attributes)) + "attributes should have been overwritten")))))) diff --git a/api/test/wfl/integration/source_test.clj b/api/test/wfl/integration/source_test.clj new file mode 100644 index 000000000..648fe49a8 --- /dev/null +++ b/api/test/wfl/integration/source_test.clj @@ -0,0 +1,234 @@ +(ns wfl.integration.source-test + (:require [clojure.test :refer [deftest is testing use-fixtures]] + [clojure.java.jdbc :as jdbc] + [clojure.set :as set] + [clojure.spec.alpha :as s] + [wfl.service.datarepo :as datarepo] + [wfl.service.postgres :as postgres] + [wfl.source :as source] + [wfl.stage :as stage] + [wfl.tools.fixtures :as fixtures] + [wfl.util :as util]) + (:import [java.time Instant LocalDateTime] + [java.util UUID] + [wfl.util UserException])) + +(def ^:private testing-dataset "cd25d59e-1451-44d0-8a24-7669edb9a8f8") +(def ^:private testing-snapshot "e8f1675e-1e7c-48b4-92ab-3598425c149d") +(def ^:private testing-table-name "flowcells") +(def ^:private testing-column-name "run_date") + +;; Snapshot creation mock +(def ^:private mock-new-rows-size 1234) + +(defn ^:private parse-timestamp + "Parse `timestamp` string in BigQuery format." + [timestamp] + (LocalDateTime/parse timestamp @#'source/bigquery-datetime-format)) + +(defn ^:private mock-find-new-rows + [_source interval] + (is (every? parse-timestamp interval)) + (range mock-new-rows-size)) + +(defn ^:private mock-create-snapshots [_ _ row-ids] + (letfn [(f [idx shard] [(vec shard) (format "mock_job_id_%s" idx)])] + (->> (partition-all 500 row-ids) + (map-indexed f)))) + +;; Note this mock only covers happy paths of TDR jobs +(defn ^:private mock-check-tdr-job [job-id] + {:snapshot_id (str (UUID/randomUUID)) + :job_status "succeeded" + :id job-id}) + +;; Queue mocks +(use-fixtures :once fixtures/temporary-postgresql-database) + +(defn ^:private create-tdr-source [] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> {:column "a-column" + :dataset {:name "a-dataset"} + :id "an-id" + :name "Terra DataRepo" + :skipValidation true + :table "a-table" + :type "a-type"} + (source/create-source! tx (rand-int 1000000)) + (zipmap [:source_type :source_items]) + (source/load-source! tx)))) + +(defn ^:private reload-source [tx {:keys [type id] :as _source}] + (source/load-source! tx {:source_type type :source_items (str id)})) + +;; A stable vector of TDR row IDs. +;; +(defonce all-rows + (delay (vec (repeatedly mock-new-rows-size #(str (UUID/randomUUID)))))) + +(defn ^:private mock-query-table-between-all + "Mock datarepo/query-table-between to find all rows." + [_dataset _table _between interval columns] + (is (every? parse-timestamp interval)) + (letfn [(field [column] {:mode "NULLABLE" :name column :type "STRING"}) + (fields [columns] (mapv field columns))] + (-> {:jobComplete true + :kind "bigquery#queryResponse" + :rows [@all-rows] + :totalRows (str (count @all-rows))} + (assoc-in [:schema :fields] (fields columns))))) + +(defn ^:private mock-query-table-between-miss + "Mock datarepo/query-table-between to miss some rows." + [dataset table between interval columns] + (-> (mock-query-table-between-all dataset table between interval columns) + (update-in [:rows 0] butlast) + (assoc :totalRows (str (dec mock-new-rows-size))))) + +(deftest test-backfill-tdr-source + (letfn [(rows-from [source] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> source :details + (postgres/get-table tx) + (mapcat :datarepo_row_ids)))) + (total-rows [query args] + (-> query (apply args) :totalRows Integer/parseInt))] + (let [args [testing-dataset testing-table-name testing-column-name + (repeatedly 2 #(-> (Instant/now) str + (subs 0 (count "2021-07-14T15:47:02")))) + [:datarepo_row_id]] + record-count (int (Math/ceil (/ mock-new-rows-size 500))) + source (create-tdr-source)] + (testing "update-source! loads snapshots" + (with-redefs [datarepo/query-table-between mock-query-table-between-miss + source/check-tdr-job mock-check-tdr-job + source/create-snapshots mock-create-snapshots] + (source/update-source! + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (source/start-source! tx source) + (reload-source tx source)))) + (let [miss-count (dec mock-new-rows-size) + miss-set (set (rows-from source))] + (is (== record-count (stage/queue-length source))) + (is (== miss-count (total-rows mock-query-table-between-miss args))) + (is (== miss-count (count miss-set))) + (testing "update-source! adds a snaphot of rows missed in prior interval" + (with-redefs [datarepo/query-table-between mock-query-table-between-all + source/check-tdr-job mock-check-tdr-job + source/create-snapshots mock-create-snapshots] + (source/update-source! + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (reload-source tx source)))) + (let [all-rows (rows-from source) + missing (set/difference (set all-rows) miss-set)] + (is (== (inc record-count) (stage/queue-length source))) + (is (== mock-new-rows-size (total-rows mock-query-table-between-all args))) + (is (= (last all-rows) (first missing))) + (is (== 1 (count missing)))))))))) + +(deftest test-create-tdr-source-from-valid-request + (is (source/datarepo-source-validate-request-or-throw + {:name "Terra DataRepo" + :dataset testing-dataset + :table testing-table-name + :column testing-column-name}))) + +(deftest test-create-tdr-source-with-non-existent-dataset + (is (thrown-with-msg? + UserException #"Cannot access dataset" + (source/datarepo-source-validate-request-or-throw + {:name "Terra DataRepo" + :dataset util/uuid-nil})))) + +(deftest test-create-tdr-source-with-invalid-dataset-table + (is (thrown-with-msg? + UserException #"Table not found" + (source/datarepo-source-validate-request-or-throw + {:name "Terra DataRepo" + :dataset testing-dataset + :table "no_such_table"})))) + +(deftest test-create-tdr-source-with-invalid-dataset-column + (is (thrown-with-msg? + UserException #"Column not found" + (source/datarepo-source-validate-request-or-throw + {:name "Terra DataRepo" + :dataset testing-dataset + :table testing-table-name + :column "no_such_column"})))) + +(deftest test-start-tdr-source + (let [source (create-tdr-source)] + (is (-> source :last_checked nil?)) + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (source/start-source! tx source) + (is (:last_checked (reload-source tx source)) + ":last_checked was not updated")))) + +(deftest test-update-tdr-source + (let [source (create-tdr-source) + expected-num-records (int (Math/ceil (/ mock-new-rows-size 500)))] + (with-redefs-fn + {#'source/create-snapshots mock-create-snapshots + #'source/find-new-rows mock-find-new-rows + #'source/check-tdr-job mock-check-tdr-job} + (fn [] + (source/update-source! + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (source/start-source! tx source) + (reload-source tx source))) + (is (== expected-num-records (stage/queue-length source)) + "snapshots should be enqueued") + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (let [records (->> source :details (postgres/get-table tx))] + (letfn [(record-updated? [record] + (and (= "succeeded" (:snapshot_creation_job_status record)) + (not (nil? (:snapshot_creation_job_id record))) + (not (nil? (:snapshot_id record)))))] + (testing "source details got updated with correct number of snapshot jobs" + (is (= expected-num-records (count records)))) + (testing "all snapshot jobs were updated and corresponding snapshot ids were inserted" + (is (every? record-updated? records)))))) + (source/update-source! + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (source/stop-source! tx source) + (reload-source tx source))) + (is (== expected-num-records (stage/queue-length source)) + "no more snapshots should be enqueued") + (is (not (stage/done? source)) "the tdr source was done before snapshots were consumed"))))) + +(deftest test-stop-tdr-sourced + (let [source (create-tdr-source)] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (source/start-source! tx source) + (source/stop-source! tx source) + (let [source (reload-source tx source)] + (is (:stopped (reload-source tx source)) ":stopped was not written"))))) + +(defn ^:private create-tdr-snapshot-list [snapshots] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (->> {:name "TDR Snapshots" + :snapshots snapshots + :skipValidation true} + (source/create-source! tx (rand-int 1000000)) + (zipmap [:source_type :source_items]) + (source/load-source! tx)))) + +(deftest test-tdr-snapshot-list-to-edn + (let [snapshot {:name "test-snapshot-name" :id (str (UUID/randomUUID))} + source (util/to-edn (create-tdr-snapshot-list [snapshot]))] + (is (not-any? source [:id :type])) + (is (= (:snapshots source) [(:id snapshot)])) + (is (s/valid? ::source/snapshot-list-source source)))) + +(deftest test-create-covid-workload-with-empty-snapshot-list + (is (source/tdr-snappshot-list-validate-request-or-throw + {:name "TDR Snapshots" + :snapshots [testing-snapshot]}))) + +(deftest test-create-covid-workload-with-invalid-snapshot + (is (thrown-with-msg? + UserException #"Cannot access snapshot" + (source/tdr-snappshot-list-validate-request-or-throw + {:name "TDR Snapshots" + :snapshots [util/uuid-nil]})))) diff --git a/api/test/wfl/integration/workloads_test.clj b/api/test/wfl/integration/workloads_test.clj index f9b088e0a..67bd6ba71 100644 --- a/api/test/wfl/integration/workloads_test.clj +++ b/api/test/wfl/integration/workloads_test.clj @@ -20,14 +20,14 @@ "gs://fake/input" "gs://fake/output" project) workloads/create-workload!)) (create-a-bunch-copyfile-workloads! [] - (dotimes [n 2] (create-copyfile-workload! upper-project)) - (dotimes [n 2] (create-copyfile-workload! lower-project))) + (dotimes [_ 2] (create-copyfile-workload! upper-project)) + (dotimes [_ 2] (create-copyfile-workload! lower-project))) (verify-copyfile-workloads-identity [project workloads] (is (every? #(= copyfile/pipeline (:pipeline %)) workloads)) (is (every? #(= project (:project %)) workloads)))] (create-a-bunch-copyfile-workloads!) (testing "No matching returns empty list" - (is empty? (workloads/load-workloads-with-project bogus-project))) + (is (empty? (workloads/load-workloads-with-project bogus-project)))) (testing "Query project parameter is case-sensitive" (let [fetched-workloads (workloads/load-workloads-with-project upper-project)] diff --git a/api/test/wfl/system/automation_test.clj b/api/test/wfl/system/automation_test.clj index 903ce1e0d..b495ecac6 100644 --- a/api/test/wfl/system/automation_test.clj +++ b/api/test/wfl/system/automation_test.clj @@ -1,53 +1,28 @@ (ns wfl.system.automation-test - (:require [clojure.pprint :as pprint] - [clojure.test :refer [deftest is]] - [wfl.environment :as env] + (:require [clojure.test :refer [deftest is]] [wfl.tools.fixtures :as fixtures] [wfl.tools.resources :as resources] - [wfl.tools.workflows :as workflows] - [wfl.service.firecloud :as firecloud] - [wfl.util :as util] + [wfl.service.cromwell :refer [final?]] [wfl.tools.endpoints :as endpoints] [wfl.tools.workloads :as workloads])) -(defn ^:private replace-urls-with-file-ids - [file->fileid type value] - (-> (fn [type value] - (case type - ("Boolean" "Float" "Int" "Number" "String") value - "File" (file->fileid value) - (throw (ex-info "Unknown type" {:type type :value value})))) - (workflows/traverse type value))) +(def firecloud-group "workflow-launcher-dev") +(def method-configuration "cdc-covid-surveillance/sarscov2_illumina_full") +(def snapshot-column "run_date") +(def snapshot-readers ["cdc-covid-surveillance@firecloud.org"]) +(def source-dataset "cd25d59e-1451-44d0-8a24-7669edb9a8f8") +(def source-table "flowcells") +(def workspace-table "flowcell") +(def workspace-to-clone "wfl-dev/CDC_Viral_Sequencing") -(def workspace-to-clone "wfl-dev/CDC_Viral_Sequencing") -(def firecloud-group "workflow-launcher-dev") -(def snapshot-readers ["cdc-covid-surveillance@firecloud.org"]) -(def source-dataset "cd25d59e-1451-44d0-8a24-7669edb9a8f8") -(def source-table "flowcells") -(def snapshot-column "run_date") -(def source-dataset-profile "395f5921-d2d9-480d-b302-f856d787c9d9") -(def method-configuration "cdc-covid-surveillance/sarscov2_illumina_full") - -(def workspace-table "flowcell") - -(defn clone-workspace [] - (println "Cloning workspace" workspace-to-clone) - (let [clone-name (util/randomize "wfl-dev/CDC_Viral_Sequencing_GP")] - (firecloud/clone-workspace workspace-to-clone clone-name firecloud-group) - (println "Cloned new workspace " clone-name) - clone-name)) - -(defn delete-workspace [workspace] - (println "Deleting" workspace) - (firecloud/delete-workspace workspace)) - -(defn ^:private covid-workload-request [workspace] +(defn ^:private covid-workload-request "Build a covid workload request." + [workspace] {:source {:name "TDR Snapshots" :snapshots ["f9242ab8-c522-4305-966d-7c51419377ab"]} :executor {:name "Terra" :workspace workspace - :methodConfiguration "cdc-covid-surveillance/sarscov2_illumina_full" + :methodConfiguration "wfl-dev/sarscov2_illumina_full" :methodConfigurationVersion 1 :fromSource "importSnapshot"} :sink {:name "Terra Workspace" @@ -62,13 +37,14 @@ :labels ["hornet:test"]}) (deftest test-automate-sarscov2-illumina-full - (let [tdr-profile (env/getenv "WFL_TDR_DEFAULT_PROFILE")] - (fixtures/with-fixtures - [(util/bracket clone-workspace delete-workspace)] - (fn [[workspace]] - (let [workload (endpoints/create-workload - (covid-workload-request workspace))] - (endpoints/start-workload workload) - (workloads/when-done - (comp pprint/pprint endpoints/get-workflows) - workload)))))) + (fixtures/with-temporary-workspace-clone + workspace-to-clone + firecloud-group + (fn [workspace] + (let [finished? (comp final? :status) + workload (endpoints/create-workload + (covid-workload-request workspace))] + (endpoints/start-workload workload) + (workloads/when-finished + #(is (every? finished? (endpoints/get-workflows %))) + workload))))) diff --git a/api/test/wfl/system/cdc_covid19_surveillance_demo.clj b/api/test/wfl/system/cdc_covid19_surveillance_demo.clj index 55d741f86..86e659d10 100644 --- a/api/test/wfl/system/cdc_covid19_surveillance_demo.clj +++ b/api/test/wfl/system/cdc_covid19_surveillance_demo.clj @@ -1,8 +1,8 @@ (ns wfl.system.cdc-covid19-surveillance-demo - (:require [wfl.module.covid :as covid] - [wfl.service.datarepo :as datarepo] + (:require [wfl.service.datarepo :as datarepo] [wfl.service.firecloud :as firecloud] [wfl.service.rawls :as rawls] + [wfl.sink :as sink] [wfl.tools.fixtures :as fixtures] [wfl.tools.snapshots :as snapshots] [wfl.tools.resources :as resources] @@ -65,14 +65,14 @@ (defn import-snapshot-into-workspace [workspace {:keys [name id] :as _snapshot}] (println "Importing snapshot" name "into" workspace) - (let [{:keys [name] :as ref} (rawls/create-snapshot-reference workspace id name)] + (let [{:keys [name] :as ref} (rawls/create-or-get-snapshot-reference workspace id name)] (println "Created snapshot reference" name) ref)) (defn update-method-configuration [workspace {:keys [name] :as _snapshot-reference}] (println "Updating" method-configuration "to use" name) - (-> (firecloud/get-method-configuration workspace method-configuration) + (-> (firecloud/method-configuration workspace method-configuration) (assoc :dataReferenceName name) (->> (firecloud/update-method-configuration workspace method-configuration)))) @@ -93,12 +93,12 @@ (defn write-known-outputs-to-workspace [workspace] (println "Writing outputs to flowcell table in" workspace) (let [from-outputs (resources/read-resource "sarscov2_illumina_full/entity-from-outputs.edn") - pipeline (:name (firecloud/get-method-configuration workspace method-configuration)) + pipeline (:name (firecloud/method-configuration workspace method-configuration)) outputs (-> workspace-to-clone (firecloud/get-workflow-outputs well-known-submission well-known-workflow) (get-in [:tasks (keyword pipeline) :outputs]) (util/unprefix-keys (keyword (str pipeline ".")))) - attributes (covid/rename-gather outputs from-outputs) + attributes (sink/rename-gather outputs from-outputs) entity-name "test"] (rawls/batch-upsert workspace [[workspace-table entity-name attributes]]))) diff --git a/api/test/wfl/system/v1_endpoint_test.clj b/api/test/wfl/system/v1_endpoint_test.clj index cb82abc48..74d0ae7bf 100644 --- a/api/test/wfl/system/v1_endpoint_test.clj +++ b/api/test/wfl/system/v1_endpoint_test.clj @@ -1,37 +1,42 @@ (ns wfl.system.v1-endpoint-test - (:require [clojure.test :refer :all] + (:require [clojure.test :refer [deftest is testing]] [clojure.instant :as instant] [clojure.set :as set] [clojure.spec.alpha :as s] [clojure.string :as str] - [wfl.api.spec :as spec] + [wfl.api.handlers :as handlers] + [wfl.environment :as env] + [wfl.module.covid :as module] [wfl.service.cromwell :as cromwell] + [wfl.service.datarepo :as datarepo] [wfl.service.google.storage :as gcs] + [wfl.tools.datasets :as datasets] [wfl.tools.endpoints :as endpoints] [wfl.tools.fixtures :as fixtures] [wfl.tools.workloads :as workloads] [wfl.tools.resources :as resources] - [wfl.util :as util]) + [wfl.util :as util] + [clojure.data.json :as json]) (:import [clojure.lang ExceptionInfo] + [java.time.format DateTimeFormatter] [java.util UUID])) (defn make-create-workload [make-request] (fn [] (endpoints/create-workload (make-request (UUID/randomUUID))))) -(def create-aou-workload (make-create-workload workloads/aou-workload-request)) -(def create-arrays-workload (make-create-workload workloads/arrays-workload-request)) -(def create-sg-workload (make-create-workload workloads/sg-workload-request)) -(def create-wgs-workload (make-create-workload workloads/wgs-workload-request)) -(def create-xx-workload (make-create-workload workloads/xx-workload-request)) +(def create-aou-workload (make-create-workload workloads/aou-workload-request)) +(def create-sg-workload (make-create-workload workloads/sg-workload-request)) +(def create-wgs-workload (make-create-workload workloads/wgs-workload-request)) +(def create-xx-workload (make-create-workload workloads/xx-workload-request)) (defn create-copyfile-workload [src dst] (endpoints/create-workload (workloads/copyfile-workload-request src dst))) (defn ^:private verify-succeeded-workflow - [{:keys [inputs labels status updated uuid] :as _workflow}] + [{:keys [inputs status] :as workflow}] (is (map? inputs) "Every workflow should have nested inputs") - (is updated) - (is uuid) + (is (every? workflow [:updated :uuid])) + (is (not-every? workflow [:id])) (is (= "Succeeded" status))) (defn ^:private verify-succeeded-workload @@ -48,13 +53,16 @@ (format "workflows should not contain %s" key)))] (run! go! [:id :items])))) -(deftest test-oauth2-endpoint +(deftest ^:parallel test-oauth2-endpoint (testing "The `oauth2_id` endpoint indeed provides an ID" (let [response (endpoints/get-oauth2-id)] (is (= (count response) 2)) (is (some #(= % :oauth2-client-id) response)) (is (some #(str/includes? % "apps.googleusercontent.com") response))))) +(deftest ^:parallel test-version-endpoint + (is (every? (endpoints/version) [:built :commit :committed :user :version]))) + (defn ^:private test-create-workload [request] (letfn [(test! [{:keys [pipeline] :as request}] @@ -80,10 +88,6 @@ (test-create-workload (workloads/wgs-workload-request (UUID/randomUUID)))) (deftest test-create-aou-workload (test-create-workload (workloads/aou-workload-request (UUID/randomUUID)))) -(deftest ^:excluded test-create-arrays-workload - (testing "Excluded. See GH-1209" - #_(test-create-workload - (workloads/arrays-workload-request (UUID/randomUUID))))) (deftest test-create-xx-workload (test-create-workload (workloads/xx-workload-request (UUID/randomUUID)))) @@ -104,15 +108,12 @@ (is (every? :updated workflows)) (is (every? :uuid workflows))) (verify-internal-properties-removed workload) - (workloads/when-done verify-succeeded-workload workload)))) + (workloads/when-all-workflows-finish verify-succeeded-workload workload)))) (deftest ^:parallel test-start-wgs-workload (test-start-workload (create-wgs-workload))) (deftest ^:parallel test-start-aou-workload (test-start-workload (create-aou-workload))) -(deftest ^:excluded ^:parallel test-start-arrays-workload - (testing "Excluded. See GH-1209" - #_(test-start-workload (create-arrays-workload)))) (deftest ^:parallel test-start-xx-workload (test-start-workload (create-xx-workload))) (deftest ^:parallel test-start-sg-workload @@ -165,7 +166,7 @@ (is (every? :updated workflows)) (is (every? :uuid workflows))) (verify-internal-properties-removed workload) - (workloads/when-done verify-succeeded-workload workload)))) + (workloads/when-all-workflows-finish verify-succeeded-workload workload)))) (deftest ^:parallel test-exec-wgs-workload (test-exec-workload (workloads/wgs-workload-request (UUID/randomUUID)))) @@ -175,10 +176,6 @@ (set/rename-keys {:executor :cromwell})))) (deftest ^:parallel test-exec-aou-workload (test-exec-workload (workloads/aou-workload-request (UUID/randomUUID)))) -(deftest ^:excluded ^:parallel test-exec-arrays-workload - (testing "Excluded. See GH-1209." - #_(test-exec-workload - (workloads/arrays-workload-request (UUID/randomUUID))))) (deftest ^:parallel test-exec-xx-workload (test-exec-workload (workloads/xx-workload-request (UUID/randomUUID)))) (deftest ^:parallel test-exec-sg-workload @@ -193,6 +190,41 @@ (gcs/upload-file src)) (test-exec-workload (workloads/copyfile-workload-request src dst)))))) +(defn ^:private test-retry-workload + [request] + (let [workload (endpoints/create-workload request) + bad-statuses (set/difference cromwell/status? cromwell/retry-status?)] + (letfn [(check-message-and-throw [message status] + (try + (endpoints/retry-workflows workload status) + (catch Exception cause + (is (= message (-> (ex-data cause) util/response-body-json :message)) + (str "Unexpected or missing exception message for status " + status)) + (throw cause)))) + (should-throw-400 [message status] + (is (thrown-with-msg? + ExceptionInfo #"clj-http: status 400" + (check-message-and-throw message status)) + (str "Expecting 400 error for retry with status " status)))] + (testing "retry-workflows fails (400) when workflow status unsupported" + (run! (partial should-throw-400 + handlers/retry-unsupported-status-error-message) + bad-statuses)) + (testing "retry-workflows fails (400) when no workflows for supported status" + (run! (partial should-throw-400 + handlers/retry-no-workflows-error-message) + cromwell/retry-status?))))) + +(deftest ^:parallel test-retry-wgs-workload + (test-retry-workload (workloads/wgs-workload-request (UUID/randomUUID)))) +(deftest ^:parallel test-retry-aou-workload + (test-retry-workload (workloads/aou-workload-request (UUID/randomUUID)))) +(deftest ^:parallel test-retry-xx-workload + (test-retry-workload (workloads/xx-workload-request (UUID/randomUUID)))) +(deftest ^:parallel test-retry-sg-workload + (test-retry-workload (workloads/sg-workload-request (UUID/randomUUID)))) + (deftest ^:parallel test-append-to-aou-workload (let [await (partial cromwell/wait-for-workflow-complete @workloads/cromwell-url) @@ -204,7 +236,7 @@ (map (comp await :uuid)) (every? #{"Succeeded"}))) (->> (endpoints/get-workload-status (:uuid workload)) - (workloads/when-done verify-succeeded-workload))))) + (workloads/when-all-workflows-finish verify-succeeded-workload))))) (deftest test-bad-pipeline (let [request (-> (workloads/copyfile-workload-request @@ -217,8 +249,9 @@ (is (thrown-with-msg? ExceptionInfo #"clj-http: status 400" (endpoints/exec-workload request)))))) -(defn ^:private covid-workload-request [] +(defn ^:private covid-workload-request "Build a covid workload request." + [] (let [terra-ns (comp (partial str/join "/") (partial vector "wfl-dev")) workspace (terra-ns "CDC_Viral_Sequencing") source {:name "Terra DataRepo" @@ -252,8 +285,8 @@ (-> workload-request endpoints/create-workload (update :created instant/read-instant-timestamp))] - (is (s/valid? ::spec/covid-workload-request workload-request)) - (is (s/valid? ::spec/covid-workload-response workload)) + (is (s/valid? ::module/workload-request workload-request)) + (is (s/valid? ::module/workload-response workload)) (verify-internal-properties-removed workload) (is (not started)) (is (= @workloads/email creator)) @@ -263,7 +296,7 @@ (instantify-timestamps :created))] (is (not started)) (verify-internal-properties-removed response) - (is (s/valid? ::spec/covid-workload-response response)))) + (is (s/valid? ::module/workload-response response)))) (testing "/workload all" (let [{:keys [started] :as response} (-> (endpoints/get-workloads) @@ -272,19 +305,85 @@ (instantify-timestamps :created))] (is (not started)) (verify-internal-properties-removed response) - (is (s/valid? ::spec/covid-workload-response response)))) + (is (s/valid? ::module/workload-response response)))) (testing "/start covid workload" (let [{:keys [created started] :as response} (-> workload endpoints/start-workload (instantify-timestamps :created :started))] - (is (s/valid? ::spec/covid-workload-response response)) + (is (s/valid? ::module/workload-response response)) (is (inst? created)) (is (inst? started)))) (testing "/stop covid workload" (let [{:keys [created started stopped] :as response} (-> workload endpoints/stop-workload (instantify-timestamps :created :started :stopped))] - (is (s/valid? ::spec/covid-workload-response response)) + (is (s/valid? ::module/workload-response response)) (is (inst? created)) (is (inst? started)) (is (inst? stopped))))))) + +(defn ^:private verify-workflows-by-status + [workload status] + (run! #(is (= (:status %) status)) (endpoints/get-workflows workload status))) + +(deftest ^:parallel test-workflows-by-status + (testing "Get workflows by status" + (let [workload (first (endpoints/get-workloads)) + workflows (endpoints/get-workflows workload)] + (->> (map :status workflows) + (distinct) + (run! #(verify-workflows-by-status workload %)))))) + +(defn ^:private ingest-illumina-genotyping-array-inputs + "Ingest inputs for the illimina_genotyping_array pipeline into the + illimina_genotyping_array `dataset`" + [dataset] + (fixtures/with-temporary-cloud-storage-folder + fixtures/gcs-test-bucket + (fn [temp] + (let [file (str temp "inputs.json")] + (-> (resources/read-resource "illumina_genotyping_array/inputs.json") + (assoc :ingested (.format (util/utc-now) (DateTimeFormatter/ofPattern "YYYY-MM-dd'T'HH:mm:ss"))) + (json/write-str :escape-slash false) + (gcs/upload-content file)) + (datarepo/poll-job (datarepo/ingest-table dataset file "inputs")))))) + +(deftest ^:parallel test-workload-sink-outputs-to-tdr + (fixtures/with-fixtures + [(fixtures/with-temporary-dataset + (datasets/unique-dataset-request + (env/getenv "WFL_TDR_DEFAULT_PROFILE") + "illumina-genotyping-array.json")) + (fixtures/with-temporary-workspace-clone + "wfl-dev/Illumina-Genotyping-Array-Template" + "workflow-launcher-dev")] + (fn [[dataset workspace]] + (let [source {:name "Terra DataRepo" + :dataset dataset + :table "inputs" + :column "ingested" + :snapshotReaders ["hornet@firecloud.org"]} + executor {:name "Terra" + :workspace workspace + :methodConfiguration "warp-pipelines/IlluminaGenotypingArray" + :methodConfigurationVersion 1 + :fromSource "importSnapshot"} + sink {:name "Terra DataRepo" + :dataset dataset + :table "outputs" + :fromOutputs (resources/read-resource + "illumina_genotyping_array/fromOutputs.edn")} + workload (endpoints/exec-workload + (workloads/covid-workload-request source executor sink))] + (try + (ingest-illumina-genotyping-array-inputs dataset) + (is (util/poll #(seq (endpoints/get-workflows workload)) 20 100) + "a workflow should have been created") + (finally + (endpoints/stop-workload workload))) + (is (util/poll + #(-> workload :uuid endpoints/get-workload-status :finished) + 20 100) + "The workload should have finished") + (is (-> dataset (datarepo/query-table "outputs") seq) + "outputs should have been written to the dataset"))))) diff --git a/api/test/wfl/tools/endpoints.clj b/api/test/wfl/tools/endpoints.clj index a102b4406..cc0e54ab2 100644 --- a/api/test/wfl/tools/endpoints.clj +++ b/api/test/wfl/tools/endpoints.clj @@ -1,10 +1,15 @@ (ns wfl.tools.endpoints - (:require [clojure.data.json :as json] - [clojure.string :as str] - [clj-http.client :as http] - [wfl.auth :as auth] - [wfl.environment :as env] - [wfl.util :as util])) + (:require [clojure.data.json :as json] + [clojure.string :as str] + [clojure.test :refer [is]] + [clj-http.client :as http] + [reitit.coercion.spec] + [reitit.ring :as ring] + [reitit.ring.coercion :as coercion] + [ring.util.http-response :refer [ok]] + [wfl.auth :as auth] + [wfl.environment :as env] + [wfl.util :as util :refer [>>>]])) (defn ^:private wfl-url "The WFL server URL to test." @@ -15,14 +20,19 @@ (defn get-oauth2-id "Query oauth2 ID that the server is currently using" [] - (-> (http/get (wfl-url "/oauth2id")) + (-> (http/get (wfl-url "oauth2id")) util/response-body-json first)) +(defn version + "Return the WFL Server version." + [] + (-> (wfl-url "version") http/get util/response-body-json)) + (defn get-workload-status "Query v1 api for the status of the workload with UUID" [uuid] - (-> (wfl-url "/api/v1/workload") + (-> (wfl-url "api/v1/workload") (http/get {:headers (auth/get-auth-header) :query-params {:uuid uuid}}) util/response-body-json first)) @@ -30,21 +40,22 @@ (defn get-workloads "Query v1 api for all workloads" [] - (-> (wfl-url "/api/v1/workload") + (-> (wfl-url "api/v1/workload") (http/get {:headers (auth/get-auth-header)}) util/response-body-json)) (defn get-workflows "Query v1 api for all workflows managed by `_workload`." - [{:keys [uuid] :as _workload}] - (-> (wfl-url "/api/v1/workload/" uuid "/workflows") - (http/get {:headers (auth/get-auth-header)}) + [{:keys [uuid] :as _workload} & [status]] + (-> (wfl-url "api/v1/workload" uuid "workflows") + (http/get (merge {:headers (auth/get-auth-header)} + (when status {:query-params {:status status}}))) util/response-body-json)) (defn create-workload "Create workload defined by WORKLOAD" [workload] - (-> (wfl-url "/api/v1/create") + (-> (wfl-url "api/v1/create") (http/post {:headers (auth/get-auth-header) :content-type :application/json :body (json/write-str workload :escape-slash false)}) @@ -55,7 +66,7 @@ [workload] (let [payload (-> (select-keys workload [:uuid]) (json/write-str :escape-slash false))] - (-> (wfl-url "/api/v1/start") + (-> (wfl-url "api/v1/start") (http/post {:headers (auth/get-auth-header) :content-type :application/json :body payload}) @@ -65,7 +76,7 @@ "Stop processing WORKLOAD. WORKLOAD must be known to the server." [workload] (let [payload (json/write-str (select-keys workload [:uuid]))] - (-> (wfl-url "/api/v1/stop") + (-> (wfl-url "api/v1/stop") (http/post {:headers (auth/get-auth-header) :content-type :application/json :body payload}) @@ -77,7 +88,7 @@ (let [payload (-> (select-keys workload [:uuid]) (assoc :notifications samples) (json/write-str :escape-slash false))] - (-> (wfl-url "/api/v1/append_to_aou") + (-> (wfl-url "api/v1/append_to_aou") (http/post {:headers (auth/get-auth-header) :content-type :application/json :body payload}) @@ -87,8 +98,42 @@ "Create and start workload defined by `workload-request`." [workload-request] (let [payload (json/write-str workload-request :escape-slash false)] - (-> (wfl-url "/api/v1/exec") + (-> (wfl-url "api/v1/exec") (http/post {:headers (auth/get-auth-header) :content-type :application/json :body payload}) util/response-body-json))) + +(defn retry-workflows + "Retry the workflows in `_workload` by `status`." + [{:keys [uuid] :as _workload} status] + (-> (wfl-url "api/v1/workload" uuid "retry") + (http/post {:headers (auth/get-auth-header) + :content-type :application/json + :body (json/write-str {:status status})}) + util/response-body-json)) + +(defn coercion-tester + "Test utility to test clojure specs with reitit coercion. Returns a function + that verifies its input can be coerced to `request-spec`. Optionally verifies + that the result of applying `transform` to its argument can be coerced to + `response-spec`." + [request-spec & [response-spec transform]] + (let [app + (ring/ring-handler + (ring/router + [["/test" {:post {:parameters {:body request-spec} + :responses {200 {:body (or response-spec nil?)}} + :handler (>>> :body-params + (or transform (constantly nil)) + ok)}}]] + {:data {:coercion reitit.coercion.spec/coercion + :middleware [coercion/coerce-exceptions-middleware + coercion/coerce-request-middleware + coercion/coerce-response-middleware]}}))] + (fn [request] + (let [{:keys [status body] :as _response} + (app {:request-method :post + :uri "/test" + :body-params request})] + (is (== 200 status) (pr-str body)))))) diff --git a/api/test/wfl/tools/fixtures.clj b/api/test/wfl/tools/fixtures.clj index 629ac7729..40c9c3559 100644 --- a/api/test/wfl/tools/fixtures.clj +++ b/api/test/wfl/tools/fixtures.clj @@ -1,13 +1,15 @@ (ns wfl.tools.fixtures - (:require [wfl.service.datarepo :as datarepo] + (:require [clojure.java.jdbc] + [wfl.environment :as env] + [wfl.jdbc :as jdbc] + [wfl.log :as log] + [wfl.service.datarepo :as datarepo] + [wfl.service.firecloud :as firecloud] [wfl.service.google.pubsub :as pubsub] [wfl.service.google.storage :as gcs] [wfl.service.postgres :as postgres] [wfl.tools.liquibase :as liquibase] - [wfl.jdbc :as jdbc] - [wfl.util :as util] - [wfl.environment :as env] - [wfl.service.firecloud :as firecloud]) + [wfl.util :as util]) (:import [java.nio.file.attribute FileAttribute] [java.nio.file Files] [java.util UUID] @@ -208,6 +210,17 @@ ([f] (with-temporary-workspace "wfl-dev/test-workspace" "workflow-launcher-dev" f))) +(defn with-temporary-workspace-clone + "Clone a temporary copy of `workspace-to-clone`, grant access to + `firecloud-group` and call `use-workspace` with the clone. The workspace will + be destroyed when `use-workspace` returns." + [workspace-to-clone firecloud-group use-workspace] + (letfn [(clone-workspace [] + (let [clone-name (util/randomize workspace-to-clone)] + (firecloud/clone-workspace workspace-to-clone clone-name firecloud-group) + clone-name))] + (util/bracket clone-workspace firecloud/delete-workspace use-workspace))) + (defn with-temporary-environment "Temporarily override the environment with the key-value mapping in `env`. The original environment will be restored after `f` returns. No guarantees @@ -235,3 +248,16 @@ "Adapter for clojure.test/use-fixtures" [env] (partial with-temporary-environment env)) + +(defmacro bind-fixture + "Returns a closure that can be used with clojure.test/use-fixtures in which + the ^:dynamic `var` is bound to the resource created by applying + `with-fixture` to its `arguments`." + [var with-fixture & arguments] + `(fn [f#] + (log/info (format "Setting up %s..." '~with-fixture)) + (~with-fixture + ~@arguments + #(binding [~var %] + (try (f#) + (finally (log/info (format "Tearing down %s..." '~with-fixture)))))))) diff --git a/api/test/wfl/tools/parallel_runner.clj b/api/test/wfl/tools/parallel_runner.clj index 5e478ebb0..29566dadc 100644 --- a/api/test/wfl/tools/parallel_runner.clj +++ b/api/test/wfl/tools/parallel_runner.clj @@ -1,7 +1,6 @@ (ns wfl.tools.parallel-runner (:require [clojure.test :as test] - [clojure.tools.logging :as log] - [clojure.tools.logging.impl :refer [disabled-logger-factory]]) + [wfl.log :as log]) (:import (java.io StringWriter))) (defn -main @@ -11,12 +10,12 @@ [& namespaces] (let [symbols (map symbol namespaces) counters (ref test/*initial-report-counters*)] - (letfn [(run-test! [test] + (letfn [(run-test! [a-test] (binding [*out* (StringWriter.) test/*test-out* (StringWriter.) test/*report-counters* counters - log/*logger-factory* disabled-logger-factory] - (test) + log/*logger* log/disabled-logger] + (a-test) (str test/*test-out*)))] (run! use symbols) (let [{parallel true, sequential false} @@ -28,4 +27,4 @@ results (concat (map run-test! sequential) (map deref futures))] (run! println (filter not-empty results)) (test/do-report (assoc @counters :type :summary)) - (System/exit (if (test/successful? @counters) 0 1)))))) \ No newline at end of file + (System/exit (if (test/successful? @counters) 0 1)))))) diff --git a/api/test/wfl/tools/queues.clj b/api/test/wfl/tools/queues.clj new file mode 100644 index 000000000..bb7f2f5c5 --- /dev/null +++ b/api/test/wfl/tools/queues.clj @@ -0,0 +1,13 @@ +(ns wfl.tools.queues + (:require [wfl.stage :as stage]) + (:import [java.util ArrayDeque])) + +(def ^:private testing-queue-type "TestQueue") + +(defn make-queue-from-list [items] + {:type testing-queue-type :queue (ArrayDeque. items)}) + +(defmethod stage/peek-queue testing-queue-type [q] (-> q :queue .peekFirst)) +(defmethod stage/pop-queue! testing-queue-type [q] (-> q :queue .removeFirst)) +(defmethod stage/queue-length testing-queue-type [q] (-> q :queue .size)) +(defmethod stage/done? testing-queue-type [q] (-> q :queue .isEmpty)) diff --git a/api/test/wfl/tools/snapshots.clj b/api/test/wfl/tools/snapshots.clj index 7ce508279..185e25c5d 100644 --- a/api/test/wfl/tools/snapshots.clj +++ b/api/test/wfl/tools/snapshots.clj @@ -1,6 +1,5 @@ (ns wfl.tools.snapshots - (:require [clojure.test :refer :all] - [wfl.service.datarepo :as datarepo] + (:require [wfl.service.datarepo :as datarepo] [wfl.util :as util])) (defn unique-snapshot-request diff --git a/api/test/wfl/tools/workflows.clj b/api/test/wfl/tools/workflows.clj index 751a2d874..97468b4e0 100644 --- a/api/test/wfl/tools/workflows.clj +++ b/api/test/wfl/tools/workflows.clj @@ -2,16 +2,16 @@ (:require [clojure.set :as set])) (defn make-object-type - "Collect `parameters` description into an \"Object\" type." - [parameters] - (->> parameters - (map #(set/rename-keys % {:name :fieldName :valueType :fieldType})) + "Transform WDL inputs or outputs `description` into a `type` for use with + `transform` and `foldl`." + [description] + (->> description + (mapv #(set/rename-keys % {:name :fieldName :valueType :fieldType})) (assoc {:typeName "Object"} :objectFieldTypes))) -(defn ^:private make-type-environment [{:keys [objectFieldTypes] :as _object}] - (let [name->type (into {} - (for [{:keys [fieldName fieldType]} objectFieldTypes] - [(keyword fieldName) fieldType]))] +(defn ^:private make-type-environment [{:keys [objectFieldTypes] :as _type}] + (let [collect (juxt (comp keyword :fieldName) :fieldType) + name->type (into {} (map collect objectFieldTypes))] (fn [varname] (or (name->type varname) (throw (ex-info "No type definition found for name." @@ -19,9 +19,9 @@ :environment name->type})))))) (defn traverse - "Use the workflow `type` to traverse the `object`, calling `f` on the values - with primitive types." - [f type object] + "Use the WDL `type` to traverse the `object`, calling `f` on the + primitive objects in the object." + [f [type object]] ((fn go [type value] (case (:typeName type) "Array" @@ -38,13 +38,13 @@ "Pair" (let [ts (mapv (:pairType type) [:leftType :rightType])] (map go ts value)) - (f (:typeName type) value))) + (f [(:typeName type) value]))) type object)) (defn foldl - "Use the workflow `type` to left-fold the `object`, calling `f` on the values - with primitive types with the current state." - [f init type object] + "Reduce the WDL [type value] `_object` starting from `init` while preserving + the types of intermediate reductions." + [f init [type value :as _object]] ((fn go [state type value] (case (:typeName type) "Array" @@ -52,20 +52,23 @@ (reduce #(go %1 array-type %2) state value)) "Map" (let [{:keys [keyType valueType]} (:mapType type)] - (reduce-kv #(-> (go %1 keyType %2) (go valueType %3)) state value)) + (reduce-kv #(-> %1 (go keyType %2) (go valueType %3)) state value)) "Object" (let [name->type (make-type-environment type)] (reduce-kv #(go %1 (name->type %2) %3) state value)) "Optional" (if value (go state (:optionalType type) value) state) "Pair" - (let [{:keys [leftType rightType]} (:pairType type)] - (-> (go state leftType (first value)) - (go rightType (second value)))) - (f state (:typeName type) value))) - init type object)) + (let [{:keys [leftType rightType]} (:pairType type) + [leftValue rightValue] value] + (-> state (go leftType leftValue) (go rightType rightValue))) + (f state [(:typeName type) value]))) + init type value)) -(defn get-files [type value] +(defn get-files "Return the unique set of objects in `value` of WDL type `File`." - (letfn [(f [files type object] (if (= "File" type) (conj files object) files))] - (foldl f #{} type value))) + [[_type _value :as object]] + (letfn [(f [files [type value]] (case type + "File" (conj files value) + files))] + (foldl f #{} object))) diff --git a/api/test/wfl/tools/workloads.clj b/api/test/wfl/tools/workloads.clj index 5ae727026..38d5127bf 100644 --- a/api/test/wfl/tools/workloads.clj +++ b/api/test/wfl/tools/workloads.clj @@ -1,11 +1,10 @@ (ns wfl.tools.workloads (:require [clojure.string :as str] - [clojure.tools.logging.readable :as log] + [wfl.api.workloads] [wfl.auth :as auth] [wfl.environment :as env] [wfl.jdbc :as jdbc] [wfl.module.aou :as aou] - [wfl.module.arrays :as arrays] [wfl.module.copyfile :as cp] [wfl.module.sg :as sg] [wfl.module.wgs :as wgs] @@ -15,9 +14,8 @@ [wfl.service.google.storage :as gcs] [wfl.service.postgres :as postgres] [wfl.tools.endpoints :as endpoints] - [wfl.util :as util :refer [shell!]]) + [wfl.util :as util]) (:import [java.time OffsetDateTime] - [java.util.concurrent TimeoutException] [java.util UUID])) (def clio-url (delay (env/getenv "WFL_CLIO_URL"))) @@ -44,8 +42,8 @@ :input_cram (str input-folder "NA12878_PLUMBING.cram")})) (defn wgs-workload-request - [identifier] "A whole genome sequencing workload used for testing." + [identifier] {:executor @cromwell-url :output (str "gs://broad-gotc-dev-wfl-ptc-test-outputs/wgs-test-output/" identifier) @@ -106,15 +104,6 @@ {:entity-name "200598830050_R07C01-1" :entity-type "sample"}) -(defn arrays-workload-request - [identifier] - {:executor (env/getenv "WFL_FIRECLOUD_URL") - :output (str "gs://broad-gotc-dev-wfl-ptc-test-outputs/arrays-test-output/" - identifier) - :pipeline arrays/pipeline - :project "general-dev-billing-account/arrays" - :items [{:inputs arrays-sample-terra}]}) - (defn copyfile-workload-request "Make a workload to copy a file from SRC to DST" [src dst] @@ -155,8 +144,8 @@ (covid-workload-request {} {} {}))) (defn xx-workload-request - [identifier] "A whole genome sequencing workload used for testing." + [identifier] {:executor @cromwell-url :output (str/join "/" ["gs://broad-gotc-dev-wfl-ptc-test-outputs" "xx-test-output" identifier]) @@ -240,72 +229,63 @@ :items [{:inputs {:base_file_name sample_alias :contamination_vcf vcf - :contamination_vcf_index (str vcf ".tbi") + :contamination_vcf_index (str vcf ".tbi") :cram_ref_fasta fasta :cram_ref_fasta_index (str fasta ".fai") :dbsnp_vcf dbsnp :dbsnp_vcf_index (str dbsnp ".tbi") :input_cram cram_path}}]})) -(defn when-done - "Call `done!` when all workflows in the `workload` have finished processing." - [done! {:keys [uuid] :as workload}] - (letfn [(finished? [{:keys [status] :as workflow}] - (let [skipped? #(-> % :uuid util/uuid-nil?)] - (or (skipped? workflow) ((set cromwell/final-statuses) status))))] - (let [interval 60 - timeout 4800] ; 80 minutes - (loop [elapsed 0 wl workload] - (when (> elapsed timeout) - (throw (TimeoutException. - (format "Timed out waiting for workload %s" uuid)))) - (if (or (:finished workload) (every? finished? (endpoints/get-workflows wl))) - (done! wl) - (do - (log/infof "Waiting for workload %s to complete" uuid) - (util/sleep-seconds interval) - (recur (+ elapsed interval) - (endpoints/get-workload-status uuid)))))))) - -(defn create-workload! [workload-request] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (wfl.api.workloads/create-workload! tx workload-request))) - -(defn start-workload! [workload] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (wfl.api.workloads/start-workload! tx workload))) - -(defn stop-workload! [workload] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (wfl.api.workloads/stop-workload! tx workload))) +(def ^:private polling-interval-seconds 60) +(def ^:private max-polling-attempts 120) -(defn execute-workload! [workload-request] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (wfl.api.workloads/execute-workload! tx workload-request))) +(defn when-finished + "Call `done!` when the `workload` is `:finished`." + [done! {:keys [uuid] :as _workload}] + (done! + (util/poll + #(let [workload (endpoints/get-workload-status uuid)] + (when (:finished workload) + workload)) + polling-interval-seconds + max-polling-attempts))) -(defn update-workload! [workload] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (wfl.api.workloads/update-workload! tx workload))) - -(defn workflows [workload] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (wfl.api.workloads/workflows tx workload))) +(defn when-all-workflows-finish + "Call `done!` when all workflows in the `workload` have finished processing." + [done! {:keys [uuid] :as workload}] + (done! + (util/poll + #(when (every? cromwell/final? (endpoints/get-workflows workload)) + (endpoints/get-workload-status uuid)) + polling-interval-seconds + max-polling-attempts))) -(defn load-workload-for-uuid [uuid] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (wfl.api.workloads/load-workload-for-uuid tx uuid))) +(defn evalT + "Evaluate `operation` in the context of a database transaction where + `operation` is a function that takes a database transaction as its first + argument followed by at least one additional argument. When no additional + arguments are supplied, returns a closure that evaluates `operation` with its + arguments in the context of a database transaction." + ([operation first & rest] + (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] + (apply operation (conj rest first tx)))) + ([operation] + (partial evalT operation))) -(defn load-workload-for-id [id] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (wfl.api.workloads/load-workload-for-id tx id))) +(def create-workload! (evalT wfl.api.workloads/create-workload!)) +(def start-workload! (evalT wfl.api.workloads/start-workload!)) +(def stop-workload! (evalT wfl.api.workloads/stop-workload!)) +(def execute-workload! (evalT wfl.api.workloads/execute-workload!)) +(def update-workload! (evalT wfl.api.workloads/update-workload!)) +(def workflows (evalT wfl.api.workloads/workflows)) +(def workflows-by-status (evalT wfl.api.workloads/workflows-by-status)) -(defn load-workloads-with-project [project] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (wfl.api.workloads/load-workloads-with-project tx project))) +(defn retry [& params] (apply wfl.api.workloads/retry params)) -(defn append-to-workload! [samples workload] - (jdbc/with-db-transaction [tx (postgres/wfl-db-config)] - (aou/append-to-workload! tx samples workload))) +(def load-workload-for-uuid (evalT wfl.api.workloads/load-workload-for-uuid)) +(def load-workload-for-id (evalT wfl.api.workloads/load-workload-for-id)) +(def load-workloads-with-project (evalT wfl.api.workloads/load-workloads-with-project)) +(def append-to-workload! (evalT aou/append-to-workload!)) (defmulti postcheck "Implement this to validate `workload` after all workflows complete." diff --git a/api/test/wfl/unit/cromwell_test.clj b/api/test/wfl/unit/cromwell_test.clj index 3c388693f..702a21ac2 100644 --- a/api/test/wfl/unit/cromwell_test.clj +++ b/api/test/wfl/unit/cromwell_test.clj @@ -1,5 +1,5 @@ (ns wfl.unit.cromwell-test - (:require [clojure.test :refer [deftest testing is]] + (:require [clojure.test :refer [deftest is]] [wfl.service.cromwell :as cromwell])) (def a-wdl {:release "foo" @@ -17,11 +17,11 @@ "https://cdn.jsdelivr.net/gh/user/repo@release/path")) (deftest test-wf-labels - (is (select-keys (cromwell/make-workflow-labels a-wdl) - [:wfl-wdl :wfl-wdl-version]) - {:wfl-wdl "baz.wdl" - :wfl-wdl-version "foo"}) - (is (select-keys (cromwell/make-workflow-labels b-wdl) - [:wfl-wdl :wfl-wdl-version]) - {:wfl-wdl "path" - :wfl-wdl-version "release"})) + (is (= (select-keys (cromwell/make-workflow-labels a-wdl) + [:wfl-wdl :wfl-wdl-version]) + {:wfl-wdl "baz.wdl" + :wfl-wdl-version "foo"})) + (is (= (select-keys (cromwell/make-workflow-labels b-wdl) + [:wfl-wdl :wfl-wdl-version]) + {:wfl-wdl "path" + :wfl-wdl-version "release"}))) diff --git a/api/test/wfl/unit/google/bigquery_test.clj b/api/test/wfl/unit/google/bigquery_test.clj index 3a0be47dc..cdfb02d67 100644 --- a/api/test/wfl/unit/google/bigquery_test.clj +++ b/api/test/wfl/unit/google/bigquery_test.clj @@ -1,6 +1,6 @@ (ns wfl.unit.google.bigquery-test - (:require [clojure.test :refer :all] - [clojure.data.csv :as csv] + (:require [clojure.test :refer [deftest is]] + [clojure.data.csv :as csv] [wfl.service.google.bigquery :as bigquery])) ;; mock output from bigquery/query-sync diff --git a/api/test/wfl/unit/logging_test.clj b/api/test/wfl/unit/logging_test.clj index 6e9876626..f0004cf62 100644 --- a/api/test/wfl/unit/logging_test.clj +++ b/api/test/wfl/unit/logging_test.clj @@ -1,40 +1,42 @@ (ns wfl.unit.logging-test "Test that logging is functional (since there's several layers of delegation)" (:require - [clojure.tools.logging :as log] - [clojure.tools.logging.test :refer [logged? with-log]] - [clojure.test :refer [is deftest testing]])) + [wfl.log :as log] + [clojure.data.json :refer [read-str]] + [clojure.test :refer [is deftest testing]] + [clojure.string :refer [upper-case blank?]]) + (:import java.util.regex.Pattern)) + +(defmulti check-message? + (fn [expected actual] + [(type expected) (type actual)])) + +(defmethod check-message? :default + [expected actual] + (= expected actual)) +(defmethod check-message? [Pattern String] + [expected actual] + (re-find expected actual)) + +(defn logged? + "Test that the logs worked" + [result severity test] + (let [json (read-str result)] + (and (= (get-in json ["severity"]) (-> severity name upper-case)) + (boolean (check-message? test (get-in json ["message"])))))) ;; Useful information on this file is in docs/logging.md#Testing (deftest level-test (testing "basic logging levels" - (with-log - (log/info "Hello World!") - (is (logged? 'wfl.unit.logging-test :info "Hello World!")) - (log/warn "This is a warning") - (is (logged? 'wfl.unit.logging-test :warn "This is a warning")) - (log/error "and this is an error") - (is (logged? 'wfl.unit.logging-test :error "and this is an error")) - (log/debug "This is just a debugging message") - (is (logged? 'wfl.unit.logging-test :debug "This is just a debugging message")) - (log/trace "This is a trace") - (is (logged? 'wfl.unit.logging-test :trace "This is a trace"))))) - -(deftest format-test - (testing "formatting (more for demonstration than assurance)" - (with-log - (log/info "abc" 6 "abcd") - (is (logged? 'wfl.unit.logging-test :info "abc 6 abcd")) - (log/infof "%s %s" "abc" 123) - (is (logged? 'wfl.unit.logging-test :info "abc 123"))))) + (with-redefs [log/logging-level (atom :debug)] + (is (logged? (with-out-str (log/info "Hello World!")) :info "Hello World!")) + (is (logged? (with-out-str (log/warn "This is a warning")) :warning "This is a warning")) + (is (logged? (with-out-str (log/error "This is an error")) :error "This is an error")) + (is (logged? (with-out-str (log/debug "This is just a debugging message")) :debug "This is just a debugging message"))))) -(deftest exception-test - (testing "exception output" - (with-log - (try - (int "not an int") - (catch Exception e - (log/error e "Oops!")) - (finally - (is (logged? 'wfl.unit.logging-test :error [Throwable #"cannot be cast"] #"Oops!"))))))) \ No newline at end of file +(deftest severity-level-filtering-test + (testing "test current logging level correctly ignores lesser levels" + (with-redefs [log/logging-level (atom :info)] + (is (blank? (with-out-str (log/debug "Debug Message")))) + (is (logged? (with-out-str (log/info "Info Message")) :info "Info Message"))))) diff --git a/api/test/wfl/unit/mime_type_test.clj b/api/test/wfl/unit/mime_type_test.clj index 23591851f..7a7dcce8a 100644 --- a/api/test/wfl/unit/mime_type_test.clj +++ b/api/test/wfl/unit/mime_type_test.clj @@ -1,5 +1,5 @@ (ns wfl.unit.mime-type-test - (:require [clojure.test :refer [deftest is testing]] + (:require [clojure.test :refer [deftest is]] [wfl.mime-type :as mime-type] [wfl.tools.resources :as resources] [wfl.tools.workflows :as workflows])) @@ -27,7 +27,7 @@ (-> "sarscov2_illumina_full.edn" resources/read-resource :outputs)]]] (doseq [[values description] cases] (let [type (workflows/make-object-type description)] - (doseq [filename (workflows/get-files type values)] + (doseq [filename (workflows/get-files [type values])] (let [ext (mime-type/ext-mime-type-no-default filename)] (is (or (some? ext) (exclude? filename)) (str filename " does not have a mime-type")))))))) diff --git a/api/test/wfl/unit/modules/aou_test.clj b/api/test/wfl/unit/modules/aou_test.clj index be853a293..d80755b2b 100644 --- a/api/test/wfl/unit/modules/aou_test.clj +++ b/api/test/wfl/unit/modules/aou_test.clj @@ -1,6 +1,6 @@ (ns wfl.unit.modules.aou-test - (:require [clojure.test :refer :all] - [clojure.set :as set] + (:require [clojure.test :refer [deftest is testing]] + [clojure.set :as set] [wfl.module.aou :as aou])) (def ^:private cromwell-url diff --git a/api/test/wfl/unit/modules/covid_test.clj b/api/test/wfl/unit/modules/covid_test.clj index 2962822c2..e8ac55018 100644 --- a/api/test/wfl/unit/modules/covid_test.clj +++ b/api/test/wfl/unit/modules/covid_test.clj @@ -1,28 +1,12 @@ (ns wfl.unit.modules.covid-test (:require [clojure.spec.alpha :as s] - [clojure.test :refer :all] - [wfl.api.spec :as spec] - [wfl.module.covid :as covid] + [clojure.test :refer [deftest is testing]] [wfl.service.datarepo :as datarepo] - [wfl.tools.resources :as resources] + [wfl.source :as source] [wfl.tools.workloads :as workloads]) (:import [java.time OffsetDateTime ZoneId] [java.lang Math])) -(deftest test-rename-gather - (let [inputs (resources/read-resource "sarscov2_illumina_full/inputs.edn")] - (is (= {:workspace_name "SARSCoV2-Illumina-Full"} - (covid/rename-gather inputs {:workspace_name "$SARSCoV2-Illumina-Full"}))) - (is (= {:instrument_model "Illumina NovaSeq 6000"} - (covid/rename-gather inputs {:instrument_model "instrument_model"}))) - (is (= {:extra ["broad_gcid-srv"]} - (covid/rename-gather inputs {:extra ["package_genbank_ftp_submission.account_name"]}))) - (is (= {:extra {:account_name "broad_gcid-srv" :workspace_name "SARSCoV2-Illumina-Full"}} - (covid/rename-gather - inputs - {:extra {:account_name "package_genbank_ftp_submission.account_name" - :workspace_name "$SARSCoV2-Illumina-Full"}}))))) - (def ^:private readers-list ["hornet@firecloud.org"]) ;; Snapshot creation mock @@ -44,7 +28,7 @@ shards->snapshot-requests (with-redefs-fn {#'datarepo/create-snapshot-job mock-create-snapshot-job} - #(vec (#'covid/create-snapshots source now-obj row-ids)))] + #(vec (#'source/create-snapshots source now-obj row-ids)))] (testing "snapshot requests are properly partitioned and made unique" (is (= expected-num-shards (count shards->snapshot-requests)) "requests are not partitioned correctly!") @@ -52,8 +36,8 @@ "requests are not made unique!")))) (deftest test-tdr-source-spec - (let [valid? (partial s/valid? ::spec/tdr-source) + (let [valid? (partial s/valid? ::source/tdr-source) {:keys [source]} (workloads/covid-workload-request)] - (is (valid? source) (s/explain-str ::spec/tdr-source source)) + (is (valid? source) (s/explain-str ::source/tdr-source source)) (is (not (valid? (assoc source :snapshotReaders ["geoff"]))) "snapshotReaders should be a list of email addresses"))) diff --git a/api/test/wfl/unit/modules/wgs_test.clj b/api/test/wfl/unit/modules/wgs_test.clj index c73014b92..87fdd625d 100644 --- a/api/test/wfl/unit/modules/wgs_test.clj +++ b/api/test/wfl/unit/modules/wgs_test.clj @@ -1,5 +1,5 @@ (ns wfl.unit.modules.wgs-test - (:require [clojure.test :refer :all] + (:require [clojure.test :refer [deftest is]] [wfl.module.wgs :as wgs])) (def ^:private output-url "gs://fake-output-bucket/") diff --git a/api/test/wfl/unit/modules/xx_test.clj b/api/test/wfl/unit/modules/xx_test.clj index c951d4ba3..d0c4b3896 100644 --- a/api/test/wfl/unit/modules/xx_test.clj +++ b/api/test/wfl/unit/modules/xx_test.clj @@ -1,5 +1,5 @@ (ns wfl.unit.modules.xx-test - (:require [clojure.test :refer :all] + (:require [clojure.test :refer [deftest is]] [wfl.module.xx :as xx])) (def ^:private output-url "gs://fake-output-bucket/") diff --git a/api/test/wfl/unit/sink_test.clj b/api/test/wfl/unit/sink_test.clj new file mode 100644 index 000000000..00c16067b --- /dev/null +++ b/api/test/wfl/unit/sink_test.clj @@ -0,0 +1,41 @@ +(ns wfl.unit.sink-test + (:require [clojure.test :refer [deftest is]] + [wfl.sink :as sink] + [wfl.tools.endpoints :refer [coercion-tester]] + [wfl.tools.resources :as resources] + [wfl.util :refer [uuid-nil]])) + +(deftest test-rename-gather + (let [inputs (resources/read-resource "sarscov2_illumina_full/inputs.edn")] + (is (= {:workspace_name "SARSCoV2-Illumina-Full"} + (sink/rename-gather inputs {:workspace_name "$SARSCoV2-Illumina-Full"}))) + (is (= {:instrument_model "Illumina NovaSeq 6000"} + (sink/rename-gather inputs {:instrument_model "instrument_model"}))) + (is (= {:extra ["broad_gcid-srv"]} + (sink/rename-gather inputs {:extra ["package_genbank_ftp_submission.account_name"]}))) + (is (= {:extra {:account_name "broad_gcid-srv" :workspace_name "SARSCoV2-Illumina-Full"}} + (sink/rename-gather + inputs + {:extra {:account_name "package_genbank_ftp_submission.account_name" + :workspace_name "$SARSCoV2-Illumina-Full"}}))))) + +(def ^:private workspace-sink-request + {:name @#'sink/terra-workspace-sink-name + :workspace "namespace/name" + :entityType "tablename" + :identifier "sample_id" + :fromOutputs {}}) + +(def ^:private datarepo-sink-request + {:name @#'sink/datarepo-sink-name + :dataset (str uuid-nil) + :table "tablename" + :fromOutputs {}}) + +(deftest test-workspace-sink-request-coercion + (let [test! (coercion-tester ::sink/sink)] + (test! workspace-sink-request))) + +(deftest test-datarepo-sink-request-coercion + (let [test! (coercion-tester ::sink/sink)] + (test! datarepo-sink-request))) diff --git a/api/test/wfl/unit/spec_test.clj b/api/test/wfl/unit/spec_test.clj index f5d24a5a5..4653acb31 100644 --- a/api/test/wfl/unit/spec_test.clj +++ b/api/test/wfl/unit/spec_test.clj @@ -2,7 +2,8 @@ (:require [clojure.spec.alpha :as s] [clojure.test :refer [deftest testing is]] [wfl.api.spec :as spec] - [wfl.tools.workloads :as workloads]) + [wfl.tools.workloads :as workloads] + [wfl.module.all :as all]) (:import [java.util UUID])) (deftest request-spec-test @@ -43,7 +44,7 @@ [invalid? ":label"] [invalid? "label"] [invalid? "test:label:bad"]]] - (is (test? ::spec/labels [label]) (format "failed: %s" label))))) + (is (test? ::all/labels [label]) (format "failed: %s" label))))) (deftest test-watchers-spec (let [valid? s/valid? @@ -53,4 +54,4 @@ ;; From tbl: https://www.netmeister.org/blog/email.html [valid? "'*+-/=?^_`{|}~#$@[IPv6:2001:470:30:84:e276:63ff:fe72:3900]"] [invalid? "foo"]]] - (is (test? ::spec/watchers [email]) (format "failed: %s" email))))) + (is (test? ::all/watchers [email]) (format "failed: %s" email))))) diff --git a/api/test/wfl/unit/workflows_test.clj b/api/test/wfl/unit/workflows_test.clj index ae35cabc0..c1933bc6f 100644 --- a/api/test/wfl/unit/workflows_test.clj +++ b/api/test/wfl/unit/workflows_test.clj @@ -1,19 +1,19 @@ (ns wfl.unit.workflows-test - (:require [clojure.test :refer :all] - [wfl.tools.workflows :as workflows] + (:require [clojure.test :refer [deftest is testing]] [wfl.tools.resources :as resources] - [wfl.util :as util]) + [wfl.tools.workflows :as workflows] + [wfl.util :as util]) (:import (clojure.lang ExceptionInfo))) -(defn ^:private filtering-type [test? type object] - (letfn [(f [vs t v] (if (test? t) (conj vs v) vs))] - (workflows/foldl f #{} type object))) +(defn ^:private collect-values-where-type [test? object] + (letfn [(f [vs [t v]] (if (test? t) (conj vs v) vs))] + (workflows/foldl f #{} object))) -(defn ^:private get-primitives [type object] - (letfn [(f [ts t _] (conj ts t))] - (workflows/foldl f #{} type object))) +(def ^:private collect-primitives + (letfn [(f [ts [t _]] (conj ts t))] + (partial workflows/foldl f #{}))) -(defn ^:private lift-value [f] (fn [_ value] (f value))) +(defn ^:private lift-value [f] (comp f second)) (def ^:private vectorize (partial workflows/traverse (lift-value vector))) (defn ^:private make-output-type [resource-file] @@ -28,12 +28,12 @@ (is (thrown-with-msg? ExceptionInfo #"No type definition found for name\." - (workflows/foldl (constantly nil) nil type {:no-such-name nil})))) + (workflows/foldl (constantly nil) nil [type {:no-such-name nil}])))) (testing "traverse" (is (thrown-with-msg? ExceptionInfo #"No type definition found for name\." - (workflows/traverse (constantly nil) type {:no-such-name nil})))))) + (workflows/traverse (constantly nil) [type {:no-such-name nil}])))))) (deftest test-primitive-types (let [type (make-output-type "primitive.edn") @@ -44,64 +44,63 @@ :outstring "Hello, World!"}] (testing "foldl" (is (= #{"Boolean" "File" "Float" "Int" "String"} - (get-primitives type outputs))) + (collect-primitives [type outputs]))) (is (= #{"Boolean" "File" "Float" "Int"} - (get-primitives type (dissoc outputs :outstring)))) - (is (= #{"lolcats.txt"} (workflows/get-files type outputs)))) + (collect-primitives [type (dissoc outputs :outstring)]))) + (is (= #{"lolcats.txt"} (workflows/get-files [type outputs])))) (testing "traverse" - (is (= (util/map-vals vector outputs) (vectorize type outputs)))))) + (is (= (util/map-vals vector outputs) (vectorize [type outputs])))))) (deftest test-array-types - (let [type (make-output-type "compound.edn") - outputs {:outarray ["clojure" "is" "fun"]}] - (testing "foldl" - (is (= (:outarray outputs) - (workflows/foldl #(conj %1 %3) [] type outputs)))) - (testing "traverse" - (is (= (util/map-vals #(map vector %) outputs) - (vectorize type outputs)))))) + (letfn [(typeless [p1 [_p2 p3]] (conj p1 p3))] + (let [type (make-output-type "compound.edn") + outputs {:outarray ["clojure" "is" "fun"]}] + (testing "foldl" + (is (= (:outarray outputs) + (workflows/foldl typeless [] [type outputs])))) + (testing "traverse" + (is (= (util/map-vals #(map vector %) outputs) + (vectorize [type outputs]))))))) (deftest test-map-types (let [type (make-output-type "compound.edn") outputs {:outmap {"foo" "lolcats.txt" "bar" "in.gif"}}] (testing "foldl" - (is (= #{"foo" "bar"} (filtering-type #(= % "String") type outputs))) - (is (= #{"lolcats.txt" "in.gif"} (filtering-type #(= % "File") type outputs)))) + (is (= #{"foo" "bar"} + (collect-values-where-type #(= % "String") [type outputs]))) + (is (= #{"lolcats.txt" "in.gif"} + (collect-values-where-type #(= % "File") [type outputs])))) (testing "traverse" (is (= {:outmap {["foo"] ["lolcats.txt"] ["bar"] ["in.gif"]}} - (vectorize type outputs)))))) + (vectorize [type outputs])))))) (deftest test-optional-types (let [type (make-output-type "compound.edn") without {:outoptional nil} with {:outoptional "lolcats.txt"}] (testing "foldl" - (is (= 0 (count (workflows/get-files type without)))) - (is (= 1 (count (workflows/get-files type with))))) + (is (= 0 (count (workflows/get-files [type without])))) + (is (= 1 (count (workflows/get-files [type with]))))) (testing "traverse" - (is (= without (vectorize type without))) - (is (= (util/map-vals vector with) (vectorize type with)))))) + (is (= without (vectorize [type without]))) + (is (= (util/map-vals vector with) (vectorize [type with])))))) (deftest test-pair-types - (let [type (make-output-type "compound.edn") - outputs {:outpair '(3 3.14)}] + (let [object [(make-output-type "compound.edn") {:outpair '(3 3.14)}]] (testing "foldl" - (is (= #{3.14} (filtering-type #(= % "Float") type outputs)))) + (is (= #{3.14} (collect-values-where-type #(= % "Float") object)))) (testing "traverse" (is (= {:outpair '(9 3.14)} (workflows/traverse - (fn [type v] (if (= type "Int") (* v v) v)) - type - outputs)))))) + (fn [[type v]] (if (= type "Int") (* v v) v)) + object)))))) (deftest test-struct-types - (let [type (make-output-type "compound.edn") - outputs {:outstruct {:value 3}}] + (let [object [(make-output-type "compound.edn") {:outstruct {:value 3}}]] (testing "foldl" - (is (= #{3} (filtering-type #(= % "Int") type outputs)))) + (is (= #{3} (collect-values-where-type #(= % "Int") object)))) (testing "traverse" (is (= {:outstruct {:value 9}} (workflows/traverse - (fn [type v] (if (= type "Int") (* v v) v)) - type - outputs)))))) + (fn [[type v]] (if (= type "Int") (* v v) v)) + object)))))) diff --git a/api/test/wfl/unit/workloads_test.clj b/api/test/wfl/unit/workloads_test.clj index f92819e3d..64ca71b6f 100644 --- a/api/test/wfl/unit/workloads_test.clj +++ b/api/test/wfl/unit/workloads_test.clj @@ -1,17 +1,17 @@ (ns wfl.unit.workloads-test - (:require [clojure.test :refer :all] - [wfl.api.workloads :as workloads] + (:require [clojure.test :refer [deftest is testing use-fixtures]] + [wfl.api.workloads :as workloads] [wfl.tools.fixtures :refer [method-overload-fixture]]) (:import (clojure.lang ExceptionInfo))) (deftest test-saved-before? - "in version 0.4.0, wgs workloads were serialized using CromwellWorkload table" - (is (not (workloads/saved-before? "0.4.0" {:version "0.4.0"}))) - (is (not (workloads/saved-before? "0.4.0" {:version "1.0.0"}))) - (is (not (workloads/saved-before? "0.4.0" {:version "0.4.1"}))) - (is (workloads/saved-before? "0.4.0" {:version "0.3.8"})) - (is (workloads/saved-before? "0.4.0" {:version "0.0.0"})) - (is (thrown? ExceptionInfo (workloads/saved-before? "0.4" {:version "0.0.0"})))) + (testing "in version 0.4.0, wgs workloads were serialized using CromwellWorkload table" + (is (not (workloads/saved-before? "0.4.0" {:version "0.4.0"}))) + (is (not (workloads/saved-before? "0.4.0" {:version "1.0.0"}))) + (is (not (workloads/saved-before? "0.4.0" {:version "0.4.1"}))) + (is (workloads/saved-before? "0.4.0" {:version "0.3.8"})) + (is (workloads/saved-before? "0.4.0" {:version "0.0.0"})) + (is (thrown? ExceptionInfo (workloads/saved-before? "0.4" {:version "0.0.0"}))))) (def dummy-pipeline "unittest") (defn dummy-handler [_ x] x) diff --git a/database/changelog.xml b/database/changelog.xml index ca01ff523..76833cddd 100644 --- a/database/changelog.xml +++ b/database/changelog.xml @@ -39,4 +39,7 @@ + + + diff --git a/database/changesets/20210624_AddRetryToTerraExecutorDetails.xml b/database/changesets/20210624_AddRetryToTerraExecutorDetails.xml new file mode 100644 index 000000000..002df0603 --- /dev/null +++ b/database/changesets/20210624_AddRetryToTerraExecutorDetails.xml @@ -0,0 +1,27 @@ + + + + + Add a `retry` attribute to the `TerraExecutorDetails` type and all + instantiations thereof to support retries. This column holds the + row id of the workflow that the workflow was retied as, thus forming + a singly linked list tracing the retry history of a set of inputs. + + + ALTER TYPE TerraExecutorDetails + ADD ATTRIBUTE retry BIGINT + CASCADE; + + + diff --git a/database/changesets/20210709_TerraDataRepoSink.xml b/database/changesets/20210709_TerraDataRepoSink.xml new file mode 100644 index 000000000..004363f14 --- /dev/null +++ b/database/changesets/20210709_TerraDataRepoSink.xml @@ -0,0 +1,48 @@ + + + + + The TDR Job list used by the `TerraDataRepo` Sink + + + CREATE TYPE TerraDataRepoSinkDetails AS ( + id BIGINT, -- ALTER ADD GENERATED ALWAYS AS IDENTITY + job TEXT, -- ID of the job created in TDR + status TEXT, -- As reported by TDR + workflow TEXT, -- The UUID of the workflow this job relates to + updated TIMESTAMPTZ, -- When this record was last updated + consumed TIMESTAMPTZ -- When this job was "popped" + ) + + + the `TerraDataRepo` sink table schema + + + CREATE TABLE TerraDataRepoSink ( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, -- primary key + dataset TEXT NOT NULL, -- the serialized EDN of the TDR dataset schema + dataset_table TEXT NOT NULL, -- the name of the dataset table + from_outputs TEXT NOT NULL, -- mapping of how to coerce the output of executor to whatever the sink understands in serialized EDN + details TEXT NOT NULL, -- name of the job queue + CONSTRAINT TERRADATAREPOSINK_PKEY PRIMARY KEY (id) + ) + + + Register the `TerraDataRepoSink` sink type + + + ALTER TYPE sink ADD VALUE 'TerraDataRepoSink' + + + diff --git a/database/changesets/20210720_AddConfigurationTable.xml b/database/changesets/20210720_AddConfigurationTable.xml new file mode 100644 index 000000000..f2ba851db --- /dev/null +++ b/database/changesets/20210720_AddConfigurationTable.xml @@ -0,0 +1,26 @@ + + + + + The Configuration table schema + + + CREATE TABLE Configuration ( + key TEXT UNIQUE NOT NULL, + value TEXT NOT NULL, + CONSTRAINT CONFIGURATION_PKEY PRIMARY KEY (key) + ) + + + diff --git a/docs/md/assets/terra-method-configuration.png b/docs/md/assets/terra-method-configuration.png new file mode 100644 index 000000000..ef1f0de74 Binary files /dev/null and b/docs/md/assets/terra-method-configuration.png differ diff --git a/docs/md/dev-logging.md b/docs/md/dev-logging.md index 765529b75..3b3ab752d 100644 --- a/docs/md/dev-logging.md +++ b/docs/md/dev-logging.md @@ -1,67 +1,66 @@ # WFL Logging ## TL;DR -> Import `clojure.tools.logging :as log` and use `log/error` / `log/info` etc. +> Import `wfl.log :as log` and use `log/error` / `log/info` etc. +> The logger will write the logs with a message, severity and timestamp by default. > -> `clojure.tools.logging` uses SLF4J under the hood which in turn uses Log4j2 as its implementation. +> Example: +> +> `{"severity": "INFO", "message": "This is an information logging message.", "timestamp": "2021-07-08T22:02:58.079938Z"}` +> +> These logs are eventually sent to Google Cloud Logging and can be queried from there. +> More information about Google Logging and what some of the fields provided mean can be found here: +> https://cloud.google.com/logging/docs/agent/logging/configuration#special-fields > > Below is more detailed information for those interested. ## Usage -We use `clojure.tools.logging` aliased to `log`. - Require it like any other dependency: ```clojure (ns "..." (:require ... - [clojure.tools.logging :as log] + [wfl.log :as log] ...)) (log/info "Hello!") ``` -Full documentation is available [here](http://clojure.github.io/tools.logging/#clojure.tools.logging). +There are currently 5 macros for creating simple json logs for `INFO, WARN, DEBUG, ERROR, NOTICE`. There is also +a public method `log` that can be called with additional fields you may want to provide in the log, such as +labels. -## Behavior -Currently, all error-level messages are routed to STDERR, and everything else is routed to STDOUT. +A list of the Google Cloud supported logging fields and severities can be found here: +https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry -Thus, to have WFL log everything to a file you'd want to use something like -```bash -my-command >output.log 2>&1 +An example call to log: +```clojure +(ns "..." + (:require + ... + [wfl.log :as log] + ...)) +(log/log :info "This is an information message with a label" :logging.googleapis.com/labels {:my-label "label value"}) ``` -That'll capture both STDOUT and STDERR to the same file. -Note that this specific syntax is more universal than just `&>output.log`. - +This example produces the following json log: +```json +{"severity":"INFO","message":"This is an information message with a label","timestamp":"2021-07-09T14:57:22.437485Z","logging.googleapis.com/labels":{"my-label":"label value"}} +``` +The logging can also be disabled if you see fit for whatever reason by binding the `*logger*` instance to `disabled-logger`. +Example: +```clojure +(binding [log/*logger* log/disabled-logger] + (log/info "This message will not be written")) +``` ## Testing -clojure.tools.logging provides a [test namespace](http://clojure.github.io/tools.logging/#clojure.tools.logging.test). - -An example of usage is in `test/wfl/unit/logging_test.clj`, which exists to test that the service loaders are correctly resolving our dependencies. - -## Under the Hood -> This section might be a bit verbose but hopefully it won't be too out-of-date since logging setup -> doesn't change all that much. -> -> The key takeaway here is that JVM logging libraries use service loaders -> and other runtime configuration to find each other. - -WFL's logging works as follows: +Test for this can be found in `test/wfl/unit/logging_test.clj`. Currently, the tests check whether the logging methods +produce json that includes the correct severity and message. -1. clojure.tools.logging is imported and used directly - - Why clojure.tools.logging? It is Clojure-native so it has intuitive syntax - - Why not wrap or delegate to it? It already works just as a wrapper to any - other logging implementation so wrapping it would duplicate its purpose -2. clojure.tools.logging delegates to SLF4J - - Why SLF4J? Jetty already uses it, so configuring it ourselves helps keep - it quiet -3. SLF4J delegates to Log4j 2 - - Why delegate? SLF4J is a facade that still needs an implementation to - actually log things - - Why Log4j 2? It is a fair default implementation: highly configurable, - well-tested, well-supported +## Usage in Debugging +In order to be able to search for specific logs locally that could be useful in your debugging you will want to follow these steps: -Even without making our own wrapper around clojure.tools.logging, we have -a lot of flexibility. Suppose Jetty removes their dependency on SLF4J: we -could remove our own dependency on SLF4J and clojure.tools.logging would -immediately begin interacting directly with Log4j 2. +1. Make sure you have `jq` installed for your terminal. +2. Run the server with `./ops/server.sh >> path/to/wfl/log 2>&1` +3. Look up logs by severity and only show the message: `tail -f path/to/wfl/log | grep --line-buffered -w '"severity":"[YOUR_SEVERITY_HERE]"' | jq '.message'` +4. Look up logs by a label and print the message: `tail -f path/to/wfl/log | grep --line-buffered -w 'my-label' | jq '.message'` diff --git a/docs/md/dev-process.md b/docs/md/dev-process.md index b8ef735d6..a509e4b3e 100644 --- a/docs/md/dev-process.md +++ b/docs/md/dev-process.md @@ -131,7 +131,6 @@ For the release process, please refer to the [release guide](./dev-release.md). 11. Merge the PR. - ## Development Tips Here are some tips for WFL development. @@ -225,6 +224,44 @@ silently fail or the Swagger page will fail to render. Check the `clojure.spec.alpha/def`s in `wfl.api.routes` for typos before tearing your hair out. +You can quickly check that the Swagger page renders +by first starting a local WFL server. + +``` shell +./ops/server.sh +``` + +Then open this URL in a browser. + +``` shell +open http://localhost:3000/swagger/swagger.json +``` + +You should see a page of valid Swagger JSON +describing the API. + +You need to start the UI server too +if you want to see the swagger page rendered. +With the local WFL server running on port 3000 as above, +start the UI this way. + +``` shell +cd ./ui +npm run serve +``` + +With the UI running, +open this URL in the browser. + +``` shell +open http://localhost:8080/ +``` + +Click the `LOGIN WITH GOOGLE` button if necessary, +Then the `SWAGGER API` button at the upper right. +You should see an interactive Swagger API page. + + ### debugging Liquibase locally Running `liquibase update`: @@ -283,3 +320,59 @@ It takes a vector of `var`s like this. ``` clojure (comment (test-vars [#'test-something])) ``` + +### No tests found + +When trying to run tests in the command line, you may see the test suite +exit prematurely -- but successfully -- with a warning indicating that +no tests were found, and thus no tests were run. + +```shell +$ make api TARGET=check +export CPCACHE=/Users/okotsopo/wfl/api/.cpcache; \ + clojure -M:test unit | \ + tee /Users/okotsopo/wfl/derived/api/unit.log +... +WARNING: No tests were found, make sure :test-paths and :ns-patterns are configured correctly in tests.edn. +api unit finished on Thu Jun 24 15:03:33 EDT 2021 +... +``` + +This may indicate a compilation error in code not compiled as part of the +build, e.g. tests. Linting can help expose any such errors. + +!!! tip + By default, linting will halt on the first thrown exception, + requiring further linting after fixing until the process succeeds. + +```shell +$ make api TARGET=lint +... +== Eastwood 0.4.2 Clojure 1.10.3 JVM 11.0.10 == +Directories scanned for source files: + +src test +... +== Linting wfl.system.cdc-covid19-surveillance-demo == +Exception thrown during phase :analyze+eval of linting namespace wfl.system.cdc-covid19-surveillance-demo +Got exception with extra ex-data: + msg='No such var: covid' + (keys dat)=(:form :file :end-column :column :line :end-line) + (:form dat)= +^{:line 101} covid/rename-gather + +ExceptionInfo No such var: covid +... +An exception was thrown while analyzing namespace wfl.system.cdc-covid19-surveillance-demo +Lint results may be incomplete. If there are compilation errors in +your code, try fixing those. If not, check above for info on the +exception. + +Stopped analyzing namespaces after wfl.system.cdc-covid19-surveillance-demo +due to exception thrown. 28 namespaces left unanalyzed. + +If you wish to force continuation of linting after an exception in one +namespace, make the option map key :continue-on-exception have the +value true. +... +``` diff --git a/docs/md/executor.md b/docs/md/executor.md new file mode 100644 index 000000000..16a34430d --- /dev/null +++ b/docs/md/executor.md @@ -0,0 +1,183 @@ +# Executor +The workload `Executor` models an intermediate stage of a processing pipeline. +In a typical workload configuration, an `Executor` uses a supported +service in the cloud to execute workflows. + +## User Guide +You can configure the type of `Executor` used in your workload by changing the +`executor` attribute of your workload request. + +### `Terra` Executor +You can execute workflows in a Terra workspace using the `Terra` executor. + +The `Terra` executor will... + +- Coerce available outputs from an upstream `Source` to a data type acceptable + for submission creation + (i.e. import a snapshot to the `executor` workspace as a reference) +- Update the method configuration with the coerced object as its root entity + type +- Launch a submission +- Periodically update the statuses of eligible workflows to enable a + downstream `Sink` to consume their outputs + +A typical `Terra` executor configuration in the workload request looks like: +```json +{ + "name": "Terra", + "workspace": "{workspace-namespace}/{workspace-name}", + "methodConfiguration": "{method-configuration-namespace}/{method-configuration-name}", + "methodConfigurationVersion": 1, + "fromSource": "importSnapshot" +} +``` + +And a real-life example for a known method configuration: +```json +{ + "name": "Terra", + "workspace": "wfl-dev/CDC_Viral_Sequencing", + "methodConfiguration": "wfl-dev/sarscov2_illumina_full", + "methodConfigurationVersion": 1, + "fromSource": "importSnapshot" +} +``` + +![](./assets/terra-method-configuration.png) + +The table below summarises the purpose of each attribute in the above request. + +| Attribute | Description | +|------------------------------|---------------------------------------------------------------------------------------------------| +| `name` | Selects the `Terra` executor implementation. | +| `workspace` | Terra Workspace in which to execute workflows. | +| `methodConfiguration` | Method configuration from which to generate submissions. | +| `methodConfigurationVersion` | Expected version of the method configuration. | +| `fromSource` | Instruction to coerce an output from an upstream `Source` to a type understood by this `executor`.| + +#### `workspace` +A `{workspace-namespace}/{workspace-name}` string as it appears in the URL path +in the Terra UI. + +Prerequisites: + +- The workspace must exist prior to workload creation. +- `workflow-launcher@firecloud.org` must be a workspace "Owner" in order to + import snapshots to the workspace. +- The workspace must be compatible with any downstream processing stage that + consumes its workflows. + +#### `methodConfiguration` +A `{method-configuration-namespace}/{method-configuration-name}` string as it +appears in the URL path in the Terra UI. + +Prerequisites: + +- The method configuration must exist within `workspace` prior to + workload creation. + +#### `methodConfigurationVersion` +The expected version of `methodConfiguration`, stored as an integer +in Firecloud. + +Prerequisites: + +- The `methodConfiguration` version when fetched from Firecloud should match + `methodConfigurationVersion`. + +!!! warning "Implications of Version Mismatch" + A version mismatch may indicate a possible concurrent modification of the + method configuration used for launching submissions. Modification is possible + programmatically or via the Terra UI. An unexpected modification may cause + submission and/or workflow creation to fail. + +#### `fromSource` +This attribute tells workflow-launcher how to coerce an output +from an upstream `Source` into a data type understood by the executor. + +Prerequisites: + +- Must be one of the following supported coercion instructions. + +###### `importSnapshot` +Workflow-launcher should import Terra Data Repository (TDR) snapshots +into `workspace` as snapshot references, +updating `methodConfiguration` with the reference as its root entity type. + +## Developer Guide +An executor is a `Queue` that satisfies the `Executor` protocol below: +```clojure +(defprotocol Executor + (update-executor! + ^Executor + [^Queue upstream ;; The queue from which to pull items to execute + ^Executor executor ;; This executor instance + ] + "Consume items from the `upstream` queue and enqueue + to the `executor` queue for consumption by a later processing stage, + performing any external effects as necessary. + Implementations should avoid maintaining in-memory state and making long- + running external calls, favouring internal queues to manage such tasks + asynchronously between invocations. Note that the `Executor` and `Queue` + are parameterised types and the `Queue`'s parameterisation must be + convertible to the `Executor`s.") + (executor-workflows + ^IPersistentVector + [^Connection transaction ;; JDBC Connection + ^Executor executor ;; This executor instance + ] + "Use database `transaction` to return workflows created by the `executor`.") + (executor-workflows-by-status + ^IPersistentVector + [^Connection transaction ;; JDBC Connection + ^Executor executor ;; This executor instance + ^String status ;; workflow status to match + ] + "Use database `transaction` to return workflows created by the `executor` + matching the workflow `status`.") + (executor-retry-workflows! + ;; Executed for side effects + [^Executor executor ;; This executor instance + ^IPersistentVector workflows ;; Workflows to retry + ] + "Retry/resubmit the `workflows` managed by the `executor`.")) +``` + +!!! note + The `Executor` protocol is implemented by a set of multimethods of the same + name. The use of a protocol is to illustrate the difference between the + in-memory data model of a `Executor` and the metadata seen by a user. + +To be used in a workload, a `Executor` implementation should satisfy the +processing `Stage` protocol and the `to-edn` multimethod in addition to the +following multimethods specific to executors: +```clojure +(defmulti create-executor + "Create an `Executor` instance using the database `transaction` and + configuration in the executor `request` and return a + `[type items]` pair to be written to a workload record as + `executor_type` and `executor_items`. + Notes: + - This is a factory method registered for workload creation. + - The `Executor` type string must match a value of the `executor` enum + in the database schema. + - This multimethod is type-dispatched on the `:name` association in the + `request`." + (fn ^[^String ^String] + [^Connection transaction ;; JDBC Connection + ^long workload-id ;; ID of the workload being created + ^IPersistentHashMap request ;; Data forwarded to the handler + ] + (:name request))) + +(defmulti load-executor! + "Return the `Executor` implementation associated with the `executor_type` and + `executor_items` fields of the `workload` row in the database. + Note that this multimethod is type-dispatched on the `:executor_type` + association in the `workload`." + (fn ^Executor + [^Connection transaction ;; JDBC Connection + ^IPersistentHashMap workload ;; Row from workload table + ] + (:executor_type workload))) +``` diff --git a/docs/md/index.md b/docs/md/index.md index e9a276ae6..a236376bc 100644 --- a/docs/md/index.md +++ b/docs/md/index.md @@ -16,6 +16,13 @@ in that workload running WGS reprocessing; a workload could also be a queue of incoming notifications that describe all of the required inputs to launch Arrays scientific pipelines in Cromwell. +Most recent efforts leverage the general applicability of a +[staged workload](staged-workload.md) model +which automates fetching data from a [source](./source.md), +pushing it into a workflow [executor](./executor.md) for analysis, +and delivering the results of the analysis to an output location +(also known as a [sink](./sink.md)). + WFL is designed to be deployed to run as a service in the cloud, primarily on Kubernetes clusters. @@ -185,8 +192,6 @@ to deploy applicable versions of WFL to various available cloud projects. ## Implementation -For frontend details, check [Frontend Section](./dev-frontend.md) - ### Top-level files After cloning a new WFL repo, the top-level files are: diff --git a/docs/md/modules-arrays.md b/docs/md/modules-aou-arrays.md similarity index 99% rename from docs/md/modules-arrays.md rename to docs/md/modules-aou-arrays.md index 05810d511..6059e2a05 100644 --- a/docs/md/modules-arrays.md +++ b/docs/md/modules-aou-arrays.md @@ -1,4 +1,4 @@ -# Arrays module +# All Of Us Arrays module WorkFlow Launcher (WFL) implements `aou-arrays` module to support secure and efficient processing of the AllOfUs Arrays diff --git a/docs/md/modules-covid.md b/docs/md/modules-covid.md new file mode 100644 index 000000000..943560f06 --- /dev/null +++ b/docs/md/modules-covid.md @@ -0,0 +1,376 @@ +# COVID module + +WorkFlow Launcher (WFL) uses the `covid` module to automate the sequencing +of COVID-positive samples in Terra workspaces for better understanding +of SARS-CoV-2 spread and evolution. + +For this processing, WFL follows a [staged workload](./staged-workload.md) model +which includes a source, executor, and sink. + +## API Overview + +The `covid` module supports the following API endpoints: + +| Verb | Endpoint | Description | +|------|-------------------------------------|--------------------------------------------------------------------------| +| GET | `/api/v1/workload` | List all workloads, optionally filtering by uuid or project | +| GET | `/api/v1/workload/{uuid}/workflows` | List all workflows for workload `uuid`, optionally filtering by status | +| POST | `/api/v1/workload/{uuid}/retry` | Retry workflows matching a given status in workload `uuid` | +| POST | `/api/v1/create` | Create a new workload | +| POST | `/api/v1/start` | Start a workload | +| POST | `/api/v1/stop` | Stop a running workload | +| POST | `/api/v1/exec` | Create and start (execute) a workload | + +The life-cycle of a workload is a multi-stage process: + +1. The caller needs to [create](#create-workload) a workload + and specify the source, executor, and sink. + + - For continuous processing, the [Source](./source.md) request + is expected to have name [`Terra DataRepo`](./source.md#terra-datarepo-source) + and specify a Terra Data Repository (TDR) dataset to poll and snapshot. + In one-off processing or development, we may instead use name + [`TDR Snapshots Source`](./source.md#tdr-snapshots-source) + to specify a list of existing TDR snapshots. + + - The [Executor](./executor.md) request is expected to have name + [`Terra`](./executor.md#terra-executor) and specify the Terra workspace + configuration for executing workflows. + + - The [Sink](./sink.md) request is expected to have name + [`Terra Workspace`](./sink.md#terra-workspace-sink) + and specify the Terra workspace configuration for saving workflow outputs. + + If all stage requests pass verification, + in response the caller will receive the newly created + [workload object](#workload-response-format) with an assigned `uuid`. + +2. Next, the caller needs to [start](#start-workload) the newly created workload, which will begin the analysis. + Once started, WFL will continue to poll for new inputs to the source until it is stopped. + +3. WFL can, in addition, [stop](#stop-workload) watching a workflow. + This will not cancel analysis, but WFL will stop polling for new inputs to that workload, + and will mark the workload finished once any previously-identified inputs have undergone processing. + + - Example: the caller may wish to stop a continuous workflow + if maintenance is required on the underlying method. + +The caller can also [retry](#retry-workload) workflows in a workload +matching a given status (ex. "Failed"). + +## API Usage Examples + +Here you'll find example requests and responses for the endpoints enumerated above. + +### Workload Response Format + +Many of the API endpoints return COVID workloads in their responses. + +An example workload response at the time of this writing is formatted thusly: + +``` +{ + "started" : "2021-07-14T15:36:47Z", + "watchers" : [ "okotsopo@broadinstitute.org" ], + "labels" : [ "hornet:test", "project:okotsopo testing enhanced source, executor, sink logging" ], + "creator" : "okotsopo@broadinstitute.org", + "updated" : "2021-08-06T21:41:28Z", + "created" : "2021-07-14T15:36:07Z", + "source" : { + "snapshots" : [ "67a2bfd7-88e4-4adf-9e41-9b0d04fb32ea" ], + "name" : "TDR Snapshots" + }, + "finished" : "2021-08-06T21:41:28Z", + "commit" : "9719eda7424bf5b0804f5493875681fa014cdb29", + "uuid" : "e66c86b2-120d-4f7f-9c3a-b9eaadeb1919", + "executor" : { + "workspace" : "wfl-dev/CDC_Viral_Sequencing_okotsopo_20210707", + "methodConfiguration" : "wfl-dev/sarscov2_illumina_full", + "methodConfigurationVersion" : 41, + "fromSource" : "importSnapshot", + "name" : "Terra" + }, + "version" : "0.8.0", + "sink" : { + "workspace" : "wfl-dev/CDC_Viral_Sequencing_okotsopo_20210707", + "entityType" : "flowcell", + "fromOutputs" : { + "submission_xml" : "submission_xml", + "assembled_ids" : "assembled_ids", + ... + }, + "identifier" : "run_id", + "name" : "Terra Workspace" + } + } +``` + +Worth mentioning is that the contents of the `source`, `executor` and `sink` blocks +within the response will be formatted according to the corresponding stage implementation. + +### Get Workloads + +!!! warning "Note" + A request to the `/api/v1/workload` endpoint without a `uuid` + or `project` parameter returns all workloads known to WFL. + That response might be large and take awhile to process. + +**GET /api/v1/workload?uuid={uuid}** + +Query WFL for a workload by its UUID. + +Note that a successful response from `/api/v1/workload` will +always be an array of [workload objects](#workload-response-format), +but specifying a `uuid` will return a singleton array. + +=== "Request" + + ``` + curl -X GET 'http://localhost:3000/api/v1/workload' \ + -H 'Authorization: Bearer '$(gcloud auth print-access-token) \ + -H 'Accept: application/json' \ + -d $'{ "uuid": "e66c86b2-120d-4f7f-9c3a-b9eaadeb1919" }' + ``` + +**GET /api/v1/workload?project={project}** + +Query WFL for all workloads with a specified `project` label. + +The response is an array of [workload objects](#workload-response-format). + +=== "Request" + + ``` + curl -X GET 'http://localhost:3000/api/v1/workload' \ + -H 'Authorization: Bearer '$(gcloud auth print-access-token) \ + -H 'Accept: application/json' \ + -d $'{ "project": "PO-1234" }' + ``` + +### Get Workflows + +**GET /api/v1/workload/{uuid}/workflows** + +Query WFL for all workflows associated with workload `uuid`. + +The response is a list of Firecloud-derived +[workflows](https://firecloud-orchestration.dsde-prod.broadinstitute.org/#/Submissions/workflowMetadata) +and their [outputs](https://firecloud-orchestration.dsde-prod.broadinstitute.org/#/Submissions/workflowOutputsInSubmission) +when available (when the workflow has succeeded). + +=== "Request" + + ``` + curl -X GET 'http://localhost:3000/api/v1/workload/e66c86b2-120d-4f7f-9c3a-b9eaadeb1919/workflows' \ + -H 'Authorization: Bearer '$(gcloud auth print-access-token) \ + -H 'Accept: application/json' + ``` + +=== "Response" + + ``` + [ { + "inputs" : { + "biosample_to_genbank.docker" : "quay.io/broadinstitute/viral-phylo:2.1.19.1", + "instrument_model" : "Illumina NovaSeq 6000", + ... + }, + "uuid" : "53f70344-6f0f-47fb-adee-4e780fb3f19a", + "status" : "Failed", + "outputs" : { }, + "updated" : "2021-08-06T21:41:28Z" + } ] + ``` + +**GET /api/v1/workload/{uuid}/workflows?status={status}** + +Query WFL for all workflows with `status` associated with workload `uuid`. + +The response has the same format as when querying without the status restriction. + +=== "Request" + + ``` + curl -X GET 'http://localhost:3000/api/v1/workload/e66c86b2-120d-4f7f-9c3a-b9eaadeb1919/workflows' \ + -H 'Authorization: Bearer '$(gcloud auth print-access-token) \ + -H 'Accept: application/json' \ + -d $'{ "status": "Failed" }' + ``` + +### Retry Workload + +**POST /api/v1/workload/{uuid}/retry?status={status}** + +Resubmit all workflows matching `status` associated with workload `uuid`. + +Prerequisites: + +- The status is [supported](./usage-retry.md#supported-statuses) +- Workflows must exist in the workload for the specified status +- The workload should be started + +With all prerequisite fulfilled, WFL will then... + +- Submit the retry to the executor +- (If necessary) remark the workload as active + so that it will be visible in the update loop + +The response is the updated [workload object](#workload-response-format). + +Further information found in general +[retry documentation](./usage-retry.md#retrying-terra-workflows-via-wfl-api). + +=== "Request" + + ``` + curl -X POST "http://localhost:3000/api/v1/workload/e66c86b2-120d-4f7f-9c3a-b9eaadeb1919/retry" \ + -H 'Authorization: Bearer '$(gcloud auth print-access-token) \ + -H "Content-Type: application/json" \ + -d '{ "status": "Aborted" }' + ``` + +### Create Workload + +**POST /api/v1/create** + +Create a new workload from a request. +Expected request format documented within [staged workload](./staged-workload.md) +navigation. + +The response is the newly created [workload object](#workload-response-format) +with an assigned `uuid`. + +=== "Request" + + ``` + curl -X "POST" "http://localhost:3000/api/v1/create" \ + -H 'Authorization: Bearer '$(gcloud auth print-access-token) \ + -H 'Content-Type: application/json' \ + -d '{ + "watchers": [ + "tester@123.com" + ], + "labels": [ + "hornet:test" + ], + "project": "wfl-dev/CDC_Viral_Sequencing _ranthony_bashing_copy", + "source": { + "name": "Terra DataRepo", + "dataset": "4bb51d98-b4aa-4c72-b76a-1a96a2ee3057", + "table": "flowcells", + "column": "last_modified_date", + "snapshotReaders": [ + "workflow-launcher-dev@firecloud.org" + ] + }, + "executor": { + "name": "Terra", + "workspace": "wfl-dev/CDC_Viral_Sequencing _ranthony_bashing_copy", + "methodConfiguration": "wfl-dev/sarscov2_illumina_full", + "methodConfigurationVersion": 2, + "fromSource": "importSnapshot" + }, + "sink": { + "name": "Terra Workspace", + "workspace": "wfl-dev/CDC_Viral_Sequencing _ranthony_bashing_copy", + "entityType": "flowcell", + "identifier": "run_id", + "fromOutputs": { + "submission_xml" : "submission_xml", + "assembled_ids" : "assembled_ids", + "num_failed_assembly" : "num_failed_assembly", + ... + } + } + }' + ``` + +### Start Workload + +**POST /api/v1/start?uuid={uuid}** + +Start an existing, unstarted workload `uuid`. + +The response is the updated [workload object](#workload-response-format). + +=== "Request" + + ``` + curl -X POST 'http://localhost:3000/api/v1/start' \ + -H 'Authorization: Bearer '$(gcloud auth print-access-token) \ + -H 'Content-Type: application/json' \ + -d $'{ "uuid": "fb06bcf3-bc10-471b-a309-b2f99e4f5a67" }' + ``` + +### Stop Workload + +**POST /api/v1/stop?uuid={uuid}** + +Stop a running workload `uuid`. + +The response is the updated [workload object](#workload-response-format). + +=== "Request" + + ``` + curl -X POST 'http://localhost:3000/api/v1/stop' \ + -H 'Authorization: Bearer '$(gcloud auth print-access-token) \ + -H 'Content-Type: application/json' \ + -d $'{ "uuid": "fb06bcf3-bc10-471b-a309-b2f99e4f5a67" }' + ``` + +### Execute Workload + +**POST /api/v1/exec** + +Create and start (execute) a workload from a request. +Expected request format documented within [staged workload](./staged-workload.md) +navigation. + +The response is the newly created and started [workload object](#workload-response-format) +with an assigned `uuid`. + +=== "Request" + + ``` + curl -X "POST" "http://localhost:3000/api/v1/exec" \ + -H 'Authorization: Bearer '$(gcloud auth print-access-token) \ + -H 'Content-Type: application/json' \ + -d '{ + "watchers": [ + "tester@123.com" + ], + "labels": [ + "hornet:test" + ], + "project": "wfl-dev/CDC_Viral_Sequencing _ranthony_bashing_copy", + "source": { + "name": "Terra DataRepo", + "dataset": "4bb51d98-b4aa-4c72-b76a-1a96a2ee3057", + "table": "flowcells", + "column": "last_modified_date", + "snapshotReaders": [ + "workflow-launcher-dev@firecloud.org" + ] + }, + "executor": { + "name": "Terra", + "workspace": "wfl-dev/CDC_Viral_Sequencing _ranthony_bashing_copy", + "methodConfiguration": "wfl-dev/sarscov2_illumina_full", + "methodConfigurationVersion": 2, + "fromSource": "importSnapshot" + }, + "sink": { + "name": "Terra Workspace", + "workspace": "wfl-dev/CDC_Viral_Sequencing _ranthony_bashing_copy", + "entityType": "flowcell", + "identifier": "run_id", + "fromOutputs": { + "submission_xml" : "submission_xml", + "assembled_ids" : "assembled_ids", + "num_failed_assembly" : "num_failed_assembly", + ... + } + } + }' + ``` \ No newline at end of file diff --git a/docs/md/sink.md b/docs/md/sink.md new file mode 100644 index 000000000..65a0d653d --- /dev/null +++ b/docs/md/sink.md @@ -0,0 +1,199 @@ +# Sink +The workload `Sink` models the terminal stage of a processing pipeline. In a +typical workload configuration, a `Sink` can be used to write workflow outputs +to a desired location in the cloud. + +## User Guide +You can configure the type of `Sink` used in your workload by changing the +`sink` attribute of your workload request. + +### Terra Workspace Sink +You can write workflow outputs to a Terra Workspace using the `Terra Workspace` +sink. A typical `Terra Workspace` sink configuration in the workload request +looks like: +```json +{ + "name": "Terra Workspace", + "workspace": "{workspace-namespace}/{workspace-name}", + "entityType": "{entity-type-name}", + "identifier": "{output-name}", + "fromOutputs": { + "attribute0": "output0", + "attribute1": ["output1", "output2"], + "attribute3": "$literal", + ... + } +} +``` +The table below summarises the purpose of each attribute in the above request. + +| Attribute | Description | +|---------------|--------------------------------------------------------------| +| `name` | Selects the `Terra Workspace` sink implementation. | +| `workspace` | The Terra Workspace to write pipeline outputs to. | +| `entityType` | The entity type in the `workspace` to write outputs to. | +| `identifier` | Selects the output that will be used as the entity name. | +| `fromOutputs` | Mapping from outputs to attribute names in the `entityType`. | + +#### `workspace` +The workspace is a `"{workspace-namespace}/{workspace-name}"` string as it +appears in the URL path in the Terra UI. The workspace must exist prior to +workload creation. You must ensure that `workflow-launcher@firecloud.org` is +a workspace "Writer" in order to write entities to the workspace. + +#### `entityType` +The `entityType` is the name of the entity type in the workspace that entities +will be created as. The entity type must exist prior to workload creation and +must be a table in the workspace. + +#### `identifier` +The `identifier` is the name of a pipeline output that should be used as the +name of each newly created entity. + +Example - Let's say the pipeline you're running has an output called +"sample_name" that uniquely identifies the inputs and outputs to that pipeline. +By setting `"identifier": "sample_name"` in the sink configuration, entities +will be created using the "sample_name" as the entity name. + +!!! note + When two sets of pipeline outputs share the same "identifier" value, + the first set of outputs will be overwritten by the second in the workspace. + +#### `fromOutputs` +`fromOutputs` configures how to create new entities from pipeline outputs by +mapping the output names to attributes in the `entityType`. Note that all +attribute names must exist in the entityType before the workload creation. + +`fromOutputs` allows a small amount of flexibility in how to construct an entity +and supports the following relations: + +- `"attribute": "output"` + Direct mapping from an output to an attribute + +- `"attribute": ["output0", "output2"]` + Make an attribute from a list of pipeline outputs. + +- `"attribute": "$value"` + Use the literal "value" for an attribute. + +### Terra Data Repository Sink +You can write workflow outputs to a Terra Data Repository dataset using the +`Terra DataRepo` sink. A typical `Terra DataRepo` sink configuration in the +workload request looks like: +```json +{ + "name": "Terra DataRepo", + "dataset": "{dataset-id}", + "table": "{table-name}", + "fromOutputs": { + "column0": "output0", + "column1": ["output1", "output2"], + "column3": "$literal", + ... + } +} +``` +The table below summarises the purpose of each attribute in the above request. + +| Attribute | Description | +|---------------|--------------------------------------------------------------| +| `name` | Selects the `Terra Workspace` sink implementation. | +| `dataset` | The `UUID` of dataset to monitor and read from. | +| `table` | The name of the `dataset` table to monitor and read from. | +| `fromOutputs` | Mapping from outputs to columns in the `table`. | + +#### `dataset` +The dataset attribute is the `UUID` that uniquely identifies the TDR dataset you +want workflow-launcher to write workflow outputs to. + +#### `table` +The `table` is the name of the table in the dataset that you want +workflow-launcher to write workflow outputs to. Once a workflow succeeds, its +outputs will be ingested as new rows in that table (see note). You cannot write +to more than one table per `Terra DataRepo` sink. + +!!! note + workflow-launcher transforms outputs into a form conformant with the table + in the dataset using the transformation described by `fromOutputs`. The + columns in your table don't have to be an exact match for the output names. + See below for more details. + +#### `fromOutputs` +`fromOutputs` configures how to create new rows in the `table` from pipeline +outputs by mapping the output names to columns in the `table`. + +`fromOutputs` allows a small amount of flexibility in how to construct an entity +and supports the following relations: + +- `"column": "output"` + Direct mapping from an output to a column + +- `"column": ["output0", "output2"]` + Make a column from an array of pipeline outputs. + +- `"column": "$value"` + Use the literal "value" for a column. + +!!! note + Any output not included in `fromOutputs` will not be ingested into the + dataset + +!!! note + Any column not included in `fromOuputs` will not have a value in the newly + added row. + +## Developer Guide +A sink is one satisfying the `Sink` protocol as below: +```clojure +(defprotocol Sink + (update-sink! + ^Sink + [^Queue upstream ;; The queue to sink outputs from + ^Sink sink ;; This sink instance + ] + "Update the internal state of the `sink`, consuming objects from the + Queue `upstream`, performing any external effects as required. + Implementations should avoid maintaining in-memory state and making long- + running external calls, favouring internal queues to manage such tasks + asynchronously between invocations. Note that The `Sink` and `Queue` are + parameterised types and the `Queue`'s parameterisation must be convertible + to the `Sink`s.")) +``` + +!!! note + The `Sink` protocol is implemented by the `update-sink!` multimethod. It's + documented thus as a means of differentiating the in-memory data model from + the metadata a user sees. + +To be used in a workload, a `Sink` implementation should satisfy `Stage`, the +`to-edn` multimethod and the following multimethods specific to `Sink`s: +```clojure +(defmulti create-sink + "Create a `Sink` instance using the database `transaction` and configuration + in the sink `request` and return a `[type items]` pair to be written to a + workload record as `sink_type` and `sink_items`. + Notes: + - This is a factory method registered for workload creation. + - The `Sink` type string must match a value of the `sink` enum in the + database schema. + - This multimethod is type-dispatched on the `:name` association in the + `request`." + (fn ^[^String ^String] + [^Connection transaction ;; JDBC Connection + ^long workload-id ;; ID of the workload being created + ^IPersistentHashMap request ;; Data forwarded to the handler + ] + (:name request))) + +(defmulti load-sink! + "Return the `Sink` implementation associated with the `sink_type` and + `sink_items` fields of the `workload` row in the database. Note that this + multimethod is type-dispatched on the `:sink_type` association in the + `workload`." + (fn ^Sink + [^Connection transaction ;; JDBC Connection + ^IPersistentHashMap workload ;; Row from workload table + ] + (:sink_type workload))) +``` + diff --git a/docs/md/source.md b/docs/md/source.md new file mode 100644 index 000000000..ea26f5f89 --- /dev/null +++ b/docs/md/source.md @@ -0,0 +1,186 @@ +# Source +The workload `Source` models the first stage of a processing pipeline. In a +typical workload configuration, a `Source` can be used to read workflow inputs +from a specified location or service in the cloud. + +## User Guide +You can configure the type of `Source` used in your workload by changing the +`source` attribute of your workload request. + +### `Terra DataRepo` Source +You can configure workflow-launcher to fetch workflow inputs from a Terra Data +Repository (TDR) dataset in real-time using the `Terra DataRepo` source. The +`Terra DataRepo` source polls a specified table in your dataset for new and/or +updated rows and snapshots the rows to be processed downstream by an `Executor`. +The table in your dataset must include a `DateTime` or `Timestamp` column +representing the load or last modification date of that row to be compatible +with a `Terra DataRepo` source. The `Terra DataRepo` source can only read inputs +from a single table. + +When you `start` the workload, the `Terra DataRepo` source will start looking +for new/updated rows from that instant. + +When you `stop` the workload, the `Terra DataRepo` source will stop looking +for new/updated rows from that instant. All pending snapshots may continue +to be processed by a later workload stage. + +!!! note + workflow-launcher creates snapshots of your data to be processed by a + later stage of the workload. Therefore, you must ensure the account + `workflow-launcher@firecloud.org` is a `custodian` of your dataset. + +A typical `Terra DataRepo` source configuration in the workload request looks +like: +```json +{ + "name": "Terra DataRepo", + "dataset": "{dataset-id}", + "table": "{dataset-table-name}", + "column": "{dataset-column-name-to-poll}", + "snapshotReaders": [ + "{user}@{domain}", + ... + ] +} +``` +The table below summarises the purpose of each attribute in the above request. + +| Attribute | Description | +|-------------------|----------------------------------------------------------| +| `name` | Selects the `Terra DataRepo` source implementation. | +| `dataset` | The `UUID` of dataset to monitor and read from. | +| `table` | The name of the `dataset` table to monitor and read from.| +| `column` | The name of the UTC `DateTime` or `Timestamp` column in the `table` to poll.| +| `snapshotReaders` | A list of email addresses whom should be `readers` of all snapshots created by workflow-launcher in this workload.| + +#### `dataset` +The dataset attribute is the `UUID` that uniquely identifies the TDR dataset you +want workflow-launcher to fetch workflow inputs form. + +#### `table` +The `table` is the name of the table in the dataset that you want +workflow-launcher to fetch inputs from. You should design this table such that +each row contains all the inputs required to execute a workflow by the workload +`Executor` downstream. + +#### `column` +The `column` is the name of a column in the table specified above used to +determine which rows are new and/or have been updated and therefore need +reprocessing. It should be a `Timestamp`, but `DateTime` is accepted too. +You must ensure that the `Timestamp` or `DateTime` column uses Universal +Coordinated Time (UTC). + +!!! note + Using a `Timestamp` will increase the likelihood of workflow-launcher + detecting and scheduling new rows in real-time due to greater precision. + Using `DateTime` may cause workflow-launcher to miss the row at first + (though it will be picked up later). + +#### `snapshotReaders` +The email addresses of those whom should be "readers" of all snapshots created +by workflow-launcher in this workload. You can specify individual users and/or +Terra/Firecloud groups. + +### `TDR Snapshots` Source + +You can configure workflow-launcher to use a list of TDR snapshots directly. +This may be useful if you don't want workflow-launcher to be a custodian of your +dataset or if you already have snapshots you want to process. In this case you +must ensure that `workflow-launcher@firecloud.org` is a `reader` of all +snapshots you want it to process. + +A typical `TDR Snapshots` source configuration in the workload request looks +like: +```json +{ + "name": "TDR Snapshots", + "snapshots": [ + "{snapshot-id}", + ... + ] +} +``` + +The table below summarises the purpose of each attribute in the above request. + +| Attribute | Description | +|-------------|----------------------------------------------------| +| `name` | Selects the `TDR Snapshots` source implementation. | +| `snapshots` | A List of `UUID`s of snapshots to process. | + +!!! note + You must ensure that the snapshots you list are compatible with the + downstream processing stage that consumes them. + +## Developer Guide +A source is a `Queue` that satisfies the `Source` protocol below: +```clojure +(defprotocol Source + (start-source! + ^Unit + [^Connection transaction ;; JDBC Connection + ^Source source ;; This source instance + ] + "Start enqueuing items onto the `source`'s queue to be consumed by a later + processing stage. This operation should not perform any long-running + external effects other than database operations via the `transaction`. This + function is called at most once during a workload's operation.") + (stop-source! + ^Unit + [^Connection transaction ;; JDBC Connection + ^Source source ;; This source instance + ] + "Stop enqueuing inputs onto the `source`'s queue to be consumed by a later + processing stage. This operation should not perform any long-running + external effects other than database operations via the `transaction`. This + function is called at most once during a workload's operation and will only + be called after `start-source!`. Any outstanding items on the `source` + queue may still be consumed by a later processing stage.") + (update-source! + ^Source + [^Source source] + "Enqueue items onto the `source` queue to be consumed by a later processing + stage unless stopped, performing any external effects as necessary. + Implementations should avoid maintaining in-memory state and making long- + running external calls, favouring internal queues to manage such tasks + asynchronously between invocations. This function is called one or more + times after `start-source!` and may be called after `stop-source!`")) +``` + +!!! note + The `Source` protocol is implemented by a set of multimethods of the same + name. The use of a protocol is to illustrate the difference between the + in-memory data model of a `Source` and the metadata seen by a user. + +To be used in a workload, a `Source` implementation should satisfy the +processing `Stage` protocol and the `to-edn` multimethod in addition to the +following multimethods specific to sinks: +```clojure +(defmulti create-source + "Create a `Source` instance using the database `transaction` and configuration + in the source `request` and return a `[type items]` pair to be written to a + workload record as `source_type` and `source_items`. + Notes: + - This is a factory method registered for workload creation. + - The `Source` type string must match a value of the `source` enum in the + database schema. + - This multimethod is type-dispatched on the `:name` association in the + `request`." + (fn ^[^String ^String] + [^Connection transaction ;; JDBC Connection + ^long workload-id ;; ID of the workload being created + ^IPersistentHashMap request ;; Data forwarded to the handler + ] + (:name request))) + +(defmulti load-source! + "Return the `Source` implementation associated with the `source_type` and + `source_items` fields of the `workload` row in the database. Note that this + multimethod is type-dispatched on the `:source_type` association in the + `workload`." + (fn ^Sink + [^Connection transaction ;; JDBC Connection + ^IPersistentHashMap workload ;; Row from workload table + ] + (:source_type workload))) +``` diff --git a/docs/md/staged-workload.md b/docs/md/staged-workload.md new file mode 100644 index 000000000..e65e1e093 --- /dev/null +++ b/docs/md/staged-workload.md @@ -0,0 +1,75 @@ +# Staged Workloads + +A staged workload is a discrete body of work, which takes data from a source, +pushes it into a workflow executor for analysis, +and then delivers the results of the analysis to an output location (also known as a sink). + +## Staged Workload Components +### Source +The workload [Source](./source.md) models the first stage of a processing pipeline. +In a typical workload configuration, a `Source` can be used to read workflow inputs +from a specified location or service in the cloud. + +### Executor +The workload [Executor](./executor.md) models an intermediate stage of a processing pipeline. +In a typical workload configuration, an `Executor` uses a supported +service in the cloud to execute workflows. + +### Sink +The workload [Sink](./sink.md) models the terminal stage of a processing pipeline. +In a typical workload configuration, a `Sink` can be used to write workflow outputs +to a desired location in the cloud. + +## Example Staged Workload +The specific values below are from the +[COVID-19 Surveillance in Terra](./modules-covid.md) project. +Workloads for other projects may leverage different implementations for source, executor or sink. + +``` +{ + "watchers": [ tester@broadinstitute.org ], + "labels": [ + "hornet:test" + ], + "project": "wfl-dev/CDC_Viral_Sequencing", + "source": { + "name": "Terra DataRepo", + "dataset": "4bb51d98-b4aa-4c72-b76a-1a96a2ee3057", + "table": "flowcells", + "column": "last_modified_date", + "snapshotReaders": [ + "workflow-launcher-dev@firecloud.org" + ] + }, + "executor": { + "name": "Terra", + "workspace": "wfl-dev/CDC_Viral_Sequencing", + "methodConfiguration": "wfl-dev/sarscov2_illumina_full", + "methodConfigurationVersion": 1, + "fromSource": "importSnapshot" + }, + "sink": { + "name": "Terra Workspace", + "workspace": "wfl-dev/CDC_Viral_Sequencing", + "entityType": "flowcell", + "identifier": "run_id", + "fromOutputs": { + "submission_xml" : "submission_xml", + "assembled_ids" : "assembled_ids", + "num_failed_assembly" : "num_failed_assembly", + ... + } + } +} +``` + +## Staged Workload Anatomy (High Level) + +| Field | Type | Description | +|----------|------|---------------------------------| +| watchers | List | A list of emails to notify | +| labels | List | A list of user-defined labels.They must be a string of the form `"name":"value”`, where `name` must start with a letter followed by any combination of digits, letters, spaces, underscores and hyphens and `value` is any non-blank string | +| project | String | The project is a non-null string required in the workload table. It's needed to support querying workloads by project | +| source | Object | The data source | +| executor | Object | The mechanism executing the analysis. (Most often this is Terra)| +| sink | Object | The location where data will be placed after analysis is complete| diff --git a/docs/md/usage-retry.md b/docs/md/usage-retry.md index 59ab69478..c9162c3c7 100644 --- a/docs/md/usage-retry.md +++ b/docs/md/usage-retry.md @@ -1,4 +1,87 @@ -# Retrying Failures via WFL +# Retrying Workflows + +## Retrying Terra Workflows via WFL API + +WFL has a `/retry` endpoint that selects workflows by their completion status +and re-submits them. + +The following `curl` shell command finds the workflows +with the Cromwell status `"Failed"` in workload `$UUID` +and resubmits them for processing. + +```bash +WFL=https://gotc-prod-wfl.gotc-prod.broadinstitute.org/api/v1/workload +AUTH="Authorization: Bearer $(gcloud auth print-access-token)" +UUID=0d307eb3-2b8e-419c-b687-8c08c84e2a0c # workload UUID + +curl -X POST -H "$AUTH" $WFL/$UUID/retry --data '{"status":"Failed"}' | jq +``` + +A successful `/retry` request returns the workload specified by `$UUID`. +A failed `/retry` request will return a description of the failure. + +The `/retry` endpoint is not yet implemented for all workloads +and in such cases returns a `501` HTTP failure status. +[Staged workloads](./staged-workload.md) with a [Terra executor](./executor.md#terra-executor) +are likely to implement this endpoint. +For confirmation, see module-specific documentation. +For unimplemented cases, see the [runbook](#retrying-failures-via-wfl-runbook) below. + +### Supported Statuses + +The only +[Cromwell statuses](https://github.com/broadinstitute/wfl/blob/6bcfde01542bfef1601eaaf4bb2657cf1520218f/api/src/wfl/service/cromwell.clj#L12-L14) +supported with the `/retry` API +are the terminal workflow statuses: + +- `"Aborted"` + +- `"Failed"` + +- `"Succeeded"` + +???+ info "Why would you retry succeeded workflows?" + A workflow may have functionally succeeded, but be scientifically inaccurate + and need to be rerun, e.g. if the initial run contained incorrect metadata. + +Attempting to retry workflows of any other status +will return a `400` HTTP failure status, +as will specifying a status for which the workload has no workflows. + +### Warnings and Caveats + +#### Submission of snapshot subsets not yet supported + +WFL is limited by [Rawls](https://github.com/broadinstitute/rawls) functionality +and cannot yet submit a subset of a snapshot. +So retrying any workflow from a workload snapshot +will resubmit all entities from that snapshot. + +Example - a running submission from a snapshot has 500 workflows: + +- 1 failed + +- 249 running + +- 250 succeeded + +Retrying the failed workflow will create a new submission +where all 500 original workflows are retried. + +Consider whether you should wait for all workflows in the submission to complete +before initiating a retry +to avoid multiple workflows running concurrently +in competition for the same output files. + +#### Race condition when retrying the same workload concurrently + +A caller could hit this endpoint for the same workload multiple times in quick succession, +making possible a race condition where each run retries the same set of workflows. + +Future improvements will make this operation threadsafe, but in the interim +try to wait for a response from your retry request before resubmitting. + +## Retrying Failures via WFL Runbook WFL remembers enough about submissions to let you quickly resubmit failed workflows with the same inputs/options as they were originally submitted. @@ -92,9 +175,9 @@ main() { main "$1" ``` -## Tips +### Tips -### Customizing Inputs/Options +#### Customizing Inputs/Options If you want to inject a new input or option into all of the retried workflows, you can do that with a `common` block. For example, replace this: diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index bfba417aa..99afe4b41 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -9,16 +9,19 @@ theme: primary: green accent: teal toggle: - icon: material/toggle-switch + icon: material/lightbulb name: Switch to light mode - scheme: slate primary: teal accent: teal toggle: - icon: material/toggle-switch-off-outline + icon: material/lightbulb-outline name: Switch to dark mode - feature: - tabs: true + language: en + features: + - navigation.top + - navigation.sections + - navigation.instant docs_dir: "md" @@ -35,16 +38,22 @@ nav: - Release Process: dev-release.md - Logging: dev-logging.md - Frontend: dev-frontend.md + - Staged Workloads: + - Overview: staged-workload.md + - Source: source.md + - Executor: executor.md + - Sink: sink.md - Module-Specific Usage: - Overview: modules-general.md - - Arrays: modules-arrays.md - - Whole Genome: modules-wgs.md + - Arrays: modules-aou-arrays.md + - Covid: modules-covid.md - External Exome: modules-external-exome-reprocessing.md - Somatic Genomes: modules-sg.md + - Whole Genome: modules-wgs.md - General Usage: - Workflow Options: usage-workflow-options.md - Usage Across a Directory: usage-across-directory.md - - Retrying Failures: usage-retry.md + - Retrying Workflows: usage-retry.md - Aborting a Workload: usage-abort.md - Readings: - WorkFlow Launcher's Role in Terra: terra.md diff --git a/docs/readme.md b/docs/readme.md index 2cff59cdb..fe57e515b 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -7,13 +7,21 @@ You may wish to launch a local version of our documentation website to test changes for formatting, link resolution, etc. -Python 3 is required: +Python 3 is required. It is also good practice to use virtualenv: ``` cd /path/to/wfl/docs +virtualenv <> +source <>/bin/activate python3 -m pip install -r requirements.txt mkdocs serve ``` +Alternatively, you can use make: +``` +make docs +. derived/.venv/docs/bin/activate && ( cd derived/docs; python3 -m mkdocs serve ) +``` + Logging output will indicate that changes are being detected, and point you to where documentation is served (e.g. http://127.0.0.1:8000). ``` @@ -34,4 +42,9 @@ INFO - Browser Connected: http://localhost:8000/dev-process/ ## GitHub Pages Resources [Relative links in markup files](https://github.blog/2013-01-31-relative-links-in-markup-files/) allow intra-doc links to work within GitHub Pages website as well as the -repository view. \ No newline at end of file +repository view. + +[Links to headers](https://stackoverflow.com/questions/27981247/github-markdown-same-page-link) +can be determined by following these conversion rules. +Or you can get the link directly from your local docsite instance +by clicking on the anchor icon visible when hovering to the right of the header. diff --git a/docs/requirements.txt b/docs/requirements.txt index 92bf440b8..45ce9af50 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,3 @@ -pymdown-extensions>="8.0" -markdown-include>="0.4" -mkdocs-material>="6.1.5" +pymdown-extensions==8.0.1 +markdown-include==0.6.0 +mkdocs-material==7.2.4 diff --git a/makerules/common.mk b/makerules/common.mk index 289a40822..7140c59a6 100644 --- a/makerules/common.mk +++ b/makerules/common.mk @@ -14,6 +14,7 @@ DATE := date DOCKER := docker DIRNAME := dirname ECHO := echo +EXIT := exit EXPORT := export FIND := find GIT := git diff --git a/makerules/modules.mk b/makerules/modules.mk index 4ff25407d..273090ea2 100644 --- a/makerules/modules.mk +++ b/makerules/modules.mk @@ -14,7 +14,7 @@ DERIVED_MODULE_DIR := $(DERIVED_DIR)/$(MODULE) export WFL_VERSION ?= $(shell $(CAT) $(PROJECT_DIR)/version) # Top level `make` targets for the module -MAKE_TARGETS := prebuild lint build unit integration check images system +MAKE_TARGETS := prebuild format build unit integration check lint images system # Timestamps for the top level make targets in a loose order of their timeings. # Implementers should write module make-targets against these, ensuring that @@ -25,7 +25,7 @@ MAKE_TARGETS := prebuild lint build unit integration check images system # @$(TOUCH) $@ PREBUILD := $(DERIVED_MODULE_DIR)/prebuild.$(TIMESTAMP) -LINT := $(DERIVED_MODULE_DIR)/lint.$(TIMESTAMP) +LINT := $(DERIVED_MODULE_DIR)/lint.$(TIMESTAMP) BUILD := $(DERIVED_MODULE_DIR)/build.$(TIMESTAMP) UNIT := $(DERIVED_MODULE_DIR)/unit.$(TIMESTAMP) INTEGRATION := $(DERIVED_MODULE_DIR)/integration.$(TIMESTAMP) @@ -38,13 +38,13 @@ all: $(MAKE_TARGETS) # Configure `make` dependencies via their timestamp. $(PREBUILD): $(shell eval $(MKDIR) $(DERIVED_MODULE_DIR)) $(LINT): $(PREBUILD) -$(BUILD): $(LINT) +$(BUILD): $(PREBUILD) $(UNIT): $(BUILD) $(INTEGRATION): $(BUILD) $(IMAGES): $(BUILD) $(SYSTEM): $(BUILD) -check: unit integration +check: lint unit integration # Top level `make` targets depend on their corresponding time stamp. $(MAKE_TARGETS): % : $(DERIVED_MODULE_DIR)/%.$(TIMESTAMP) diff --git a/ui/package-lock.json b/ui/package-lock.json index 609e3402a..709c37898 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -14,59 +14,149 @@ } }, "@babel/compat-data": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.11.0.tgz", - "integrity": "sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ==", - "dev": true, - "requires": { - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "semver": "^5.5.0" - } + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.5.tgz", + "integrity": "sha512-kixrYn4JwfAVPa0f2yfzc2AWti6WRRyO3XjWW5PJAvtE11qhSayrrcrEnee05KAtNaPC+EwehE8Qt1UedEVB8w==", + "dev": true }, "@babel/core": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.0.tgz", - "integrity": "sha512-mkLq8nwaXmDtFmRkQ8ED/eA2CnVw4zr7dCztKalZXBvdK5EeNUAesrrwUqjQEzFgomJssayzB0aqlOsP1vGLqg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.0", - "@babel/helper-module-transforms": "^7.11.0", - "@babel/helpers": "^7.10.4", - "@babel/parser": "^7.11.0", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.11.0", - "@babel/types": "^7.11.0", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", + "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helpers": "^7.14.6", + "@babel/parser": "^7.14.6", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", + "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", + "semver": "^6.3.0", "source-map": "^0.5.0" }, "dependencies": { "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.14.5" + } + }, + "@babel/generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" } }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } + }, + "@babel/parser": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.6.tgz", + "integrity": "sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/traverse": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.5.tgz", + "integrity": "sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -82,81 +172,347 @@ } }, "@babel/helper-annotate-as-pure": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", - "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz", + "integrity": "sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz", - "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz", + "integrity": "sha512-YTA/Twn0vBXDVGJuAX6PwW7x5zQei1luDDo2Pl6q1qZ7hVNl0RZrhHCQG/ArGpR29Vl7ETiB8eJyrvpuRp300w==", "dev": true, "requires": { - "@babel/helper-explode-assignable-expression": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-explode-assignable-expression": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-compilation-targets": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz", - "integrity": "sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", + "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", "dev": true, "requires": { - "@babel/compat-data": "^7.10.4", - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "levenary": "^1.1.1", - "semver": "^5.5.0" + "@babel/compat-data": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "@babel/helper-create-class-features-plugin": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz", - "integrity": "sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A==", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz", + "integrity": "sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-member-expression-to-functions": "^7.10.5", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4" + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.6.tgz", + "integrity": "sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz", - "integrity": "sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz", + "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-regex": "^7.10.4", - "regexpu-core": "^4.7.0" + "@babel/helper-annotate-as-pure": "^7.14.5", + "regexpu-core": "^4.7.1" } }, - "@babel/helper-define-map": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz", - "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==", + "@babel/helper-define-polyfill-provider": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz", + "integrity": "sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/types": "^7.10.5", - "lodash": "^4.17.19" + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.6.tgz", + "integrity": "sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/traverse": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.5.tgz", + "integrity": "sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "@babel/helper-explode-assignable-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.4.tgz", - "integrity": "sha512-4K71RyRQNPRrR85sr5QY4X3VwG4wtVoXZB9+L3r1Gp38DhELyHCtovqydRi7c1Ovb17eRGiQ/FD5s8JdU0Uy5A==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz", + "integrity": "sha512-Htb24gnGJdIGT4vnRKMdoXiOIlqOLmdiUYpAQ0mYfgVT/GDm8GOYhgi4GL+hMKrkiPRohO4ts34ELFsGAPQLDQ==", "dev": true, "requires": { - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-function-name": { @@ -180,113 +536,452 @@ } }, "@babel/helper-hoist-variables": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz", - "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-member-expression-to-functions": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", - "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.5.tgz", + "integrity": "sha512-UxUeEYPrqH1Q/k0yRku1JE7dyfyehNwT6SVkMHvYvPDv4+uu627VXBckVj891BO8ruKBkiDoGnZf4qPDD8abDQ==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-module-imports": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", + "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-module-transforms": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", - "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/template": "^7.10.4", - "@babel/types": "^7.11.0", - "lodash": "^4.17.19" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", - "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", - "dev": true - }, - "@babel/helper-regex": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.5.tgz", - "integrity": "sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg==", - "dev": true, - "requires": { - "lodash": "^4.17.19" - } - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.4.tgz", - "integrity": "sha512-86Lsr6NNw3qTNl+TBcF1oRZMaVzJtbWTyTko+CQL/tvNvcGYEFKbLXDPxtW0HKk3McNOk4KzY55itGWCAGK5tg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", + "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-wrap-function": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-simple-access": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.6.tgz", + "integrity": "sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/traverse": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.5.tgz", + "integrity": "sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", + "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-plugin-utils": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.14.5.tgz", + "integrity": "sha512-rLQKdQU+HYlxBwQIj8dk4/0ENOUEhA/Z0l4hN8BexpvmSMN9oA9EagjnhnDpNsRdWCfjwa4mn/HyBXO9yhQP6A==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-wrap-function": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-replace-supers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", - "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", + "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.6.tgz", + "integrity": "sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/traverse": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.5.tgz", + "integrity": "sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-simple-access": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", - "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", + "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", "dev": true, "requires": { - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz", - "integrity": "sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz", + "integrity": "sha512-dmqZB7mrb94PZSAOYtr+ZN5qt5owZIAgqtoTuqiFbHFtxgEcmQlRJVI+bO++fciBunXtB6MK7HrzrfcAzIz2NQ==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-split-export-declaration": { @@ -304,27 +999,257 @@ "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true + }, "@babel/helper-wrap-function": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz", - "integrity": "sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.14.5.tgz", + "integrity": "sha512-YEdjTCq+LNuNS1WfxsDCNpgXkJaIyqco6DAelTUjT4f2KIWC1nBcaCaSdHTBqQVLnTBexBcVcFhLSU1KnYuePQ==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-function-name": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.6.tgz", + "integrity": "sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/traverse": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.5.tgz", + "integrity": "sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helpers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", - "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz", + "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==", "dev": true, "requires": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.6.tgz", + "integrity": "sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/traverse": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.5.tgz", + "integrity": "sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/highlight": { @@ -344,148 +1269,184 @@ "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", "dev": true }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz", + "integrity": "sha512-ZoJS2XCKPBfTmL122iP6NM9dOg+d4lc9fFk3zxc8iDjvt8Pk4+TlsHSKhIPf6X+L5ORCdBzqMZDjL/WHj7WknQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@babel/plugin-proposal-optional-chaining": "^7.14.5" + } + }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz", - "integrity": "sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.5.tgz", + "integrity": "sha512-tbD/CG3l43FIXxmu4a7RBe4zH7MLJ+S/lFowPFO7HetS2hyOZ/0nnnznegDuzFzfkyQYTxqdTH/hKmuBngaDAA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.10.4", - "@babel/plugin-syntax-async-generators": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.14.5", + "@babel/plugin-syntax-async-generators": "^7.8.4" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz", - "integrity": "sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz", + "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-proposal-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.5.tgz", + "integrity": "sha512-KBAH5ksEnYHCegqseI5N9skTdxgJdmDoAOc0uXa+4QMYKeZD0w5IARh4FMlTNtaHhbB8v+KzMdTgxMMzsIy6Yg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-proposal-decorators": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.10.5.tgz", - "integrity": "sha512-Sc5TAQSZuLzgY0664mMDn24Vw2P8g/VhyLyGPaWiHahhgLqeZvcGeyBZOrJW0oSKIK2mvQ22a1ENXBIQLhrEiQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.14.5.tgz", + "integrity": "sha512-LYz5nvQcvYeRVjui1Ykn28i+3aUiXwQ/3MGoEy0InTaz1pJo/lAzmIDXX+BQny/oufgHzJ6vnEEiXQ8KZjEVFg==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.5", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-decorators": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-decorators": "^7.14.5" } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz", - "integrity": "sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz", + "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-dynamic-import": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz", - "integrity": "sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz", + "integrity": "sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.14.5", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-proposal-json-strings": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz", - "integrity": "sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz", + "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz", - "integrity": "sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz", + "integrity": "sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.14.5", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz", - "integrity": "sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz", + "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz", - "integrity": "sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", + "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.14.5", "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz", - "integrity": "sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.5.tgz", + "integrity": "sha512-VzMyY6PWNPPT3pxc5hi9LloKNr4SSrVCg7Yr6aZpW4Ym07r7KqSU/QXYwjXLVxqwSv0t/XSXkFoKBPUkZ8vb2A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.10.4" + "@babel/compat-data": "^7.14.5", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.14.5" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz", - "integrity": "sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz", + "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz", - "integrity": "sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz", + "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, "@babel/plugin-proposal-private-methods": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz", - "integrity": "sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz", + "integrity": "sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-62EyfyA3WA0mZiF2e2IV9mc9Ghwxcg8YTu8BS4Wss4Y3PY725OmS9M0qLORbJwLqFtGh+jiE4wAmocK2CTUK2Q==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz", - "integrity": "sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz", + "integrity": "sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-syntax-async-generators": { @@ -498,21 +1459,30 @@ } }, "@babel/plugin-syntax-class-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", - "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-syntax-decorators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.10.4.tgz", - "integrity": "sha512-2NaoC6fAk2VMdhY1eerkfHV+lVYC1u8b+jmRJISqANCJlTxYy19HGdIkkQtix2UtkcPuPu+IlDgrVseZnU03bw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.14.5.tgz", + "integrity": "sha512-c4sZMRWL4GSvP1EXy0woIP7m4jkVcEuG8R1TOZxPBPtp4FSM/kiPZub9UIs/Jrb5ZAOzvTUSGYrWsrSu1JvoPw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-syntax-dynamic-import": { @@ -543,12 +1513,12 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz", - "integrity": "sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz", + "integrity": "sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-syntax-logical-assignment-operators": { @@ -605,422 +1575,634 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, "@babel/plugin-syntax-top-level-await": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz", - "integrity": "sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz", - "integrity": "sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz", + "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz", - "integrity": "sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz", + "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.10.4" + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.14.5" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz", - "integrity": "sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz", + "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.5.tgz", - "integrity": "sha512-6Ycw3hjpQti0qssQcA6AMSFDHeNJ++R6dIMnpRqUjFeBBTmTDPa8zgF90OVfTvAo11mXZTlVUViY1g8ffrURLg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.5.tgz", + "integrity": "sha512-LBYm4ZocNgoCqyxMLoOnwpsmQ18HWTQvql64t3GvMUzLQrNoV1BDG0lNftC8QKYERkZgCCT/7J5xWGObGAyHDw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-classes": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz", - "integrity": "sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.5.tgz", + "integrity": "sha512-J4VxKAMykM06K/64z9rwiL6xnBHgB1+FVspqvlgCdwD1KUbQNfszeKVVOMh59w3sztHYIZDgnhOC4WbdEfHFDA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-define-map": "^7.10.4", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.6.tgz", + "integrity": "sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/plugin-transform-computed-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz", - "integrity": "sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz", + "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-destructuring": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz", - "integrity": "sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.5.tgz", + "integrity": "sha512-wU9tYisEbRMxqDezKUqC9GleLycCRoUsai9ddlsq54r8QRLaeEhc+d+9DqCG+kV9W2GgQjTZESPTpn5bAFMDww==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz", - "integrity": "sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz", + "integrity": "sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz", - "integrity": "sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz", + "integrity": "sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz", - "integrity": "sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz", + "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-for-of": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz", - "integrity": "sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.14.5.tgz", + "integrity": "sha512-CfmqxSUZzBl0rSjpoQSFoR9UEj3HzbGuGNL21/iFTmjb5gFggJp3ph0xR1YBhexmLoKRHzgxuFvty2xdSt6gTA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz", - "integrity": "sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz", + "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.6.tgz", + "integrity": "sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/plugin-transform-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz", - "integrity": "sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz", + "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz", - "integrity": "sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz", + "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz", - "integrity": "sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz", + "integrity": "sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.10.5", - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz", - "integrity": "sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.5.tgz", + "integrity": "sha512-en8GfBtgnydoao2PS+87mKyw62k02k7kJ9ltbKe0fXTHrQmG6QZZflYuGI1VVG7sVpx4E1n7KBpNlPb8m78J+A==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-simple-access": "^7.14.5", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz", - "integrity": "sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.14.5.tgz", + "integrity": "sha512-mNMQdvBEE5DcMQaL5LbzXFMANrQjd2W7FPzg34Y4yEz7dBgdaC+9B84dSO+/1Wba98zoDbInctCDo4JGxz1VYA==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.10.4", - "@babel/helper-module-transforms": "^7.10.5", - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.5", "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + } } }, "@babel/plugin-transform-modules-umd": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz", - "integrity": "sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz", + "integrity": "sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz", - "integrity": "sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.5.tgz", + "integrity": "sha512-+Xe5+6MWFo311U8SchgeX5c1+lJM+eZDBZgD+tvXu9VVQPXwwVzeManMMjYX6xw2HczngfOSZjoFYKwdeB/Jvw==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.14.5" } }, "@babel/plugin-transform-new-target": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz", - "integrity": "sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz", + "integrity": "sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-object-super": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz", - "integrity": "sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz", + "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5" } }, "@babel/plugin-transform-parameters": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz", - "integrity": "sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.5.tgz", + "integrity": "sha512-Tl7LWdr6HUxTmzQtzuU14SqbgrSKmaR77M0OKyq4njZLQTPfOvzblNKyNkGwOfEFCEx7KeYHQHDI0P3F02IVkA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-property-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz", - "integrity": "sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz", + "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-regenerator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz", - "integrity": "sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz", + "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==", "dev": true, "requires": { "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz", - "integrity": "sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz", + "integrity": "sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-runtime": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.11.0.tgz", - "integrity": "sha512-LFEsP+t3wkYBlis8w6/kmnd6Kb1dxTd+wGJ8MlxTGzQo//ehtqlVL4S9DNUa53+dtPSQobN2CXx4d81FqC58cw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.14.5.tgz", + "integrity": "sha512-fPMBhh1AV8ZyneiCIA+wYYUH1arzlXR1UMcApjvchDhfKxhy2r2lReJv8uHEyihi4IFIGlr1Pdx7S5fkESDQsg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "resolve": "^1.8.1", - "semver": "^5.5.1" + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "babel-plugin-polyfill-corejs2": "^0.2.2", + "babel-plugin-polyfill-corejs3": "^0.2.2", + "babel-plugin-polyfill-regenerator": "^0.2.2", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz", - "integrity": "sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz", + "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-spread": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz", - "integrity": "sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw==", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz", + "integrity": "sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz", - "integrity": "sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz", + "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-regex": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-template-literals": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz", - "integrity": "sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz", + "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz", - "integrity": "sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz", + "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz", - "integrity": "sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz", + "integrity": "sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz", - "integrity": "sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz", + "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/preset-env": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.11.0.tgz", - "integrity": "sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.11.0", - "@babel/helper-compilation-targets": "^7.10.4", - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-proposal-async-generator-functions": "^7.10.4", - "@babel/plugin-proposal-class-properties": "^7.10.4", - "@babel/plugin-proposal-dynamic-import": "^7.10.4", - "@babel/plugin-proposal-export-namespace-from": "^7.10.4", - "@babel/plugin-proposal-json-strings": "^7.10.4", - "@babel/plugin-proposal-logical-assignment-operators": "^7.11.0", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", - "@babel/plugin-proposal-numeric-separator": "^7.10.4", - "@babel/plugin-proposal-object-rest-spread": "^7.11.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.10.4", - "@babel/plugin-proposal-optional-chaining": "^7.11.0", - "@babel/plugin-proposal-private-methods": "^7.10.4", - "@babel/plugin-proposal-unicode-property-regex": "^7.10.4", - "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.10.4", - "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.5.tgz", + "integrity": "sha512-ci6TsS0bjrdPpWGnQ+m4f+JSSzDKlckqKIJJt9UZ/+g7Zz9k0N8lYU8IeLg/01o2h8LyNZDMLGgRLDTxpudLsA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.14.5", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.14.5", + "@babel/plugin-proposal-async-generator-functions": "^7.14.5", + "@babel/plugin-proposal-class-properties": "^7.14.5", + "@babel/plugin-proposal-class-static-block": "^7.14.5", + "@babel/plugin-proposal-dynamic-import": "^7.14.5", + "@babel/plugin-proposal-export-namespace-from": "^7.14.5", + "@babel/plugin-proposal-json-strings": "^7.14.5", + "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", + "@babel/plugin-proposal-numeric-separator": "^7.14.5", + "@babel/plugin-proposal-object-rest-spread": "^7.14.5", + "@babel/plugin-proposal-optional-catch-binding": "^7.14.5", + "@babel/plugin-proposal-optional-chaining": "^7.14.5", + "@babel/plugin-proposal-private-methods": "^7.14.5", + "@babel/plugin-proposal-private-property-in-object": "^7.14.5", + "@babel/plugin-proposal-unicode-property-regex": "^7.14.5", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.10.4", - "@babel/plugin-transform-arrow-functions": "^7.10.4", - "@babel/plugin-transform-async-to-generator": "^7.10.4", - "@babel/plugin-transform-block-scoped-functions": "^7.10.4", - "@babel/plugin-transform-block-scoping": "^7.10.4", - "@babel/plugin-transform-classes": "^7.10.4", - "@babel/plugin-transform-computed-properties": "^7.10.4", - "@babel/plugin-transform-destructuring": "^7.10.4", - "@babel/plugin-transform-dotall-regex": "^7.10.4", - "@babel/plugin-transform-duplicate-keys": "^7.10.4", - "@babel/plugin-transform-exponentiation-operator": "^7.10.4", - "@babel/plugin-transform-for-of": "^7.10.4", - "@babel/plugin-transform-function-name": "^7.10.4", - "@babel/plugin-transform-literals": "^7.10.4", - "@babel/plugin-transform-member-expression-literals": "^7.10.4", - "@babel/plugin-transform-modules-amd": "^7.10.4", - "@babel/plugin-transform-modules-commonjs": "^7.10.4", - "@babel/plugin-transform-modules-systemjs": "^7.10.4", - "@babel/plugin-transform-modules-umd": "^7.10.4", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.10.4", - "@babel/plugin-transform-new-target": "^7.10.4", - "@babel/plugin-transform-object-super": "^7.10.4", - "@babel/plugin-transform-parameters": "^7.10.4", - "@babel/plugin-transform-property-literals": "^7.10.4", - "@babel/plugin-transform-regenerator": "^7.10.4", - "@babel/plugin-transform-reserved-words": "^7.10.4", - "@babel/plugin-transform-shorthand-properties": "^7.10.4", - "@babel/plugin-transform-spread": "^7.11.0", - "@babel/plugin-transform-sticky-regex": "^7.10.4", - "@babel/plugin-transform-template-literals": "^7.10.4", - "@babel/plugin-transform-typeof-symbol": "^7.10.4", - "@babel/plugin-transform-unicode-escapes": "^7.10.4", - "@babel/plugin-transform-unicode-regex": "^7.10.4", - "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.11.0", - "browserslist": "^4.12.0", - "core-js-compat": "^3.6.2", - "invariant": "^2.2.2", - "levenary": "^1.1.1", - "semver": "^5.5.0" + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.14.5", + "@babel/plugin-transform-async-to-generator": "^7.14.5", + "@babel/plugin-transform-block-scoped-functions": "^7.14.5", + "@babel/plugin-transform-block-scoping": "^7.14.5", + "@babel/plugin-transform-classes": "^7.14.5", + "@babel/plugin-transform-computed-properties": "^7.14.5", + "@babel/plugin-transform-destructuring": "^7.14.5", + "@babel/plugin-transform-dotall-regex": "^7.14.5", + "@babel/plugin-transform-duplicate-keys": "^7.14.5", + "@babel/plugin-transform-exponentiation-operator": "^7.14.5", + "@babel/plugin-transform-for-of": "^7.14.5", + "@babel/plugin-transform-function-name": "^7.14.5", + "@babel/plugin-transform-literals": "^7.14.5", + "@babel/plugin-transform-member-expression-literals": "^7.14.5", + "@babel/plugin-transform-modules-amd": "^7.14.5", + "@babel/plugin-transform-modules-commonjs": "^7.14.5", + "@babel/plugin-transform-modules-systemjs": "^7.14.5", + "@babel/plugin-transform-modules-umd": "^7.14.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.5", + "@babel/plugin-transform-new-target": "^7.14.5", + "@babel/plugin-transform-object-super": "^7.14.5", + "@babel/plugin-transform-parameters": "^7.14.5", + "@babel/plugin-transform-property-literals": "^7.14.5", + "@babel/plugin-transform-regenerator": "^7.14.5", + "@babel/plugin-transform-reserved-words": "^7.14.5", + "@babel/plugin-transform-shorthand-properties": "^7.14.5", + "@babel/plugin-transform-spread": "^7.14.5", + "@babel/plugin-transform-sticky-regex": "^7.14.5", + "@babel/plugin-transform-template-literals": "^7.14.5", + "@babel/plugin-transform-typeof-symbol": "^7.14.5", + "@babel/plugin-transform-unicode-escapes": "^7.14.5", + "@babel/plugin-transform-unicode-regex": "^7.14.5", + "@babel/preset-modules": "^0.1.4", + "@babel/types": "^7.14.5", + "babel-plugin-polyfill-corejs2": "^0.2.2", + "babel-plugin-polyfill-corejs3": "^0.2.2", + "babel-plugin-polyfill-regenerator": "^0.2.2", + "core-js-compat": "^3.14.0", + "semver": "^6.3.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "@babel/preset-modules": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", - "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", + "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1039,11 +2221,11 @@ } }, "@babel/runtime-corejs3": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.11.2.tgz", - "integrity": "sha512-qh5IR+8VgFz83VBa6OkaET6uN/mJOhHONuy3m1sgF0CV6mXdPSEBdA7e1eUbVvyNtANjMbg22JUv71BaDXLY6A==", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.6.tgz", + "integrity": "sha512-Xl8SPYtdjcMoCsIM4teyVRg7jIcgl8F2kRtoCcXuHzXswt9UxZCS6BzRo8fcnCuP6u2XtPgvyonmEPF57Kxo9Q==", "requires": { - "core-js-pure": "^3.0.0", + "core-js-pure": "^3.14.0", "regenerator-runtime": "^0.13.4" } }, @@ -1131,65 +2313,67 @@ } }, "@braintree/sanitize-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-5.0.0.tgz", - "integrity": "sha512-WmKrB/575EJCzbeSJR3YQ5sET5FaizeljLRw1382qVUeGqzuWBgIS+AF5a0FO51uQTrDpoRgvuHC2IWVsgwkkA==" - }, - "@fortawesome/fontawesome-free": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.14.0.tgz", - "integrity": "sha512-OfdMsF+ZQgdKHP9jUbmDcRrP0eX90XXrsXIdyjLbkmSBzmMXPABB8eobUJtivaupucYaByz6WNe1PI1JuYm3qA==", - "dev": true - }, - "@hapi/address": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", - "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==", - "dev": true - }, - "@hapi/bourne": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", - "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==", - "dev": true + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-5.0.2.tgz", + "integrity": "sha512-NBEJlHWrhQucLhZGHtSxM2loSaNUMajC7KOYJLyfcdW/6goVoff2HoYI3bz8YCDN0wKGbxtUL0gx2dvHpvnWlw==" }, - "@hapi/hoek": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", - "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==", - "dev": true - }, - "@hapi/joi": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", - "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", - "dev": true, - "requires": { - "@hapi/address": "2.x.x", - "@hapi/bourne": "1.x.x", - "@hapi/hoek": "8.x.x", - "@hapi/topo": "3.x.x" - } - }, - "@hapi/topo": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", - "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", + "@eslint/eslintrc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", "dev": true, "requires": { - "@hapi/hoek": "^8.3.0" + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } } }, - "@intervolga/optimize-cssnano-plugin": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@intervolga/optimize-cssnano-plugin/-/optimize-cssnano-plugin-1.0.6.tgz", - "integrity": "sha512-zN69TnSr0viRSU6cEDIcuPcP67QcpQ6uHACg58FiN9PDrU6SLyGW3MR4tiISbYxy1kDWAVPwD+XwQTWE5cigAA==", - "dev": true, - "requires": { - "cssnano": "^4.0.0", - "cssnano-preset-default": "^4.0.0", - "postcss": "^7.0.0" - } + "@fortawesome/fontawesome-free": { + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.3.tgz", + "integrity": "sha512-rFnSUN/QOtnOAgqFRooTA3H57JLDm0QEG/jPdk+tLQNL/eWd+Aok8g3qCI+Q1xuDPWpGW/i9JySpJVsq8Q0s9w==", + "dev": true }, "@kyleshockey/object-assign-deep": { "version": "0.4.2", @@ -1210,16 +2394,6 @@ "integrity": "sha512-m2sbAs+SMwRnWpkMriBxEulwuhmqRyh6X+hdOZlqSxYZUM2C2TaDnQ4gcilzdoAgru2XYnWViZ/xPuSDGgRXVw==", "dev": true }, - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - } - }, "@nodelib/fs.scandir": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", @@ -1239,9 +2413,9 @@ } }, "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "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": { @@ -1255,12 +2429,13 @@ } }, "@npmcli/move-file": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz", - "integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", "dev": true, "requires": { - "mkdirp": "^1.0.4" + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" }, "dependencies": { "mkdirp": { @@ -1268,59 +2443,73 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true - } - } - }, - "@soda/friendly-errors-webpack-plugin": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.1.tgz", - "integrity": "sha512-cWKrGaFX+rfbMrAxVv56DzhPNqOJPZuNIS2HGMELtgGzb+vsMzyig9mml5gZ/hr2BGtSLV+dP2LUEuAL8aG2mQ==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "error-stack-parser": "^2.0.0", - "string-width": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "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": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "glob": "^7.1.3" } - }, + } + } + }, + "@polka/url": { + "version": "1.0.0-next.15", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.15.tgz", + "integrity": "sha512-15spi3V28QdevleWBNXE4pIls3nFZmBbUGrW9IVPwiQczuSb9n76TCB4bsk8TSel+I1OkHEdPhu5QKMfY6rQHA==", + "dev": true + }, + "@sideway/address": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", + "integrity": "sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA==", + "dev": true, + "requires": { + "@hapi/hoek": "^9.0.0" + }, + "dependencies": { + "@hapi/hoek": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", + "integrity": "sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==", + "dev": true + } + } + }, + "@sideway/formula": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", + "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==", + "dev": true + }, + "@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "dev": true + }, + "@soda/friendly-errors-webpack-plugin": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.0.tgz", + "integrity": "sha512-RLotfx6k1+nfLacwNCenj7VnTMPxVwYKoGOcffMFoJDKM8tXzBiCN0hMHFJNnoAojduYAsxuiMm0EOMixgiRow==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "error-stack-parser": "^2.0.2", + "string-width": "^2.0.0", + "strip-ansi": "^5" + }, + "dependencies": { "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^4.1.0" } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true } } }, @@ -1330,12 +2519,90 @@ "integrity": "sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w==", "dev": true }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "@trysound/sax": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.1.1.tgz", + "integrity": "sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow==", + "dev": true + }, + "@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", + "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect-history-api-fallback": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.4.tgz", + "integrity": "sha512-Kf8v0wljR5GSCOCF/VQWdV3ZhKOVA73drXtY3geMTQgHy9dgqQ0dLrf31M0hcuWkhFzK5sP0kkS3mJzcKVtZbw==", + "dev": true, + "requires": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "@types/eslint": { + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.13.tgz", + "integrity": "sha512-LKmQCWAlnVHvvXq4oasNUMTJJb2GwSyTY8+1C7OH5ILR8mPLaljv1jxL1bXW3xB3jFbQxTKxJAvI8PyjB09aBg==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", + "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "0.0.47", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", + "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==", "dev": true }, + "@types/express": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.12.tgz", + "integrity": "sha512-pTYas6FrP15B1Oa0bkN5tQMNqOcVXa9j4FTFtO8DWI9kppKib+6NJtfTOOLcwxuuYvcX2+dVG6et1SxW/Kc17Q==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.21.tgz", + "integrity": "sha512-gwCiEZqW6f7EoR8TTEfalyEhb1zA5jQJnRngr97+3pzMaO1RKoI1w2bw07TK72renMUVWcWS5mLI6rk1NqN0nA==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "@types/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", @@ -1346,22 +2613,57 @@ "@types/node": "*" } }, + "@types/hast": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.1.tgz", + "integrity": "sha512-viwwrB+6xGzw+G1eWpF9geV3fnsDgXqHG+cqgiHrvQfDUW5hzhCyV7Sy3UJxhfRFBsgky2SSW33qi/YrIkjX5Q==", + "requires": { + "@types/unist": "*" + } + }, + "@types/html-minifier-terser": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", + "integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==", + "dev": true + }, + "@types/http-proxy": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.6.tgz", + "integrity": "sha512-+qsjqR75S/ib0ig0R9WN+CDoZeOBU6F2XLewgC4KVgdXiNHiKKHFEMRHOrs5PbYE97D5vataw5wPj4KLYfUkuQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/json-schema": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", "dev": true }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==", + "dev": true + }, + "@types/minimist": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", + "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", "dev": true }, "@types/node": { - "version": "14.0.27", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz", - "integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==", + "version": "15.12.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz", + "integrity": "sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==", "dev": true }, "@types/normalize-package-data": { @@ -1370,187 +2672,378 @@ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "dev": true }, - "@types/q": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", - "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "@types/react": { - "version": "16.4.6", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.4.6.tgz", - "integrity": "sha512-9LDZdhsuKSc+DjY65SjBkA958oBWcTWSVWAd2cD9XqKBjhGw1KzAkRhWRw2eIsXvaIE/TOTjjKMFVC+JA1iU4g==", - "optional": true, + "@types/qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", + "dev": true + }, + "@types/serve-static": { + "version": "1.13.9", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", + "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/source-list-map": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", + "dev": true + }, + "@types/tapable": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.7.tgz", + "integrity": "sha512-0VBprVqfgFD7Ehb2vd8Lh9TG3jP98gvr8rgehQqzztZNI7o8zS8Ad4jyZneKELphpuE212D8J70LnSNQSyO6bQ==", + "dev": true + }, + "@types/uglify-js": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.0.tgz", + "integrity": "sha512-EGkrJD5Uy+Pg0NUR8uA4bJ5WMfljyad0G+784vLCNUkD+QwOJXUbBYExXfVGf7YtyzdQp3L/XMYcliB987kL5Q==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@types/unist": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", + "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" + }, + "@types/webpack": { + "version": "4.41.29", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.29.tgz", + "integrity": "sha512-6pLaORaVNZxiB3FSHbyBiWM7QdazAWda1zvAq4SbZObZqHSDbWLi62iFdblVea6SK9eyBIVp5yHhKt/yNQdR7Q==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/tapable": "^1", + "@types/uglify-js": "*", + "@types/webpack-sources": "*", + "anymatch": "^3.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@types/webpack-dev-server": { + "version": "3.11.4", + "resolved": "https://registry.npmjs.org/@types/webpack-dev-server/-/webpack-dev-server-3.11.4.tgz", + "integrity": "sha512-DCKORHjqNNVuMIDWFrlljftvc9CL0+09p3l7lBpb8dRqgN5SmvkWCY4MPKxoI6wJgdRqohmoNbptkxqSKAzLRg==", + "dev": true, + "requires": { + "@types/connect-history-api-fallback": "*", + "@types/express": "*", + "@types/serve-static": "*", + "@types/webpack": "^4", + "http-proxy-middleware": "^1.0.0" + } + }, + "@types/webpack-sources": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.0.tgz", + "integrity": "sha512-LXn/oYIpBeucgP1EIJbKQ2/4ZmpvRl+dlrFdX7+94SKRUV3Evy3FsfMZY318vGhkWUS5MPhtOM3w1/hCOAOXcg==", + "dev": true, "requires": { - "csstype": "^2.2.0" + "@types/node": "*", + "@types/source-list-map": "*", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } } }, "@vue/babel-helper-vue-jsx-merge-props": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz", - "integrity": "sha512-6tyf5Cqm4m6v7buITuwS+jHzPlIPxbFzEhXR5JGZpbrvOcp1hiQKckd305/3C7C36wFekNTQSxAtgeM0j0yoUw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz", + "integrity": "sha512-QOi5OW45e2R20VygMSNhyQHvpdUwQZqGPc748JLGCYEy+yp8fNFNdbNIGAgZmi9e+2JHPd6i6idRuqivyicIkA==", "dev": true }, + "@vue/babel-helper-vue-transform-on": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz", + "integrity": "sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==", + "dev": true + }, + "@vue/babel-plugin-jsx": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.0.6.tgz", + "integrity": "sha512-RzYsvBhzKUmY2YG6LoV+W5PnlnkInq0thh1AzCmewwctAgGN6e9UFon6ZrQQV1CO5G5PeME7MqpB+/vvGg0h4g==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "@vue/babel-helper-vue-transform-on": "^1.0.2", + "camelcase": "^6.0.0", + "html-tags": "^3.1.0", + "svg-tags": "^1.0.0" + } + }, "@vue/babel-plugin-transform-vue-jsx": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.1.2.tgz", - "integrity": "sha512-YfdaoSMvD1nj7+DsrwfTvTnhDXI7bsuh+Y5qWwvQXlD24uLgnsoww3qbiZvWf/EoviZMrvqkqN4CBw0W3BWUTQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.2.1.tgz", + "integrity": "sha512-HJuqwACYehQwh1fNT8f4kyzqlNMpBuUK4rSiSES5D4QsYncv5fxFsLyrxFPG2ksO7t5WP+Vgix6tt6yKClwPzA==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", + "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", "html-tags": "^2.0.0", "lodash.kebabcase": "^4.1.1", "svg-tags": "^1.0.0" + }, + "dependencies": { + "html-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", + "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", + "dev": true + } } }, "@vue/babel-preset-app": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-4.4.6.tgz", - "integrity": "sha512-urIa6Qk3lKacLvscrzxMNyYlTqKFcPAUo5MohOjv1ISZ9PssHw693WTOrqSC0XksdMLtp/rnLvc6l5G8Muk0lw==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-5.0.0-beta.2.tgz", + "integrity": "sha512-PUBrNTgcRkEfrIfxBzD9FDErw3kF3qDqq9vmMcESJ/DiNuAAxS0Y1BmDSkJ4QJnIPRGF2FSQ2AYtIvGm2MD+KA==", "dev": true, "requires": { - "@babel/core": "^7.9.6", - "@babel/helper-compilation-targets": "^7.9.6", - "@babel/helper-module-imports": "^7.8.3", - "@babel/plugin-proposal-class-properties": "^7.8.3", - "@babel/plugin-proposal-decorators": "^7.8.3", + "@babel/core": "^7.12.16", + "@babel/helper-compilation-targets": "^7.12.16", + "@babel/helper-module-imports": "^7.12.13", + "@babel/plugin-proposal-class-properties": "^7.12.13", + "@babel/plugin-proposal-decorators": "^7.12.13", "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-jsx": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.9.6", - "@babel/preset-env": "^7.9.6", - "@babel/runtime": "^7.9.6", + "@babel/plugin-syntax-jsx": "^7.12.13", + "@babel/plugin-transform-runtime": "^7.12.15", + "@babel/preset-env": "^7.12.16", + "@babel/runtime": "^7.12.13", + "@vue/babel-plugin-jsx": "^1.0.3", "@vue/babel-preset-jsx": "^1.1.2", "babel-plugin-dynamic-import-node": "^2.3.3", - "core-js": "^3.6.5", - "core-js-compat": "^3.6.5", - "semver": "^6.1.0" + "core-js": "^3.8.3", + "core-js-compat": "^3.8.3", + "semver": "^7.3.4" }, "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "@babel/runtime": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz", + "integrity": "sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "core-js": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.14.0.tgz", + "integrity": "sha512-3s+ed8er9ahK+zJpp9ZtuVcDoFzHNiZsPbNAAE4KXgrRHbjSqqNN6xGSXq6bq7TZIbKj4NLrLb6bJ5i+vSVjHA==", "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, "@vue/babel-preset-jsx": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.1.2.tgz", - "integrity": "sha512-zDpVnFpeC9YXmvGIDSsKNdL7qCG2rA3gjywLYHPCKDT10erjxF4U+6ay9X6TW5fl4GsDlJp9bVfAVQAAVzxxvQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.2.4.tgz", + "integrity": "sha512-oRVnmN2a77bYDJzeGSt92AuHXbkIxbf/XXSE3klINnh9AXBmVS1DGa1f0d+dDYpLfsAKElMnqKTQfKn7obcL4w==", + "dev": true, + "requires": { + "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", + "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", + "@vue/babel-sugar-composition-api-inject-h": "^1.2.1", + "@vue/babel-sugar-composition-api-render-instance": "^1.2.4", + "@vue/babel-sugar-functional-vue": "^1.2.2", + "@vue/babel-sugar-inject-h": "^1.2.2", + "@vue/babel-sugar-v-model": "^1.2.3", + "@vue/babel-sugar-v-on": "^1.2.3" + } + }, + "@vue/babel-sugar-composition-api-inject-h": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-inject-h/-/babel-sugar-composition-api-inject-h-1.2.1.tgz", + "integrity": "sha512-4B3L5Z2G+7s+9Bwbf+zPIifkFNcKth7fQwekVbnOA3cr3Pq71q71goWr97sk4/yyzH8phfe5ODVzEjX7HU7ItQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@vue/babel-sugar-composition-api-render-instance": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-render-instance/-/babel-sugar-composition-api-render-instance-1.2.4.tgz", + "integrity": "sha512-joha4PZznQMsxQYXtR3MnTgCASC9u3zt9KfBxIeuI5g2gscpTsSKRDzWQt4aqNIpx6cv8On7/m6zmmovlNsG7Q==", "dev": true, "requires": { - "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", - "@vue/babel-sugar-functional-vue": "^1.1.2", - "@vue/babel-sugar-inject-h": "^1.1.2", - "@vue/babel-sugar-v-model": "^1.1.2", - "@vue/babel-sugar-v-on": "^1.1.2" + "@babel/plugin-syntax-jsx": "^7.2.0" } }, "@vue/babel-sugar-functional-vue": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.1.2.tgz", - "integrity": "sha512-YhmdJQSVEFF5ETJXzrMpj0nkCXEa39TvVxJTuVjzvP2rgKhdMmQzlJuMv/HpadhZaRVMCCF3AEjjJcK5q/cYzQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.2.2.tgz", + "integrity": "sha512-JvbgGn1bjCLByIAU1VOoepHQ1vFsroSA/QkzdiSs657V79q6OwEWLCQtQnEXD/rLTA8rRit4rMOhFpbjRFm82w==", "dev": true, "requires": { "@babel/plugin-syntax-jsx": "^7.2.0" } }, "@vue/babel-sugar-inject-h": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.1.2.tgz", - "integrity": "sha512-VRSENdTvD5htpnVp7i7DNuChR5rVMcORdXjvv5HVvpdKHzDZAYiLSD+GhnhxLm3/dMuk8pSzV+k28ECkiN5m8w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.2.2.tgz", + "integrity": "sha512-y8vTo00oRkzQTgufeotjCLPAvlhnpSkcHFEp60+LJUwygGcd5Chrpn5480AQp/thrxVm8m2ifAk0LyFel9oCnw==", "dev": true, "requires": { "@babel/plugin-syntax-jsx": "^7.2.0" } }, "@vue/babel-sugar-v-model": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.1.2.tgz", - "integrity": "sha512-vLXPvNq8vDtt0u9LqFdpGM9W9IWDmCmCyJXuozlq4F4UYVleXJ2Fa+3JsnTZNJcG+pLjjfnEGHci2339Kj5sGg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.2.3.tgz", + "integrity": "sha512-A2jxx87mySr/ulAsSSyYE8un6SIH0NWHiLaCWpodPCVOlQVODCaSpiR4+IMsmBr73haG+oeCuSvMOM+ttWUqRQ==", "dev": true, "requires": { "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", + "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", + "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", "camelcase": "^5.0.0", "html-tags": "^2.0.0", "svg-tags": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "html-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", + "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", + "dev": true + } } }, "@vue/babel-sugar-v-on": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.1.2.tgz", - "integrity": "sha512-T8ZCwC8Jp2uRtcZ88YwZtZXe7eQrJcfRq0uTFy6ShbwYJyz5qWskRFoVsdTi9o0WEhmQXxhQUewodOSCUPVmsQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.2.3.tgz", + "integrity": "sha512-kt12VJdz/37D3N3eglBywV8GStKNUhNrsxChXIV+o0MwVXORYuhDTHJRKPgLJRb/EY3vM2aRFQdxJBp9CLikjw==", "dev": true, "requires": { "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", + "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", "camelcase": "^5.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } } }, "@vue/cli-overlay": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@vue/cli-overlay/-/cli-overlay-4.4.6.tgz", - "integrity": "sha512-fzjg2gWQt+jw5fyLsD9HZNxGNQgZjLDI2s9bLWJwRucdfmncSi9neqA0TZyszGrgcJA4Qu4V5KgV0qwVSBYCaw==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/cli-overlay/-/cli-overlay-5.0.0-beta.2.tgz", + "integrity": "sha512-chdiOnN6eQ+sZw6atP1t8mp9GP/18g5BaxQtbo85ildbJ7VWbyyMSpAXZyHrDEVizJXa07nxw+fG6O1+ghdOiw==", "dev": true }, "@vue/cli-plugin-babel": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@vue/cli-plugin-babel/-/cli-plugin-babel-4.4.6.tgz", - "integrity": "sha512-9cX9mN+4DIbcqw3rV6UBOA0t5zikIkrBLQloUzsOBOu5Xb7/UoD7inInFj7bnyHUflr5LqbdWJ+etCQcWAIIXA==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-babel/-/cli-plugin-babel-5.0.0-beta.2.tgz", + "integrity": "sha512-EuEgQNN0IjdGb+8C66XzxLG2Xxz2A7PWzin6CY8AUSFuZmk4RMm6uFT/QqZ3wmOlh2hdDH7ze+QWnR9y3nrNuw==", "dev": true, "requires": { - "@babel/core": "^7.9.6", - "@vue/babel-preset-app": "^4.4.6", - "@vue/cli-shared-utils": "^4.4.6", - "babel-loader": "^8.1.0", - "cache-loader": "^4.1.0", - "thread-loader": "^2.1.3", - "webpack": "^4.0.0" + "@babel/core": "^7.12.16", + "@vue/babel-preset-app": "^5.0.0-beta.2", + "@vue/cli-shared-utils": "^5.0.0-beta.2", + "babel-loader": "^8.2.2", + "thread-loader": "^3.0.0", + "webpack": "^5.22.0" } }, "@vue/cli-plugin-eslint": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@vue/cli-plugin-eslint/-/cli-plugin-eslint-4.4.6.tgz", - "integrity": "sha512-3a9rVpOKPQsDgAlRkhmBMHboGobivG/47BbQGE66Z8YJxrgF/AWikP3Jy67SmxtszRkyiWfw4aJFRV9r3MzffQ==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-eslint/-/cli-plugin-eslint-5.0.0-beta.2.tgz", + "integrity": "sha512-qDmvHq1PO4MeII8stAtIcU0PQ3swmE2mN1yTnO4rATdtelkRtpgKGkc+f1TeLiAcGptGigPeFvWpzsovo0qVaA==", "dev": true, "requires": { - "@vue/cli-shared-utils": "^4.4.6", - "eslint-loader": "^2.2.1", - "globby": "^9.2.0", - "inquirer": "^7.1.0", - "webpack": "^4.0.0", + "@vue/cli-shared-utils": "^5.0.0-beta.2", + "eslint-webpack-plugin": "2.4.3", + "globby": "^11.0.2", + "inquirer": "^8.0.0", + "webpack": "^5.22.0", "yorkie": "^2.0.0" }, "dependencies": { "ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "requires": { - "type-fest": "^0.11.0" + "type-fest": "^0.21.3" } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -1603,21 +3096,22 @@ "dev": true }, "inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.1.0.tgz", + "integrity": "sha512-1nKYPoalt1vMBfCMtpomsUc32wmOoWXAoq3kM/5iTfxyQ2f/BxjixQpC+mbZ7BI0JUXHED4/XPXekDVtJNpXYw==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", + "chalk": "^4.1.1", "cli-cursor": "^3.1.0", "cli-width": "^3.0.0", "external-editor": "^3.0.3", "figures": "^3.0.0", - "lodash": "^4.17.19", + "lodash": "^4.17.21", "mute-stream": "0.0.8", + "ora": "^5.3.0", "run-async": "^2.4.0", - "rxjs": "^6.6.0", + "rxjs": "^6.6.6", "string-width": "^4.1.0", "strip-ansi": "^6.0.0", "through": "^2.3.6" @@ -1642,9 +3136,9 @@ "dev": true }, "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { "mimic-fn": "^2.1.0" @@ -1667,18 +3161,18 @@ "dev": true }, "rxjs": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", - "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, "requires": { "tslib": "^1.9.0" } }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -1687,304 +3181,459 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } }, "type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true } } }, "@vue/cli-plugin-router": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@vue/cli-plugin-router/-/cli-plugin-router-4.4.6.tgz", - "integrity": "sha512-TkLdn0ZYo3zgn78Rk8doPlR+4UkGjGW2R1eGEaZEkue/mw2VhUWtTk9cKLZaYrw0eY8Ro/j+OV6mD+scyrairg==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-router/-/cli-plugin-router-5.0.0-beta.2.tgz", + "integrity": "sha512-UFS5Z62FCOsE/obWlThlvzvKpbPxrx6BteGoeTYX9c37NxnxF5AhuP6gHb9AeIew88a5GF1A+s0SOObqovM6Ew==", "dev": true, "requires": { - "@vue/cli-shared-utils": "^4.4.6" + "@vue/cli-shared-utils": "^5.0.0-beta.2" } }, "@vue/cli-plugin-vuex": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.4.6.tgz", - "integrity": "sha512-Ho0YzUivn8BLPqFoFypntR8CMTEXYYHVr0GdnZW99XL+DbGw75f+tJfnrV9UFHDTfvZt7uewKiXDMlrzQ0l3Ug==", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-5.0.0-beta.2.tgz", + "integrity": "sha512-Gth9jHcY0azWvWU20WVC1dXrGlwg7Kn/OHaNaTWgqJXeJi7fNmUxUyt8Yif0u1t+r/mhU6jBqKVbAujSfuzcPA==", "dev": true }, "@vue/cli-service": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@vue/cli-service/-/cli-service-4.4.6.tgz", - "integrity": "sha512-k5OFGh2NnvRymCyq9DfBiNJvECUuun3pl5KMm3557IZyA5E5csv+RHoSW3dX8HHe0zXq18g52VswP1llvR9POw==", - "dev": true, - "requires": { - "@intervolga/optimize-cssnano-plugin": "^1.0.5", - "@soda/friendly-errors-webpack-plugin": "^1.7.1", - "@soda/get-current-script": "^1.0.0", - "@vue/cli-overlay": "^4.4.6", - "@vue/cli-plugin-router": "^4.4.6", - "@vue/cli-plugin-vuex": "^4.4.6", - "@vue/cli-shared-utils": "^4.4.6", + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/cli-service/-/cli-service-5.0.0-beta.2.tgz", + "integrity": "sha512-U8l1FK4j0hB7EGFLreemZK8uSzSphd0ISleZP97bTbXvSWf3Orr9Z729ls6fnjEeUeMgGXaJePQByBI+Nb55cA==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.12.16", + "@soda/friendly-errors-webpack-plugin": "^1.8.0", + "@soda/get-current-script": "^1.0.2", + "@types/minimist": "^1.2.0", + "@types/webpack-dev-server": "^3.11.0", + "@vue/cli-overlay": "^5.0.0-beta.2", + "@vue/cli-plugin-router": "^5.0.0-beta.2", + "@vue/cli-plugin-vuex": "^5.0.0-beta.2", + "@vue/cli-shared-utils": "^5.0.0-beta.2", "@vue/component-compiler-utils": "^3.1.2", - "@vue/preload-webpack-plugin": "^1.1.0", - "@vue/web-component-wrapper": "^1.2.0", - "acorn": "^7.2.0", - "acorn-walk": "^7.1.1", + "@vue/vue-loader-v15": "npm:vue-loader@^15.9.7", + "@vue/web-component-wrapper": "^1.3.0", + "acorn": "^8.0.5", + "acorn-walk": "^8.0.2", "address": "^1.1.2", - "autoprefixer": "^9.8.0", - "browserslist": "^4.12.0", + "autoprefixer": "^10.2.4", + "browserslist": "^4.16.3", "cache-loader": "^4.1.0", "case-sensitive-paths-webpack-plugin": "^2.3.0", - "cli-highlight": "^2.1.4", + "cli-highlight": "^2.1.10", "clipboardy": "^2.3.0", - "cliui": "^6.0.0", - "copy-webpack-plugin": "^5.1.1", - "css-loader": "^3.5.3", - "cssnano": "^4.1.10", + "cliui": "^7.0.4", + "copy-webpack-plugin": "^8.0.0", + "css-loader": "^5.1.1", + "css-minimizer-webpack-plugin": "^2.0.0", + "cssnano": "^5.0.0", "debug": "^4.1.1", - "default-gateway": "^5.0.5", + "default-gateway": "^6.0.3", "dotenv": "^8.2.0", "dotenv-expand": "^5.1.0", - "file-loader": "^4.2.0", - "fs-extra": "^7.0.1", - "globby": "^9.2.0", + "file-loader": "^6.1.1", + "fs-extra": "^9.1.0", + "globby": "^11.0.2", "hash-sum": "^2.0.0", - "html-webpack-plugin": "^3.2.0", + "html-webpack-plugin": "^5.1.0", + "is-file-esm": "^1.0.0", "launch-editor-middleware": "^2.2.1", "lodash.defaultsdeep": "^4.6.1", "lodash.mapvalues": "^4.6.0", - "lodash.transform": "^4.6.0", - "mini-css-extract-plugin": "^0.9.0", + "mini-css-extract-plugin": "^1.3.7", "minimist": "^1.2.5", - "pnp-webpack-plugin": "^1.6.4", + "module-alias": "^2.2.2", "portfinder": "^1.0.26", - "postcss-loader": "^3.0.0", - "ssri": "^7.1.0", - "terser-webpack-plugin": "^2.3.6", - "thread-loader": "^2.1.3", - "url-loader": "^2.2.0", - "vue-loader": "^15.9.2", - "vue-style-loader": "^4.1.2", - "webpack": "^4.0.0", - "webpack-bundle-analyzer": "^3.8.0", - "webpack-chain": "^6.4.0", - "webpack-dev-server": "^3.11.0", - "webpack-merge": "^4.2.2" + "postcss": "^8.2.6", + "postcss-loader": "^5.0.0", + "ssri": "^8.0.1", + "terser-webpack-plugin": "^5.1.1", + "thread-loader": "^3.0.0", + "url-loader": "^4.1.1", + "vue-loader": "^16.1.2", + "vue-style-loader": "^4.1.3", + "webpack": "^5.22.0", + "webpack-bundle-analyzer": "^4.4.0", + "webpack-chain": "^6.5.1", + "webpack-dev-server": "^3.11.2", + "webpack-merge": "^5.7.3", + "webpack-virtual-modules": "^0.4.2" }, "dependencies": { - "acorn": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", - "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "@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 }, - "ajv": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", - "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "@vue/cli-plugin-router": { + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-router/-/cli-plugin-router-5.0.0-beta.2.tgz", + "integrity": "sha512-UFS5Z62FCOsE/obWlThlvzvKpbPxrx6BteGoeTYX9c37NxnxF5AhuP6gHb9AeIew88a5GF1A+s0SOObqovM6Ew==", "dev": true, "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "@vue/cli-shared-utils": "^5.0.0-beta.2" } }, - "cacache": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz", - "integrity": "sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w==", - "dev": true, - "requires": { - "chownr": "^1.1.2", - "figgy-pudding": "^3.5.1", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.2", - "infer-owner": "^1.0.4", - "lru-cache": "^5.1.1", - "minipass": "^3.0.0", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "p-map": "^3.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^2.7.1", - "ssri": "^7.0.0", - "unique-filename": "^1.1.1" + "@vue/cli-shared-utils": { + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-5.0.0-beta.2.tgz", + "integrity": "sha512-gYznhuPIsSpX6M0LE6GTOsy/V9xG0qEZoBw9bSCC5/eEg+JOwoBXqDdqOXrTPEc6oc0zjPM3lk9zlwsJQ4cUcg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "execa": "^1.0.0", + "joi": "^17.4.0", + "launch-editor": "^2.2.1", + "lru-cache": "^6.0.0", + "node-fetch": "^2.6.1", + "node-ipc": "^9.1.1", + "open": "^8.0.2", + "ora": "^5.3.0", + "read-pkg": "^5.1.1", + "semver": "^7.3.4", + "strip-ansi": "^6.0.0" } }, - "copy-webpack-plugin": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz", - "integrity": "sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==", + "@vue/vue-loader-v15": { + "version": "npm:vue-loader@15.9.8", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.8.tgz", + "integrity": "sha512-GwSkxPrihfLR69/dSV3+5CdMQ0D+jXg8Ma1S4nQXKJAznYFX14vHdc/NetQc34Dw+rBbIJyP7JOuVb9Fhprvog==", "dev": true, "requires": { - "cacache": "^12.0.3", - "find-cache-dir": "^2.1.0", - "glob-parent": "^3.1.0", - "globby": "^7.1.1", - "is-glob": "^4.0.1", - "loader-utils": "^1.2.3", - "minimatch": "^3.0.4", - "normalize-path": "^3.0.0", - "p-limit": "^2.2.1", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", - "webpack-log": "^2.0.0" + "@vue/component-compiler-utils": "^3.1.0", + "hash-sum": "^1.0.2", + "loader-utils": "^1.1.0", + "vue-hot-reload-api": "^2.3.0", + "vue-style-loader": "^4.1.0" }, "dependencies": { - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "globby": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", - "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "dir-glob": "^2.0.0", - "glob": "^7.1.2", - "ignore": "^3.3.5", - "pify": "^3.0.0", - "slash": "^1.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", "dev": true }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "find-up": "^3.0.0" + "minimist": "^1.2.0" } }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", "dev": true, "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + } + } + }, + "@webassemblyjs/ast": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", + "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", + "dev": true, + "requires": { + "@webassemblyjs/helper-numbers": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0" + } + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", + "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", + "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==", + "dev": true + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", + "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", + "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", + "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", + "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", + "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", + "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/helper-wasm-section": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/wasm-opt": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0", + "@webassemblyjs/wast-printer": "1.11.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", + "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/utf8": "1.11.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", + "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", + "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-api-error": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/utf8": "1.11.0" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", + "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@xtuc/long": "4.2.2" + } + }, + "acorn": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.0.tgz", + "integrity": "sha512-ULr0LDaEqQrMFGyQ3bhJkLsbtrQ8QibAseGZeaSUiT/6zb9IvIkomWHJIvgvwad+hinRAgsI51JcWk2yvwyL+w==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "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" + } + }, + "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 + }, + "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" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "copy-webpack-plugin": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-8.1.1.tgz", + "integrity": "sha512-rYM2uzRxrLRpcyPqGceRBDpxxUV8vcDqIKxAUKfcnFpcrPxT5+XvhTxv7XLjo5AvEJFPdAE3zCogG2JVahqgSQ==", + "dev": true, + "requires": { + "fast-glob": "^3.2.5", + "glob-parent": "^5.1.1", + "globby": "^11.0.3", + "normalize-path": "^3.0.0", + "p-limit": "^3.1.0", + "schema-utils": "^3.0.0", + "serialize-javascript": "^5.0.1" + } + }, + "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" + } + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "enhanced-resolve": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true - }, - "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } } } }, @@ -1994,193 +3643,517 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "fast-glob": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.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" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "globby": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "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-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "jest-worker": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.2.tgz", + "integrity": "sha512-EoBdilOTTyOgmHXtw/cPc+ZrCA0KJMrkXzkrPGNwLmnvvlN1nj7MPrxpT7m+otSv2e1TLaVffzDnE/LB14zJMg==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", + "dev": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "dependencies": { + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + } + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "dev": true + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-8.2.0.tgz", + "integrity": "sha512-O8uInONB4asyY3qUcEytpgwxQG3O0fJ/hlssoUHsBboOIRVZzT6Wq+Rwj5nffbeUhOdMjpXeISpDDzHCMRDuOQ==", + "dev": true, + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } + }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "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 + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", "dev": true, "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" + "minipass": "^3.1.1" } }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "has-flag": "^4.0.0" } }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", + "dev": true + }, + "terser": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.0.tgz", + "integrity": "sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g==", "dev": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" }, "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true } } }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "terser-webpack-plugin": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.3.tgz", + "integrity": "sha512-cxGbMqr6+A2hrIB5ehFIF+F/iST5ZOxvOmy9zih9ySbP1C2oEWQSOUS+2SNBTjzx5xLKO4xnod9eywdfq1Nb9A==", "dev": true, "requires": { - "p-locate": "^4.1.0" + "jest-worker": "^27.0.2", + "p-limit": "^3.1.0", + "schema-utils": "^3.0.0", + "serialize-javascript": "^5.0.1", + "source-map": "^0.6.1", + "terser": "^5.7.0" } }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "thread-loader": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-3.0.4.tgz", + "integrity": "sha512-ByaL2TPb+m6yArpqQUZvP+5S1mZtXsEP7nWKKlAUTm7fCml8kB5s1uI3+eHRP2bk5mVYfRSBI7FFf+tWEyLZwA==", "dev": true, "requires": { - "semver": "^6.0.0" + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.1.0", + "loader-utils": "^2.0.0", + "neo-async": "^2.6.2", + "schema-utils": "^3.0.0" } }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "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": { - "p-limit": "^2.2.0" + "is-number": "^7.0.0" } }, - "path-exists": { + "watchpack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", + "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "webpack": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.39.0.tgz", + "integrity": "sha512-25CHmuDj+oOTyteI13sUqNlCnjCnySuhiKWE/cRYPQYeoQ3ijHgyWX27CiyUKLNGq27v8S0mrksyTreT/xo7pg==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.47", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/wasm-edit": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0", + "acorn": "^8.2.1", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.0", + "es-module-lexer": "^0.4.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.0.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.1", + "watchpack": "^2.2.0", + "webpack-sources": "^2.3.0" + } + }, + "webpack-sources": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.0.tgz", + "integrity": "sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + } + }, + "yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true + } + } + }, + "@vue/cli-shared-utils": { + "version": "5.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-5.0.0-beta.2.tgz", + "integrity": "sha512-gYznhuPIsSpX6M0LE6GTOsy/V9xG0qEZoBw9bSCC5/eEg+JOwoBXqDdqOXrTPEc6oc0zjPM3lk9zlwsJQ4cUcg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "execa": "^1.0.0", + "joi": "^17.4.0", + "launch-editor": "^2.2.1", + "lru-cache": "^6.0.0", + "node-fetch": "^2.6.1", + "node-ipc": "^9.1.1", + "open": "^8.0.2", + "ora": "^5.3.0", + "read-pkg": "^5.1.1", + "semver": "^7.3.4", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "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" + } }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { - "find-up": "^4.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "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": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" + "color-name": "~1.1.4" } }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "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 }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", "dev": true }, - "ssri": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.0.tgz", - "integrity": "sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g==", + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { - "figgy-pudding": "^3.5.1", - "minipass": "^3.1.1" + "lru-cache": "^6.0.0" } }, - "terser-webpack-plugin": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.7.tgz", - "integrity": "sha512-xzYyaHUNhzgaAdBsXxk2Yvo/x1NJdslUaussK3fdpBbvttm1iIwU+c26dj9UxJcwk2c5UWt5F55MUTIA8BE7Dg==", + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "cacache": "^13.0.1", - "find-cache-dir": "^3.3.1", - "jest-worker": "^25.4.0", - "p-limit": "^2.3.0", - "schema-utils": "^2.6.6", - "serialize-javascript": "^3.1.0", - "source-map": "^0.6.1", - "terser": "^4.6.12", - "webpack-sources": "^1.4.3" + "has-flag": "^4.0.0" } } } }, - "@vue/cli-shared-utils": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-4.4.6.tgz", - "integrity": "sha512-ba+FZZCjiTSu2otnLjY4qXqASe7ZIQ/QBljk5oRPgqrR0p1NUkDPUcZhqa041aOaSW1yAfSfhOD7Q84nMnWhzQ==", - "dev": true, - "requires": { - "@hapi/joi": "^15.0.1", - "chalk": "^2.4.2", - "execa": "^1.0.0", - "launch-editor": "^2.2.1", - "lru-cache": "^5.1.1", - "node-ipc": "^9.1.1", - "open": "^6.3.0", - "ora": "^3.4.0", - "read-pkg": "^5.1.1", - "request": "^2.88.2", - "semver": "^6.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, "@vue/component-compiler-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.2.0.tgz", - "integrity": "sha512-lejBLa7xAMsfiZfNp7Kv51zOzifnb29FwdnMLa96z26kXErPFioSf9BMcePVIQ6/Gc6/mC0UrPpxAWIHyae0vw==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.2.1.tgz", + "integrity": "sha512-Mci9WJYLRjyJEBkGHMPxZ1ihJ9l6gOy2Gr6hpYZUNpQoe5+nbpeb3w00aP+PSHJygCF+fxJsqp7Af1zGDITzuw==", "dev": true, "requires": { "consolidate": "^0.15.1", "hash-sum": "^1.0.2", "lru-cache": "^4.1.2", "merge-source-map": "^1.1.0", - "postcss": "^7.0.14", "postcss-selector-parser": "^6.0.2", "prettier": "^1.18.2", "source-map": "~0.6.1", @@ -2217,190 +4190,163 @@ } } }, - "@vue/preload-webpack-plugin": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz", - "integrity": "sha512-LIZMuJk38pk9U9Ur4YzHjlIyMuxPlACdBIHH9/nGYVTsaGKOSnSuELiE8vS9wa+dJpIYspYUOqk+L1Q4pgHQHQ==", - "dev": true - }, "@vue/web-component-wrapper": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vue/web-component-wrapper/-/web-component-wrapper-1.2.0.tgz", - "integrity": "sha512-Xn/+vdm9CjuC9p3Ae+lTClNutrVhsXpzxvoTXXtoys6kVRX9FkueSUAqSWAyZntmVLlR4DosBV4pH8y5Z/HbUw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz", + "integrity": "sha512-Iu8Tbg3f+emIIMmI2ycSI8QcEuAUgPTgHwesDU1eKMLE4YC/c/sFbGc70QgMq31ijRftV0R7vCm9co6rldCeOA==", "dev": true }, "@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", + "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", "dev": true, "requires": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" + "@webassemblyjs/helper-numbers": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0" } }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", - "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", - "dev": true - }, "@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", - "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", + "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==", "dev": true }, "@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", - "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", - "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", - "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", + "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==", "dev": true }, - "@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", - "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "@webassemblyjs/helper-numbers": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", + "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.9.0" + "@webassemblyjs/floating-point-hex-parser": "1.11.0", + "@webassemblyjs/helper-api-error": "1.11.0", + "@xtuc/long": "4.2.2" + }, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", + "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", + "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==", + "dev": true + } } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", - "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", + "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==", "dev": true }, "@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", - "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", + "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0" } }, "@webassemblyjs/ieee754": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", - "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", + "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", "dev": true, "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", - "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", + "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", "dev": true, "requires": { "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", - "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", + "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==", "dev": true }, "@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", - "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", + "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/helper-wasm-section": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/wasm-opt": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0", + "@webassemblyjs/wast-printer": "1.11.0" } }, "@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", - "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", + "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/utf8": "1.11.0" } }, "@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", - "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", + "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0" } }, "@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", - "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", - "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", + "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-api-error": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/utf8": "1.11.0" } }, "@webassemblyjs/wast-printer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", - "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", + "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", + "@webassemblyjs/ast": "1.11.0", "@xtuc/long": "4.2.2" } }, @@ -2439,9 +4385,9 @@ "dev": true }, "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.0.tgz", + "integrity": "sha512-mjmzmv12YIG/G8JQdQuz2MUDShEJ6teYpT5bmWA4q7iwoGen8xtt3twF3OvzIUl+Q06aWIjvnwQUKvQ6TtMRjg==", "dev": true }, "address": { @@ -2451,9 +4397,9 @@ "dev": true }, "aggregate-error": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", - "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "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", @@ -2496,12 +4442,6 @@ "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", "dev": true }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, "ansi-html": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", @@ -2539,16 +4479,10 @@ "picomatch": "^2.0.4" } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, "arch": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.2.tgz", - "integrity": "sha512-NTBIIbAfkJeIletyABbVtdPgeKfDafR+1mZV/AyyfC1UkVkp9iUjV+wwmqtUgphHYajbI86jejBJp5e+jkGTiQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", "dev": true }, "argparse": { @@ -2578,9 +4512,9 @@ "dev": true }, "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", "dev": true }, "array-union": { @@ -2604,72 +4538,17 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true + }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -2677,9 +4556,9 @@ "dev": true }, "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "async": { @@ -2708,6 +4587,12 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", @@ -2715,40 +4600,27 @@ "dev": true }, "autolinker": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-3.14.1.tgz", - "integrity": "sha512-yvsRHIaY51EYDml6MGlbqyJGfl4n7zezGYf+R7gvM8c5LNpRGc4SISkvgAswSS8SWxk/OrGCylKV9mJyVstz7w==", + "version": "3.14.3", + "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-3.14.3.tgz", + "integrity": "sha512-t81i2bCpS+s+5FIhatoww9DmpjhbdiimuU9ATEuLxtZMQ7jLv9fyFn7SWNG8IkEfD4AmYyirL1ss9k1aqVWRvg==", "requires": { "tslib": "^1.9.3" } }, "autoprefixer": { - "version": "9.8.6", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", - "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.2.6.tgz", + "integrity": "sha512-8lChSmdU6dCNMCQopIf4Pe5kipkAGj/fvTMslCsih0uHpOrXOPUEVOmYMMqmw3cekQkSD7EhIeuYl5y0BLdKqg==", "dev": true, "requires": { - "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001109", - "colorette": "^1.2.1", + "browserslist": "^4.16.6", + "caniuse-lite": "^1.0.30001230", + "colorette": "^1.2.2", + "fraction.js": "^4.1.1", "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.32", "postcss-value-parser": "^4.1.0" } }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", - "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", - "dev": true - }, "axios": { "version": "0.21.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", @@ -2772,22 +4644,21 @@ } }, "babel-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", - "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz", + "integrity": "sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==", "dev": true, "requires": { - "find-cache-dir": "^2.1.0", + "find-cache-dir": "^3.3.1", "loader-utils": "^1.4.0", - "mkdirp": "^0.5.3", - "pify": "^4.0.1", + "make-dir": "^3.1.0", "schema-utils": "^2.6.5" }, "dependencies": { "ajv": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", - "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -2796,6 +4667,12 @@ "uri-js": "^4.2.2" } }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", @@ -2829,14 +4706,14 @@ } }, "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", "dev": true, "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" } } } @@ -2847,7 +4724,45 @@ "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", "dev": true, "requires": { - "object.assign": "^4.1.0" + "object.assign": "^4.1.0" + } + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz", + "integrity": "sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.2.2", + "semver": "^6.1.1" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.2.tgz", + "integrity": "sha512-l1Cf8PKk12eEk5QP/NQ6TH8A1pee6wWDJ96WjxrMXFLHLOBFzYM4moG80HFgduVhTqAFez4alnZKEhP/bYHg0A==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.2", + "core-js-compat": "^3.9.1" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz", + "integrity": "sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.2" } }, "babel-runtime": { @@ -2860,9 +4775,9 @@ }, "dependencies": { "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" }, "regenerator-runtime": { "version": "0.11.1", @@ -2943,37 +4858,15 @@ "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", "dev": true }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bfj": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/bfj/-/bfj-6.1.2.tgz", - "integrity": "sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "check-types": "^8.0.3", - "hoopy": "^0.1.4", - "tryer": "^1.0.1" - } - }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" }, "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "bindings": { @@ -2986,18 +4879,46 @@ "file-uri-to-path": "1.0.0" } }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, - "bn.js": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz", - "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==", - "dev": true - }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -3016,6 +4937,12 @@ "type-is": "~1.6.17" }, "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -3051,14 +4978,6 @@ "dns-txt": "^2.0.2", "multicast-dns": "^6.0.1", "multicast-dns-service-types": "^1.1.0" - }, - "dependencies": { - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - } } }, "boolbase": { @@ -3106,122 +5025,17 @@ } } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz", - "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, "browserslist": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.13.0.tgz", - "integrity": "sha512-MINatJ5ZNrLnQ6blGvePd/QOz9Xtu+Ne+x29iQSCHfkU5BugKVJwZKn/iiL8UbpIpa3JhviKjz+XxMo0m2caFQ==", + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001093", - "electron-to-chromium": "^1.3.488", - "escalade": "^3.0.1", - "node-releases": "^1.1.58" + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" } }, "btoa": { @@ -3230,14 +5044,19 @@ "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==" }, "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + }, + "dependencies": { + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + } } }, "buffer-from": { @@ -3258,45 +5077,61 @@ "integrity": "sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==", "dev": true }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", "dev": true }, "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz", + "integrity": "sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==", "dev": true, "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "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" + } + }, + "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" + } + } } }, "cache-base": { @@ -3328,123 +5163,45 @@ "mkdirp": "^0.5.1", "neo-async": "^2.6.1", "schema-utils": "^2.0.0" - }, - "dependencies": { - "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", - "dev": true - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dev": true, - "requires": { - "callsites": "^2.0.0" } }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dev": true, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "requires": { - "caller-callsite": "^2.0.0" + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" } }, - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", "dev": true }, "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", "dev": true, "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "dev": true + } } }, "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, "caniuse-api": { @@ -3460,21 +5217,15 @@ } }, "caniuse-lite": { - "version": "1.0.30001109", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001109.tgz", - "integrity": "sha512-4JIXRodHzdS3HdK8nSgIqXYLExOvG+D2/EenSvcub2Kp3QEADjo2v2oUn5g0n0D+UNwG9BtwKOyGcSq2qvQXvQ==", + "version": "1.0.30001237", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001237.tgz", + "integrity": "sha512-pDHgRndit6p1NR2GhzMbQ6CkRrp4VKuSsqbcLeOQppYPKOYkKT/6ZvZDvKJUqcmtyWIAHuZq3SVS2vc1egCZzw==", "dev": true }, "case-sensitive-paths-webpack-plugin": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz", - "integrity": "sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", "dev": true }, "chalk": { @@ -3509,28 +5260,32 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, - "check-types": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz", - "integrity": "sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==", - "dev": true - }, "chokidar": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.1.tgz", - "integrity": "sha512-TQTJyr2stihpC4Sya9hs2Xh+O2wf+igjL36Y75xx2WdHuiICcn/XJza46Jwt0eT5hVpQOzo3FpY3cj3RVYLX0g==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", "dev": true, "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", + "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.4.0" + "readdirp": "~3.6.0" }, "dependencies": { + "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" + } + }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -3567,19 +5322,16 @@ } }, "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true }, "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true }, "ci-info": { "version": "1.6.0", @@ -3587,16 +5339,6 @@ "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", "dev": true }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -3621,9 +5363,9 @@ } }, "classnames": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", - "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" }, "clean-css": { "version": "4.2.3", @@ -3645,46 +5387,36 @@ "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 - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true }, "cli-highlight": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.4.tgz", - "integrity": "sha512-s7Zofobm20qriqDoU9sXptQx0t2R9PEgac92mENNm7xaEe1hn71IIMsXMK+6encA6WRCWWxIGQbipr3q998tlQ==", + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", "dev": true, "requires": { - "chalk": "^3.0.0", - "highlight.js": "^9.6.0", + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", "mz": "^2.4.0", "parse5": "^5.1.1", - "parse5-htmlparser2-tree-adapter": "^5.1.1", - "yargs": "^15.0.0" + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" }, "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -3713,15 +5445,15 @@ "dev": true }, "highlight.js": { - "version": "9.18.5", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.5.tgz", - "integrity": "sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA==", + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -3730,21 +5462,15 @@ } }, "cli-spinners": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.4.0.tgz", - "integrity": "sha512-sJAofoarcm76ZGpuooaO0eDy8saEy+YoZBLjC4h8srt4jeBnkYeOgqxgsJQTpyt2LjI5PTfLJHSL+41Yu4fEJA==", - "dev": true - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz", + "integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==", "dev": true }, "clipboard": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", - "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz", + "integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==", "optional": true, "requires": { "good-listener": "^1.2.2", @@ -3775,14 +5501,14 @@ } }, "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "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": "^6.2.0" + "wrap-ansi": "^7.0.0" }, "dependencies": { "is-fullwidth-code-point": { @@ -3792,9 +5518,9 @@ "dev": true }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -3821,17 +5547,6 @@ "shallow-clone": "^3.0.0" } }, - "coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "dev": true, - "requires": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - } - }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -3842,16 +5557,6 @@ "object-visit": "^1.0.0" } }, - "color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", - "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", - "dev": true, - "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" - } - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -3867,21 +5572,16 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", - "dev": true, - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } + "colord": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.0.1.tgz", + "integrity": "sha512-vm5YpaWamD0Ov6TSG0GGmUIwstrWcfKQV/h2CmbR7PbNu41+qdB5PW9lpzhjedrpm08uuYvcXi0Oel1RLZIJuA==", + "dev": true }, "colorette": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", - "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", - "dev": true + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" }, "combined-stream": { "version": "1.0.8", @@ -3938,12 +5638,6 @@ "vary": "~1.1.2" }, "dependencies": { - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -3967,30 +5661,12 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "connect-history-api-fallback": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", "dev": true }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, "consolidate": { "version": "0.15.1", "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", @@ -4000,12 +5676,6 @@ "bluebird": "^3.1.1" } }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", @@ -4042,20 +5712,6 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", "dev": true }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", @@ -4071,9 +5727,9 @@ } }, "copy-webpack-plugin": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.2.0.tgz", - "integrity": "sha512-1s/VbhIX73FBFBYF4D0KdeBLkjEnAlCQn0Ufo2a/IyJ41jHpQ9ZzM4JAfbE7yTOhbmwRFkARErJ/XIiLceja6Q==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.4.1.tgz", + "integrity": "sha512-MXyPCjdPVx5iiWyl40Va3JGh27bKzOTNY3NjUTrosD2q7dR/cLD0013uqJ3BpFbUjyONINjb6qI7nDIJujrMbA==", "dev": true, "requires": { "cacache": "^15.0.5", @@ -4084,21 +5740,21 @@ "loader-utils": "^2.0.0", "normalize-path": "^3.0.0", "p-limit": "^3.0.2", - "schema-utils": "^2.7.1", + "schema-utils": "^3.0.0", "serialize-javascript": "^5.0.1", "webpack-sources": "^1.4.3" }, "dependencies": { - "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", "dev": true }, "ajv": { - "version": "6.12.5", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", - "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -4113,61 +5769,6 @@ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "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 - }, - "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" - } - }, - "cacache": { - "version": "15.0.5", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.5.tgz", - "integrity": "sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A==", - "dev": true, - "requires": { - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.0", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "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" - } - }, "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", @@ -4180,268 +5781,51 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - } - }, - "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-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "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 - }, "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "p-limit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", - "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - }, - "dependencies": { - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - } - } - }, - "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" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-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 - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "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" - } - }, - "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", "dev": true, "requires": { - "randombytes": "^2.1.0" + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" } }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { - "minipass": "^3.1.1" + "yocto-queue": "^0.1.0" } }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", "dev": true, "requires": { - "is-number": "^7.0.0" + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true } } }, "core-js": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", - "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==" + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.14.0.tgz", + "integrity": "sha512-3s+ed8er9ahK+zJpp9ZtuVcDoFzHNiZsPbNAAE4KXgrRHbjSqqNN6xGSXq6bq7TZIbKj4NLrLb6bJ5i+vSVjHA==" }, "core-js-compat": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", - "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.14.0.tgz", + "integrity": "sha512-R4NS2eupxtiJU+VwgkF9WTpnSfZW4pogwKHd8bclWU2sp93Pr5S1uYJI84cMOubJRou7bcfL0vmwtLslWN5p3A==", "dev": true, "requires": { - "browserslist": "^4.8.5", + "browserslist": "^4.16.6", "semver": "7.0.0" }, "dependencies": { @@ -4454,9 +5838,9 @@ } }, "core-js-pure": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", - "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==" + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.14.0.tgz", + "integrity": "sha512-YVh+LN2FgNU0odThzm61BsdkwrbrchumFq3oztnE9vTKC4KS2fvnPmcx8t6jnqAyOTCTF4ZSiuK8Qhh7SNcL4g==" }, "core-util-is": { "version": "1.0.2", @@ -4465,74 +5849,26 @@ "dev": true }, "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", "dev": true, "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" }, "dependencies": { - "parse-json": { + "path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - } - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true } } }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, "create-react-class": { "version": "15.7.0", "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.7.0.tgz", @@ -4543,9 +5879,9 @@ } }, "cross-fetch": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.6.tgz", - "integrity": "sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", + "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", "requires": { "node-fetch": "2.6.1" }, @@ -4570,66 +5906,49 @@ "which": "^1.2.9" } }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, "css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-1.0.1.tgz", + "integrity": "sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA==", "dev": true }, "css-declaration-sorter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", - "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.0.3.tgz", + "integrity": "sha512-52P95mvW1SMzuRZegvpluT6yEv0FqQusydKQPZsNN5Q7hh8EwQvN8E2nwuJ16BBvNN6LcoIZXu/Bk58DAhrrxw==", "dev": true, "requires": { - "postcss": "^7.0.1", "timsort": "^0.3.0" } }, "css-loader": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", - "integrity": "sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==", + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.6.tgz", + "integrity": "sha512-0wyN5vXMQZu6BvjbrPdUJvkCzGEO24HC7IS7nW4llc6BBFC+zwR9CKtYGv63Puzsg10L/o12inMY5/2ByzfD6w==", "dev": true, "requires": { - "camelcase": "^5.3.1", - "cssesc": "^3.0.0", - "icss-utils": "^4.1.1", - "loader-utils": "^1.2.3", - "normalize-path": "^3.0.0", - "postcss": "^7.0.32", - "postcss-modules-extract-imports": "^2.0.0", - "postcss-modules-local-by-default": "^3.0.2", - "postcss-modules-scope": "^2.2.0", - "postcss-modules-values": "^3.0.0", + "icss-utils": "^5.1.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.15", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.1.0", - "schema-utils": "^2.7.0", - "semver": "^6.3.0" + "schema-utils": "^3.0.0", + "semver": "^7.3.5" }, "dependencies": { + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, "ajv": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", - "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -4638,56 +5957,193 @@ "uri-js": "^4.2.2" } }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "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" + } + }, + "postcss": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.4.tgz", + "integrity": "sha512-/tZY0PXExXXnNhKv3TOvZAOUYRyuqcCbBm2c17YMDK0PlVII3K7/LKdt3ScHL+hhouddjUWi+1sKDf9xXW+8YA==", + "dev": true, + "requires": { + "colorette": "^1.2.2", + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" + } + }, "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", "dev": true, "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "css-minimizer-webpack-plugin": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-2.0.0.tgz", + "integrity": "sha512-cG/uc94727tx5pBNtb1Sd7gvUPzwmcQi1lkpfqTpdkuNq75hJCw7bIVsCNijLm4dhDcr1atvuysl2rZqOG8Txw==", + "dev": true, + "requires": { + "cssnano": "^5.0.0", + "jest-worker": "^26.3.0", + "p-limit": "^3.0.2", + "postcss": "^8.2.9", + "schema-utils": "^3.0.0", + "serialize-javascript": "^5.0.1", + "source-map": "^0.6.1" + }, + "dependencies": { + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, "css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-3.1.2.tgz", + "integrity": "sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==", "dev": true, "requires": { "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" + "css-what": "^4.0.0", + "domhandler": "^4.0.0", + "domutils": "^2.4.3", + "nth-check": "^2.0.0" + }, + "dependencies": { + "css-what": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-4.0.0.tgz", + "integrity": "sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==", + "dev": true + } } }, - "css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", - "dev": true - }, "css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", "dev": true, "requires": { - "mdn-data": "2.0.4", + "mdn-data": "2.0.14", "source-map": "^0.6.1" }, "dependencies": { @@ -4700,10 +6156,9 @@ } }, "css-what": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz", - "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==", - "dev": true + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz", + "integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==" }, "css.escape": { "version": "1.5.1", @@ -4717,127 +6172,68 @@ "dev": true }, "cssnano": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", - "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.6.tgz", + "integrity": "sha512-NiaLH/7yqGksFGsFNvSRe2IV/qmEBAeDE64dYeD8OBrgp6lE8YoMeQJMtsv5ijo6MPyhuoOvFhI94reahBRDkw==", "dev": true, "requires": { - "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.7", - "is-resolvable": "^1.0.0", - "postcss": "^7.0.0" + "cosmiconfig": "^7.0.0", + "cssnano-preset-default": "^5.1.3", + "is-resolvable": "^1.1.0" } }, "cssnano-preset-default": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", - "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", - "dev": true, - "requires": { - "css-declaration-sorter": "^4.0.1", - "cssnano-util-raw-cache": "^4.0.1", - "postcss": "^7.0.0", - "postcss-calc": "^7.0.1", - "postcss-colormin": "^4.0.3", - "postcss-convert-values": "^4.0.1", - "postcss-discard-comments": "^4.0.2", - "postcss-discard-duplicates": "^4.0.2", - "postcss-discard-empty": "^4.0.1", - "postcss-discard-overridden": "^4.0.1", - "postcss-merge-longhand": "^4.0.11", - "postcss-merge-rules": "^4.0.3", - "postcss-minify-font-values": "^4.0.2", - "postcss-minify-gradients": "^4.0.2", - "postcss-minify-params": "^4.0.2", - "postcss-minify-selectors": "^4.0.2", - "postcss-normalize-charset": "^4.0.1", - "postcss-normalize-display-values": "^4.0.2", - "postcss-normalize-positions": "^4.0.2", - "postcss-normalize-repeat-style": "^4.0.2", - "postcss-normalize-string": "^4.0.2", - "postcss-normalize-timing-functions": "^4.0.2", - "postcss-normalize-unicode": "^4.0.1", - "postcss-normalize-url": "^4.0.1", - "postcss-normalize-whitespace": "^4.0.2", - "postcss-ordered-values": "^4.1.2", - "postcss-reduce-initial": "^4.0.3", - "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.2", - "postcss-unique-selectors": "^4.0.1" - } - }, - "cssnano-util-get-arguments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", - "dev": true - }, - "cssnano-util-get-match": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", - "dev": true - }, - "cssnano-util-raw-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", - "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "cssnano-util-same-parent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", - "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.3.tgz", + "integrity": "sha512-qo9tX+t4yAAZ/yagVV3b+QBKeLklQbmgR3wI7mccrDcR+bEk9iHgZN1E7doX68y9ThznLya3RDmR+nc7l6/2WQ==", + "dev": true, + "requires": { + "css-declaration-sorter": "^6.0.3", + "cssnano-utils": "^2.0.1", + "postcss-calc": "^8.0.0", + "postcss-colormin": "^5.2.0", + "postcss-convert-values": "^5.0.1", + "postcss-discard-comments": "^5.0.1", + "postcss-discard-duplicates": "^5.0.1", + "postcss-discard-empty": "^5.0.1", + "postcss-discard-overridden": "^5.0.1", + "postcss-merge-longhand": "^5.0.2", + "postcss-merge-rules": "^5.0.2", + "postcss-minify-font-values": "^5.0.1", + "postcss-minify-gradients": "^5.0.1", + "postcss-minify-params": "^5.0.1", + "postcss-minify-selectors": "^5.1.0", + "postcss-normalize-charset": "^5.0.1", + "postcss-normalize-display-values": "^5.0.1", + "postcss-normalize-positions": "^5.0.1", + "postcss-normalize-repeat-style": "^5.0.1", + "postcss-normalize-string": "^5.0.1", + "postcss-normalize-timing-functions": "^5.0.1", + "postcss-normalize-unicode": "^5.0.1", + "postcss-normalize-url": "^5.0.2", + "postcss-normalize-whitespace": "^5.0.1", + "postcss-ordered-values": "^5.0.2", + "postcss-reduce-initial": "^5.0.1", + "postcss-reduce-transforms": "^5.0.1", + "postcss-svgo": "^5.0.2", + "postcss-unique-selectors": "^5.0.1" + } + }, + "cssnano-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-2.0.1.tgz", + "integrity": "sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ==", "dev": true }, "csso": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", - "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", "dev": true, "requires": { - "css-tree": "1.0.0-alpha.39" - }, - "dependencies": { - "css-tree": { - "version": "1.0.0-alpha.39", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", - "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", - "dev": true, - "requires": { - "mdn-data": "2.0.6", - "source-map": "^0.6.1" - } - }, - "mdn-data": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", - "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "css-tree": "^1.1.2" } }, - "csstype": { - "version": "2.6.13", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.13.tgz", - "integrity": "sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A==", - "optional": true - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, "d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", @@ -4847,15 +6243,6 @@ "type": "^1.0.1" } }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "de-indent": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", @@ -4871,6 +6258,15 @@ "ms": "^2.1.1" } }, + "decache": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/decache/-/decache-4.6.0.tgz", + "integrity": "sha512-PppOuLiz+DFeaUvFXEYZjLxAkKiMYH/do/b/MxpDe/8AgKBi5GhZxridoVIbBq72GDbL36e4p0Ce2jTGUwwU+w==", + "dev": true, + "requires": { + "callsite": "^1.0.0" + } + }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -4915,12 +6311,12 @@ "dev": true }, "default-gateway": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-5.0.5.tgz", - "integrity": "sha512-z2RnruVmj8hVMmAnEJMTIJNijhKCDiGjbLP+BHJFOT7ld3Bo5qcIBpVYDniqhbMIIf+jZDlkP2MkPXiQy/DBLA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", "dev": true, "requires": { - "execa": "^3.3.0" + "execa": "^5.0.0" }, "dependencies": { "cross-spawn": { @@ -4935,32 +6331,28 @@ } }, "execa": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", - "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "p-finally": "^2.0.0", - "signal-exit": "^3.0.2", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -4983,20 +6375,14 @@ } }, "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { "mimic-fn": "^2.1.0" } }, - "p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", - "dev": true - }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -5018,6 +6404,12 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5038,6 +6430,12 @@ "clone": "^1.0.2" } }, + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -5123,12 +6521,6 @@ "dev": true } } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true } } }, @@ -5149,16 +6541,6 @@ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", "dev": true }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, "destroy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", @@ -5166,37 +6548,18 @@ "dev": true }, "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, "dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "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": "^3.0.0" + "path-type": "^4.0.0" } }, "dns-equal": { @@ -5243,72 +6606,69 @@ } }, "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", "dev": true, "requires": { "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", - "dev": true - } } }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", "dev": true }, "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", + "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", "dev": true, "requires": { - "domelementtype": "1" + "domelementtype": "^2.2.0" } }, "dompurify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.1.1.tgz", - "integrity": "sha512-NijiNVkS/OL8mdQL1hUbCD6uty/cgFpmNiuFxrmJ5YPH2cXrPKIewoixoji56rbZ6XBPmtM8GA8/sf9unlSuwg==" + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.2.9.tgz", + "integrity": "sha512-+9MqacuigMIZ+1+EwoEltogyWGFTJZWU3258Rupxs+2CGs4H914G9er6pZbsme/bvb5L67o2rade9n21e4RW/w==" }, "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.7.0.tgz", + "integrity": "sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg==", "dev": true, "requires": { - "dom-serializer": "0", - "domelementtype": "1" + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" } }, - "dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "dev": true, "requires": { - "is-obj": "^2.0.0" + "no-case": "^3.0.4", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "dev": true + } } }, "dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", "dev": true }, "dotenv-expand": { @@ -5318,80 +6678,29 @@ "dev": true }, "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, "easy-stack": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.0.tgz", - "integrity": "sha1-EskbMIWjfwuqM26UhurEv5Tj54g=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.1.tgz", + "integrity": "sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==", "dev": true }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, - "ejs": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", - "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", - "dev": true - }, "electron-to-chromium": { - "version": "1.3.515", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.515.tgz", - "integrity": "sha512-C9h2yLQwNSK/GTtWQsA9O6mLKv0ubmiAQgmz1HvHnAIH8g5Sje1shWxcooumbGiwgqvZ9yrTYULe4seMTgMYqQ==", + "version": "1.3.752", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz", + "integrity": "sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A==", "dev": true }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, "emitter-component": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.1.tgz", @@ -5424,9 +6733,9 @@ }, "dependencies": { "iconv-lite": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", - "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "requires": { "safer-buffer": ">= 2.1.2 < 3.0.0" } @@ -5443,38 +6752,42 @@ } }, "enhanced-resolve": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", - "integrity": "sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" }, "dependencies": { - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true } } }, "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "dev": true }, "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", "dev": true, "requires": { "prr": "~1.0.1" @@ -5498,35 +6811,11 @@ "stackframe": "^1.1.1" } }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "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" - } + "es-module-lexer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", + "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==", + "dev": true }, "es5-ext": { "version": "0.10.53", @@ -5576,9 +6865,9 @@ } }, "escalade": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.2.tgz", - "integrity": "sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, "escape-html": { @@ -5594,95 +6883,277 @@ "dev": true }, "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz", + "integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "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" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + } + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "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" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "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 + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "shebang-regex": "^3.0.0" } }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "isexe": "^2.0.0" } } } }, - "eslint-loader": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-2.2.1.tgz", - "integrity": "sha512-RLgV9hoCVsMLvOxCuNjdqOrUqIj9oJg8hF44vzJaYqsAHuY9G2YAeN3joQ9nxP0p5Th9iFSIpKo+SD8KISxXRg==", - "dev": true, - "requires": { - "loader-fs-cache": "^1.0.0", - "loader-utils": "^1.0.2", - "object-assign": "^4.0.1", - "object-hash": "^1.1.4", - "rimraf": "^2.6.1" - } - }, "eslint-plugin-vue": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-5.2.3.tgz", @@ -5703,9 +7174,9 @@ } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" @@ -5717,15 +7188,140 @@ "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", "dev": true }, + "eslint-webpack-plugin": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-2.4.3.tgz", + "integrity": "sha512-+15ifHFkGn0gB7lQBe+xgyKcjelxv9xlTutGHEPYBUUj+1Rjrjq3+1REJLJpyAHgpQTatpqkRY1z8gQuyn3Aww==", + "dev": true, + "requires": { + "@types/eslint": "^7.2.4", + "arrify": "^2.0.1", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "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" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "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 + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "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" + } + } + } + }, "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, "esprima": { @@ -5785,36 +7381,26 @@ "dev": true }, "eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "dev": true }, "events": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", - "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true }, "eventsource": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", - "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz", + "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==", "dev": true, "requires": { "original": "^1.0.0" } }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, "execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", @@ -5918,6 +7504,12 @@ "vary": "~1.1.2" }, "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -5950,18 +7542,12 @@ }, "dependencies": { "type": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", - "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", + "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==" } } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", @@ -6059,67 +7645,88 @@ } } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true }, "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", "dev": true, "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" }, "dependencies": { - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "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": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "fill-range": "^7.0.1" + } + }, + "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" + } + }, + "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 + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" }, "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "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" + } } } }, "fast-json-patch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-2.2.1.tgz", - "integrity": "sha512-4j5uBaTnsYAV5ebkidvxiLUYOwjQ+JSFljeqfTxCrH9bDmlCQaOJFS84oDJ2rAXZq2yskmk3ORfoP9DCwqFNig==", - "requires": { - "fast-deep-equal": "^2.0.1" - } + "version": "3.0.0-1", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.0.0-1.tgz", + "integrity": "sha512-6pdFb07cknxvPzCeLsFHStEy+MysPJPgZQ9LbQ/2O67unQF93SNqfdSqnPPl71YMHX+AD8gbl7iuoGFzHEdDuw==" }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "fast-levenshtein": { "version": "2.0.6", @@ -6145,9 +7752,9 @@ } }, "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "dev": true, "requires": { "websocket-driver": ">=0.5.1" @@ -6174,38 +7781,83 @@ } } }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "file-loader": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.3.0.tgz", - "integrity": "sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", "dev": true, "requires": { - "loader-utils": "^1.2.3", - "schema-utils": "^2.5.0" + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } } }, "file-uri-to-path": { @@ -6215,12 +7867,6 @@ "dev": true, "optional": true }, - "filesize": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", - "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", - "dev": true - }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -6277,40 +7923,40 @@ } }, "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", "dev": true, "requires": { "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" } }, "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "locate-path": "^3.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "dependencies": { "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "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" @@ -6319,21 +7965,11 @@ } }, "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, "follow-redirects": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz", @@ -6345,16 +7981,10 @@ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -6367,9 +7997,15 @@ "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=" }, "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true + }, + "fraction.js": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.1.tgz", + "integrity": "sha512-MHOhvvxHTfRFpF1geTK9czMIZ6xclsEor2wkIGYYq+PxcQqT7vStJqjhe6S1TenZrMZzo+wlqOufBDVepUEgPg==", "dev": true }, "fragment-cache": { @@ -6387,25 +8023,16 @@ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "dev": true }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" } }, "fs-minipass": { @@ -6417,18 +8044,6 @@ "minipass": "^3.0.0" } }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -6436,17 +8051,16 @@ "dev": true }, "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "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 + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -6455,9 +8069,9 @@ "dev": true }, "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true }, "get-caller-file": { @@ -6466,6 +8080,16 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -6481,15 +8105,6 @@ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -6505,18 +8120,17 @@ } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "requires": { "is-glob": "^4.0.1" } }, "glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, "globals": { @@ -6526,19 +8140,31 @@ "dev": true }, "globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", "dev": true, "requires": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "dependencies": { + "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 + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + } } }, "good-listener": { @@ -6551,19 +8177,18 @@ } }, "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, "gzip-size": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", - "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", "dev": true, "requires": { - "duplexer": "^0.1.1", - "pify": "^4.0.1" + "duplexer": "^0.1.2" } }, "handle-thing": { @@ -6572,68 +8197,14 @@ "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "dev": true }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", - "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "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-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } - } - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -6641,10 +8212,9 @@ "dev": true }, "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" }, "has-value": { "version": "1.0.0", @@ -6678,62 +8248,23 @@ } } }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, "hash-sum": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==", "dev": true }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, "hast-util-parse-selector": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.4.tgz", - "integrity": "sha512-gW3sxfynIvZApL4L07wryYF4+C9VvH3AUi7LAnVXV4MneGEgwOByXvFo18BgmTWnm7oHAe874jKbIB1YhHSIzA==" + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==" }, "hastscript": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-5.1.2.tgz", - "integrity": "sha512-WlztFuK+Lrvi3EggsqOkQ52rKbxkXL3RwB6t5lwoa8QLMemoWfBuL43eDrwOamJyR7uKQKdmKYaBH1NZBiIRrQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", "requires": { + "@types/hast": "^2.0.0", "comma-separated-tokens": "^1.0.0", "hast-util-parse-selector": "^2.0.0", "property-information": "^5.0.0", @@ -6753,20 +8284,9 @@ "dev": true }, "highlight.js": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.4.1.tgz", - "integrity": "sha512-yR5lWvNz7c85OhVAEAeFhVCc/GV4C30Fjzc/rCP0aCWzc1UUOPUk55dK/qdwTZHBvMZo+eZ2jpk62ndX/xMFlg==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.0.1.tgz", + "integrity": "sha512-EqYpWyTF2s8nMfttfBA2yLKPNoZCO33pLS4MnbXQ4hECf1TKujCt1Kq7QAdrio7roL4+CqsfjqwYj4tYgq0pJQ==" }, "hoist-non-react-statics": { "version": "3.3.2", @@ -6776,12 +8296,6 @@ "react-is": "^16.7.0" } }, - "hoopy": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", - "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", - "dev": true - }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -6812,129 +8326,72 @@ "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", "dev": true }, - "html-comment-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", - "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", - "dev": true - }, "html-entities": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", - "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", + "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==", "dev": true }, - "html-minifier": { - "version": "3.5.21", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", - "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", + "html-minifier-terser": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", + "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", "dev": true, "requires": { - "camel-case": "3.0.x", - "clean-css": "4.2.x", - "commander": "2.17.x", - "he": "1.2.x", - "param-case": "2.1.x", - "relateurl": "0.2.x", - "uglify-js": "3.4.x" + "camel-case": "^4.1.1", + "clean-css": "^4.2.3", + "commander": "^4.1.1", + "he": "^1.2.0", + "param-case": "^3.0.3", + "relateurl": "^0.2.7", + "terser": "^4.6.3" }, "dependencies": { "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true } } }, "html-tags": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", - "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", + "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", "dev": true }, "html-webpack-plugin": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz", - "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.3.1.tgz", + "integrity": "sha512-rZsVvPXUYFyME0cuGkyOHfx9hmkFa4pWfxY/mdY38PsBEaVNsRoA+Id+8z6DBDgyv3zaw6XQszdF8HLwfQvcdQ==", "dev": true, "requires": { - "html-minifier": "^3.2.3", - "loader-utils": "^0.2.16", - "lodash": "^4.17.3", - "pretty-error": "^2.0.2", - "tapable": "^1.0.0", - "toposort": "^1.0.0", - "util.promisify": "1.0.0" + "@types/html-minifier-terser": "^5.0.0", + "html-minifier-terser": "^5.0.1", + "lodash": "^4.17.20", + "pretty-error": "^2.1.1", + "tapable": "^2.0.0" }, "dependencies": { - "big.js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", "dev": true - }, - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - }, - "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" - } } } }, "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", "dev": true, "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" } }, "http-deceiver": { @@ -6964,6 +8421,12 @@ } } }, + "http-parser-js": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", + "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==", + "dev": true + }, "http-proxy": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", @@ -6976,38 +8439,73 @@ } }, "http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", - "dev": true, - "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz", + "integrity": "sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==", "dev": true, "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "@types/http-proxy": "^1.17.5", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "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 + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "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" + } + } } }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, "iconv-lite": { @@ -7020,23 +8518,15 @@ } }, "icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", - "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", - "dev": true, - "requires": { - "postcss": "^7.0.14" - } + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true }, "ieee754": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", "dev": true }, "ignore": { @@ -7050,32 +8540,14 @@ "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=" }, - "import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "dev": true, - "requires": { - "import-from": "^2.1.0" - } - }, "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dev": true, - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "import-from": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", - "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { - "resolve-from": "^3.0.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" } }, "import-local": { @@ -7086,6 +8558,51 @@ "requires": { "pkg-dir": "^3.0.0", "resolve-cwd": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + } } }, "imurmurhash": { @@ -7100,12 +8617,6 @@ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", - "dev": true - }, "infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", @@ -7127,38 +8638,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, "internal-ip": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", @@ -7214,9 +8693,9 @@ "dev": true }, "is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", "dev": true }, "is-accessor-descriptor": { @@ -7254,10 +8733,13 @@ } }, "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", - "dev": true + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0" + } }, "is-arrayish": { "version": "0.2.1", @@ -7280,12 +8762,6 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, "is-ci": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", @@ -7307,6 +8783,14 @@ "hsla-regex": "^1.0.0", "rgb-regex": "^1.0.1", "rgba-regex": "^1.0.0" + }, + "dependencies": { + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true + } } }, "is-data-descriptor": { @@ -7330,9 +8814,9 @@ } }, "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", "dev": true }, "is-decimal": { @@ -7359,16 +8843,10 @@ } } }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true - }, "is-docker": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", - "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true }, "is-dom": { @@ -7389,8 +8867,16 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-file-esm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-file-esm/-/is-file-esm-1.0.0.tgz", + "integrity": "sha512-rZlaNKb4Mr8WlRu2A9XdeoKgnO5aA53XdPHgCKVyCrQ/rWi89RET1+bq37Ru46obaQXeiX4vmFIm1vks41hoSA==", + "dev": true, + "requires": { + "read-pkg-up": "^7.0.1" + } }, "is-fullwidth-code-point": { "version": "2.0.0", @@ -7402,7 +8888,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -7412,6 +8897,12 @@ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -7432,16 +8923,10 @@ } } }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, "is-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==" }, "is-path-cwd": { "version": "2.2.0", @@ -7468,9 +8953,9 @@ } }, "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", "dev": true }, "is-plain-object": { @@ -7483,17 +8968,18 @@ } }, "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" }, "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", "dev": true, "requires": { - "has-symbols": "^1.0.1" + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" } }, "is-resolvable": { @@ -7507,28 +8993,10 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, - "is-svg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", - "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", - "dev": true, - "requires": { - "html-comment-regex": "^1.1.0" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, "is-window": { @@ -7583,24 +9051,19 @@ "form-data": "^2.3.2" } }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, "javascript-stringify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.1.tgz", - "integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", "dev": true }, "jest-worker": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", - "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, "requires": { + "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^7.0.0" }, @@ -7612,9 +9075,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -7622,24 +9085,54 @@ } } }, + "joi": { + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.4.0.tgz", + "integrity": "sha512-F4WiW2xaV6wc1jxete70Rw4V/VuMd6IN+a5ilZsxG4uYtUXWu2kq9W5P2dz30e7Gmw8RCbY/u/uk+dMPma9tAg==", + "dev": true, + "requires": { + "@hapi/hoek": "^9.0.0", + "@hapi/topo": "^5.0.0", + "@sideway/address": "^4.1.0", + "@sideway/formula": "^3.0.0", + "@sideway/pinpoint": "^2.0.0" + }, + "dependencies": { + "@hapi/hoek": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", + "integrity": "sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==", + "dev": true + }, + "@hapi/topo": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz", + "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==", + "dev": true, + "requires": { + "@hapi/hoek": "^9.0.0" + } + } + } + }, "js-file-download": { "version": "0.4.12", "resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz", "integrity": "sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg==" }, "js-message": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.5.tgz", - "integrity": "sha1-IwDSSxrwjondCVvBpMnJz8uJLRU=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz", + "integrity": "sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==", "dev": true }, "js-queue": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.0.tgz", - "integrity": "sha1-NiITz4YPRo8BJfxslqvBdCUx+Ug=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.2.tgz", + "integrity": "sha512-pbKLsbCfi7kriM3s1J4DDCo7jQkI58zPLHi0heXPzPlj0hjUsm+FesPUbE0DSbIVIK503A36aUBoCN7eMFedkA==", "dev": true, "requires": { - "easy-stack": "^1.0.0" + "easy-stack": "^1.0.1" } }, "js-tokens": { @@ -7656,12 +9149,6 @@ "esprima": "^4.0.0" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -7674,17 +9161,16 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -7692,12 +9178,6 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, "json3": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", @@ -7708,30 +9188,18 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", - "dev": true, "requires": { "minimist": "^1.2.5" } }, "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" } }, "killable": { @@ -7745,6 +9213,12 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" }, + "klona": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz", + "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==", + "dev": true + }, "launch-editor": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.2.1.tgz", @@ -7764,29 +9238,14 @@ "launch-editor": "^2.2.1" } }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levenary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", - "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", - "dev": true, - "requires": { - "leven": "^3.1.0" - } - }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "lines-and-columns": { @@ -7795,61 +9254,10 @@ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, - "loader-fs-cache": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz", - "integrity": "sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA==", - "dev": true, - "requires": { - "find-cache-dir": "^0.1.1", - "mkdirp": "^0.5.1" - }, - "dependencies": { - "find-cache-dir": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", - "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "mkdirp": "^0.5.1", - "pkg-dir": "^1.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", - "dev": true, - "requires": { - "find-up": "^1.0.0" - } - } - } - }, "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", "dev": true }, "loader-utils": { @@ -7875,13 +9283,12 @@ } }, "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" } }, "lodash": { @@ -7890,9 +9297,15 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash-es": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz", - "integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true }, "lodash.debounce": { "version": "4.0.8", @@ -7923,10 +9336,16 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, - "lodash.transform": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.transform/-/lodash.transform-4.6.0.tgz", - "integrity": "sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A=", + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", "dev": true }, "lodash.uniq": { @@ -7936,18 +9355,70 @@ "dev": true }, "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "requires": { - "chalk": "^2.0.1" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "dependencies": { + "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" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "loglevel": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", - "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", + "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==", "dev": true }, "loose-envify": { @@ -7959,34 +9430,45 @@ } }, "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", - "dev": true + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "dev": true + } + } }, "lowlight": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.15.0.tgz", - "integrity": "sha512-GhG/R+2zt5Wg8kCfOhapH8wDdJSHSIvdDW/DOPXCeResVqgHYLnOHBp6g9DoUIPVIyBpvQYCG4SV7XeelYFpyA==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", + "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", "requires": { "fault": "^1.0.0", - "highlight.js": "~10.2.0" + "highlight.js": "~10.7.0" }, "dependencies": { "highlight.js": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.2.1.tgz", - "integrity": "sha512-A+sckVPIb9zQTUydC9lpRX1qRFO/N0OKEh0NwIr65ckvWA/oMY8v9P3+kGRK3w2ULSh9E8v5MszXafodQ6039g==" + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" } } }, "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "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": "^3.0.2" + "yallist": "^4.0.0" } }, "lru-queue": { @@ -7998,13 +9480,20 @@ } }, "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "map-cache": { @@ -8028,21 +9517,10 @@ "integrity": "sha512-Xg6rIdGrfySTqiTZ6d+nQbcFepS6R4uKbJP0oAqyeZXJY/bX6mZDnOmmUJusqLXfhIwirs0c++a6JpqVa8RFvA==", "dev": true }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, "mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "dev": true }, "media-typer": { @@ -8052,18 +9530,18 @@ "dev": true }, "memoizee": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.14.tgz", - "integrity": "sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg==", + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", "requires": { - "d": "1", - "es5-ext": "^0.10.45", - "es6-weak-map": "^2.0.2", + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", "event-emitter": "^0.3.5", - "is-promise": "^2.1", - "lru-queue": "0.1", - "next-tick": "1", - "timers-ext": "^0.1.5" + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" } }, "memory-fs": { @@ -8138,28 +9616,10 @@ "to-regex": "^3.0.2" } }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, "mime": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", - "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", "dev": true }, "mime-db": { @@ -8175,45 +9635,65 @@ "mime-db": "1.44.0" } }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, "mini-css-extract-plugin": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz", - "integrity": "sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==", - "dev": true, + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.0.tgz", + "integrity": "sha512-nPFKI7NSy6uONUo9yn2hIfb9vyYvkFu95qki0e21DQ9uaqNKDP15DGpK0KnV6wDroWxPHtExrdEwx/yDQ8nVRw==", "requires": { - "loader-utils": "^1.1.0", - "normalize-url": "1.9.1", - "schema-utils": "^1.0.0", + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0", "webpack-sources": "^1.1.0" }, "dependencies": { - "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "dev": true, + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "requires": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" } }, "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" } } } @@ -8224,12 +9704,6 @@ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "dev": true }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -8296,32 +9770,6 @@ "requires": { "minipass": "^3.0.0", "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" } }, "mixin-deep": { @@ -8354,19 +9802,11 @@ "minimist": "^1.2.5" } }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } + "module-alias": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz", + "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==", + "dev": true }, "ms": { "version": "2.1.2", @@ -8390,12 +9830,6 @@ "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", "dev": true }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, "mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -8408,12 +9842,17 @@ } }, "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", "dev": true, "optional": true }, + "nanoid": { + "version": "3.1.23", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", + "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==" + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -8463,12 +9902,21 @@ "dev": true }, "no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "dev": true, "requires": { - "lower-case": "^1.1.1" + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "dev": true + } } }, "node-fetch": { @@ -8487,59 +9935,20 @@ "dev": true }, "node-ipc": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.1.1.tgz", - "integrity": "sha512-FAyICv0sIRJxVp3GW5fzgaf9jwwRQxAKDJlmNFUL5hOy+W4X/I5AypyHoq0DXXbo9o/gt79gj++4cMr4jVWE/w==", + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.1.4.tgz", + "integrity": "sha512-A+f0mn2KxUt1uRTSd5ktxQUsn2OEhj5evo7NUi/powBzMSZ0vocdzDjlq9QN2v3LH6CJi3e5xAenpZ1QwU5A8g==", "dev": true, "requires": { "event-pubsub": "4.3.0", - "js-message": "1.0.5", - "js-queue": "2.0.0" - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } + "js-message": "1.0.7", + "js-queue": "2.0.2" } }, "node-releases": { - "version": "1.1.60", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz", - "integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==", + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", "dev": true }, "normalize-package-data": { @@ -8567,10 +9976,9 @@ "dev": true }, "normalize-url": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", - "dev": true + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.0.1.tgz", + "integrity": "sha512-VU4pzAuh7Kip71XEmO9aNREYAdMHFGTVj/i+CaTImS8x0i1d3jUZkXhqluy/PRgjPLMgsLQulYY3PJ/aSbSjpQ==" }, "npm-run-path": { "version": "2.0.2", @@ -8582,49 +9990,84 @@ } }, "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", + "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", "dev": true, "requires": { - "boolbase": "~1.0.0" + "boolbase": "^1.0.0" } }, "null-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-3.0.0.tgz", - "integrity": "sha512-hf5sNLl8xdRho4UPBOOeoIwT3WhjYcMUQm0zj44EhD6UscMAz72o2udpoDFBgykucdEDGIcd6SXbc/G6zssbzw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-4.0.1.tgz", + "integrity": "sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==", "dev": true, "requires": { - "loader-utils": "^1.2.3", - "schema-utils": "^1.0.0" + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" }, "dependencies": { + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", "dev": true, "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" } } } }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -8661,26 +10104,19 @@ } } }, - "object-hash": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", - "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==", - "dev": true - }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==" }, "object-is": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", - "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "object-keys": { @@ -8699,25 +10135,15 @@ } }, "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" } }, "object.pick": { @@ -8729,18 +10155,6 @@ "isobject": "^3.0.1" } }, - "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, "obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", @@ -8771,28 +10185,32 @@ "wrappy": "1" } }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, "open": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", - "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-8.2.0.tgz", + "integrity": "sha512-O8uInONB4asyY3qUcEytpgwxQG3O0fJ/hlssoUHsBboOIRVZzT6Wq+Rwj5nffbeUhOdMjpXeISpDDzHCMRDuOQ==", "dev": true, "requires": { - "is-wsl": "^1.1.0" + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "dependencies": { + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + } } }, "opener": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", - "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", "dev": true }, "opn": { @@ -8805,40 +10223,117 @@ } }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, "ora": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", - "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-spinners": "^2.0.0", - "log-symbols": "^2.2.0", - "strip-ansi": "^5.2.0", - "wcwidth": "^1.0.1" - }, - "dependencies": { - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "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": { - "ansi-regex": "^4.1.0" + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" } } } @@ -8852,12 +10347,6 @@ "url-parse": "^1.4.3" } }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -8880,22 +10369,19 @@ } }, "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "p-limit": "^2.2.0" } }, "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true }, "p-retry": { "version": "3.0.1", @@ -8912,30 +10398,22 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, "param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", "dev": true, "requires": { - "no-case": "^2.2.0" + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "dev": true + } } }, "parent-module": { @@ -8955,20 +10433,6 @@ } } }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, "parse-entities": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", @@ -8983,14 +10447,14 @@ } }, "parse-json": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", - "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, @@ -9001,12 +10465,20 @@ "dev": true }, "parse5-htmlparser2-tree-adapter": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-5.1.1.tgz", - "integrity": "sha512-CF+TKjXqoqyDwHqBhFQ+3l5t83xYi6fVT1tQNg+Ye0JRLnTxWvIroCjEp1A0k4lneHNBGnICUf0cfYVYGEazqw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", "dev": true, "requires": { - "parse5": "^5.1.1" + "parse5": "^6.0.1" + }, + "dependencies": { + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + } } }, "parseurl": { @@ -9015,18 +10487,30 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "dev": true + } + } + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", @@ -9034,9 +10518,9 @@ "dev": true }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-is-absolute": { @@ -9058,9 +10542,9 @@ "dev": true }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "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-to-regexp": { @@ -9070,39 +10554,15 @@ "dev": true }, "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" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "pbkdf2": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", - "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true }, "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" }, "picomatch": { "version": "2.2.2", @@ -9132,21 +10592,12 @@ } }, "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "pnp-webpack-plugin": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz", - "integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { - "ts-pnp": "^1.1.6" + "find-up": "^4.0.0" } }, "portfinder": { @@ -9161,9 +10612,9 @@ }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { "ms": "^2.1.1" @@ -9178,580 +10629,351 @@ "dev": true }, "postcss": { - "version": "7.0.32", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", - "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", - "dev": true, + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.4.tgz", + "integrity": "sha512-/tZY0PXExXXnNhKv3TOvZAOUYRyuqcCbBm2c17YMDK0PlVII3K7/LKdt3ScHL+hhouddjUWi+1sKDf9xXW+8YA==", "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "colorette": "^1.2.2", + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" } }, "postcss-calc": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.2.tgz", - "integrity": "sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.0.0.tgz", + "integrity": "sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g==", "dev": true, "requires": { - "postcss": "^7.0.27", "postcss-selector-parser": "^6.0.2", "postcss-value-parser": "^4.0.2" } }, "postcss-colormin": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", - "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.2.0.tgz", + "integrity": "sha512-+HC6GfWU3upe5/mqmxuqYZ9B2Wl4lcoUUNkoaX59nEWV4EtADCMiBqui111Bu8R8IvaZTmqmxrqOAqjbHIwXPw==", "dev": true, "requires": { - "browserslist": "^4.0.0", - "color": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "colord": "^2.0.1", + "postcss-value-parser": "^4.1.0" } }, "postcss-convert-values": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", - "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.1.tgz", + "integrity": "sha512-C3zR1Do2BkKkCgC0g3sF8TS0koF2G+mN8xxayZx3f10cIRmTaAnpgpRQZjNekTZxM2ciSPoh2IWJm0VZx8NoQg==", "dev": true, "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "postcss-value-parser": "^4.1.0" } }, "postcss-discard-comments": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", - "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz", + "integrity": "sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg==", + "dev": true }, "postcss-discard-duplicates": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", - "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz", + "integrity": "sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA==", + "dev": true }, "postcss-discard-empty": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", - "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz", + "integrity": "sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw==", + "dev": true }, "postcss-discard-overridden": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", - "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-load-config": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", - "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", - "dev": true, - "requires": { - "cosmiconfig": "^5.0.0", - "import-cwd": "^2.0.0" - } + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz", + "integrity": "sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q==", + "dev": true }, "postcss-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", - "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-5.3.0.tgz", + "integrity": "sha512-/+Z1RAmssdiSLgIZwnJHwBMnlABPgF7giYzTN2NOfr9D21IJZ4mQC1R2miwp80zno9M4zMD/umGI8cR+2EL5zw==", "dev": true, "requires": { - "loader-utils": "^1.1.0", - "postcss": "^7.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^1.0.0" + "cosmiconfig": "^7.0.0", + "klona": "^2.0.4", + "semver": "^7.3.4" }, "dependencies": { - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "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": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, "postcss-merge-longhand": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", - "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.2.tgz", + "integrity": "sha512-BMlg9AXSI5G9TBT0Lo/H3PfUy63P84rVz3BjCFE9e9Y9RXQZD3+h3YO1kgTNsNJy7bBc1YQp8DmSnwLIW5VPcw==", "dev": true, "requires": { - "css-color-names": "0.0.4", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "stylehacks": "^4.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "css-color-names": "^1.0.1", + "postcss-value-parser": "^4.1.0", + "stylehacks": "^5.0.1" } - }, - "postcss-merge-rules": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", - "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "cssnano-util-same-parent": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0", - "vendors": "^1.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } + }, + "postcss-merge-rules": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.2.tgz", + "integrity": "sha512-5K+Md7S3GwBewfB4rjDeol6V/RZ8S+v4B66Zk2gChRqLTCC8yjnHQ601omj9TKftS19OPGqZ/XzoqpzNQQLwbg==", + "dev": true, + "requires": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^2.0.1", + "postcss-selector-parser": "^6.0.5", + "vendors": "^1.0.3" } }, "postcss-minify-font-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", - "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.1.tgz", + "integrity": "sha512-7JS4qIsnqaxk+FXY1E8dHBDmraYFWmuL6cgt0T1SWGRO5bzJf8sUoelwa4P88LEWJZweHevAiDKxHlofuvtIoA==", "dev": true, "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "postcss-value-parser": "^4.1.0" } }, "postcss-minify-gradients": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", - "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.1.tgz", + "integrity": "sha512-odOwBFAIn2wIv+XYRpoN2hUV3pPQlgbJ10XeXPq8UY2N+9ZG42xu45lTn/g9zZ+d70NKSQD6EOi6UiCMu3FN7g==", "dev": true, "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "is-color-stop": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "cssnano-utils": "^2.0.1", + "is-color-stop": "^1.1.0", + "postcss-value-parser": "^4.1.0" } }, "postcss-minify-params": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", - "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.1.tgz", + "integrity": "sha512-4RUC4k2A/Q9mGco1Z8ODc7h+A0z7L7X2ypO1B6V8057eVK6mZ6xwz6QN64nHuHLbqbclkX1wyzRnIrdZehTEHw==", "dev": true, "requires": { - "alphanum-sort": "^1.0.0", - "browserslist": "^4.0.0", - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", + "alphanum-sort": "^1.0.2", + "browserslist": "^4.16.0", + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0", "uniqs": "^2.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } } }, "postcss-minify-selectors": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", - "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.1.0.tgz", + "integrity": "sha512-NzGBXDa7aPsAcijXZeagnJBKBPMYLaJJzB8CQh6ncvyl2sIndLVWfbcDi0SBjRWk5VqEjXvf8tYwzoKf4Z07og==", "dev": true, "requires": { - "alphanum-sort": "^1.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } + "alphanum-sort": "^1.0.2", + "postcss-selector-parser": "^6.0.5" } }, "postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "dev": true, - "requires": { - "postcss": "^7.0.5" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true }, "postcss-modules-local-by-default": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", - "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", "dev": true, "requires": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.32", + "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", "postcss-value-parser": "^4.1.0" } }, "postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", "dev": true, "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" + "postcss-selector-parser": "^6.0.4" } }, "postcss-modules-values": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", - "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", "dev": true, "requires": { - "icss-utils": "^4.0.0", - "postcss": "^7.0.6" + "icss-utils": "^5.0.0" } }, "postcss-normalize-charset": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", - "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz", + "integrity": "sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg==", + "dev": true }, "postcss-normalize-display-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", - "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz", + "integrity": "sha512-uupdvWk88kLDXi5HEyI9IaAJTE3/Djbcrqq8YgjvAVuzgVuqIk3SuJWUisT2gaJbZm1H9g5k2w1xXilM3x8DjQ==", "dev": true, "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" } }, "postcss-normalize-positions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", - "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.1.tgz", + "integrity": "sha512-rvzWAJai5xej9yWqlCb1OWLd9JjW2Ex2BCPzUJrbaXmtKtgfL8dBMOOMTX6TnvQMtjk3ei1Lswcs78qKO1Skrg==", "dev": true, "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "postcss-value-parser": "^4.1.0" } }, "postcss-normalize-repeat-style": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", - "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.1.tgz", + "integrity": "sha512-syZ2itq0HTQjj4QtXZOeefomckiV5TaUO6ReIEabCh3wgDs4Mr01pkif0MeVwKyU/LHEkPJnpwFKRxqWA/7O3w==", "dev": true, "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" } }, "postcss-normalize-string": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", - "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.1.tgz", + "integrity": "sha512-Ic8GaQ3jPMVl1OEn2U//2pm93AXUcF3wz+OriskdZ1AOuYV25OdgS7w9Xu2LO5cGyhHCgn8dMXh9bO7vi3i9pA==", "dev": true, "requires": { - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "postcss-value-parser": "^4.1.0" } }, "postcss-normalize-timing-functions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", - "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.1.tgz", + "integrity": "sha512-cPcBdVN5OsWCNEo5hiXfLUnXfTGtSFiBU9SK8k7ii8UD7OLuznzgNRYkLZow11BkQiiqMcgPyh4ZqXEEUrtQ1Q==", "dev": true, "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" } }, "postcss-normalize-unicode": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", - "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.1.tgz", + "integrity": "sha512-kAtYD6V3pK0beqrU90gpCQB7g6AOfP/2KIPCVBKJM2EheVsBQmx/Iof+9zR9NFKLAx4Pr9mDhogB27pmn354nA==", "dev": true, "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "browserslist": "^4.16.0", + "postcss-value-parser": "^4.1.0" } }, "postcss-normalize-url": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", - "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.2.tgz", + "integrity": "sha512-k4jLTPUxREQ5bpajFQZpx8bCF2UrlqOTzP9kEqcEnOfwsRshWs2+oAFIHfDQB8GO2PaUaSE0NlTAYtbluZTlHQ==", "dev": true, "requires": { - "is-absolute-url": "^2.0.0", - "normalize-url": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "is-absolute-url": "^3.0.3", + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.1.0" } }, "postcss-normalize-whitespace": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", - "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.1.tgz", + "integrity": "sha512-iPklmI5SBnRvwceb/XH568yyzK0qRVuAG+a1HFUsFRf11lEJTiQQa03a4RSCQvLKdcpX7XsI1Gen9LuLoqwiqA==", "dev": true, "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "postcss-value-parser": "^4.1.0" } }, "postcss-ordered-values": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", - "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.2.tgz", + "integrity": "sha512-8AFYDSOYWebJYLyJi3fyjl6CqMEG/UVworjiyK1r573I56kb3e879sCJLGvR3merj+fAdPpVplXKQZv+ey6CgQ==", "dev": true, "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" } }, "postcss-reduce-initial": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", - "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz", + "integrity": "sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw==", "dev": true, "requires": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0" + "browserslist": "^4.16.0", + "caniuse-api": "^3.0.0" } }, "postcss-reduce-transforms": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", - "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.1.tgz", + "integrity": "sha512-a//FjoPeFkRuAguPscTVmRQUODP+f3ke2HqFNgGPwdYnpeC29RZdCBvGRGTsKpMURb/I3p6jdKoBQ2zI+9Q7kA==", "dev": true, "requires": { - "cssnano-util-get-match": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" } }, "postcss-selector-parser": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", - "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", "dev": true, "requires": { "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "util-deprecate": "^1.0.2" } }, "postcss-svgo": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", - "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.2.tgz", + "integrity": "sha512-YzQuFLZu3U3aheizD+B1joQ94vzPfE6BNUcSYuceNxlVnKKsOtdo6hL9/zyC168Q8EwfLSgaDSalsUGa9f2C0A==", "dev": true, "requires": { - "is-svg": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "svgo": "^1.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } + "postcss-value-parser": "^4.1.0", + "svgo": "^2.3.0" } }, "postcss-unique-selectors": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", - "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.1.tgz", + "integrity": "sha512-gwi1NhHV4FMmPn+qwBNuot1sG1t2OmacLQ/AX29lzyggnjd+MnVD5uqQmpXO3J17KGL2WAxQruj1qTd3H0gG/w==", "dev": true, "requires": { - "alphanum-sort": "^1.0.0", - "postcss": "^7.0.0", + "alphanum-sort": "^1.0.2", + "postcss-selector-parser": "^6.0.5", "uniqs": "^2.0.0" } }, @@ -9762,15 +10984,9 @@ "dev": true }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prettier": { @@ -9781,29 +10997,23 @@ "optional": true }, "pretty-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", - "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", + "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", "dev": true, "requires": { - "renderkid": "^2.0.1", - "utila": "~0.4" + "lodash": "^4.17.20", + "renderkid": "^2.0.4" } }, "prismjs": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.21.0.tgz", - "integrity": "sha512-uGdSIu1nk3kej2iZsLyDoJ7e9bnPzIgY0naW/HdknGj61zScaprVEVGHrPoXqI+M9sP0NDnTK2jpkvmldpuqDw==", + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz", + "integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==", "requires": { "clipboard": "^2.0.0" } }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -9841,20 +11051,20 @@ } }, "property-information": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.5.0.tgz", - "integrity": "sha512-RgEbCx2HLa1chNgvChcx+rrCWD0ctBmGSE0M7lVm1yyv4UbvbrWoXp/BkVLZefzjrRBGW8/Js6uh/BnlHXFyjA==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", "requires": { "xtend": "^4.0.0" } }, "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, "requires": { - "forwarded": "~0.1.2", + "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, @@ -9870,34 +11080,6 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -9908,55 +11090,17 @@ "once": "^1.3.1" } }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "dev": true, + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" + "side-channel": "^1.0.4" } }, "querystring": { @@ -9969,12 +11113,6 @@ "resolved": "https://registry.npmjs.org/querystring-browser/-/querystring-browser-1.0.4.tgz", "integrity": "sha1-8uNYgYQKgZvHsb9Zf68JeeZiLcY=" }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, "querystringify": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", @@ -9986,6 +11124,13 @@ "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", "requires": { "performance-now": "^2.1.0" + }, + "dependencies": { + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + } } }, "randombytes": { @@ -9996,16 +11141,6 @@ "safe-buffer": "^5.1.0" } }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -10022,6 +11157,14 @@ "http-errors": "1.7.2", "iconv-lite": "0.4.24", "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + } } }, "react": { @@ -10037,27 +11180,27 @@ } }, "react-copy-to-clipboard": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.1.tgz", - "integrity": "sha512-ELKq31/E3zjFs5rDWNCfFL4NvNFQvGRoJdAKReD/rUPA+xxiLPQmZBZBvy2vgH7V0GE9isIQpT9WXbwIVErYdA==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.3.tgz", + "integrity": "sha512-9S3j+m+UxDZOM0Qb8mhnT/rMR0NGSrj9A/073yz2DSxPMYhmYFBMYIdI2X4o8AjOjyFsSNxDRnCX6s/gRxpriw==", "requires": { "copy-to-clipboard": "^3", "prop-types": "^15.5.8" } }, "react-debounce-input": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-debounce-input/-/react-debounce-input-3.2.2.tgz", - "integrity": "sha512-RIBu68Cq/gImKz/2h1cE042REDqyqj3D+7SJ3lnnIpJX0ht9D9PfH7KAnL+SgDz6hvKa9pZS2CnAxlkrLmnQlg==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/react-debounce-input/-/react-debounce-input-3.2.3.tgz", + "integrity": "sha512-7Bfjm9sxrtgB+IsSrdXoo4CVqKg7CbWC68dNhr8q7ZmY6C0AqtR524//SenHQWT+eeSG9DmSLWNWCUFSyaaWSQ==", "requires": { "lodash.debounce": "^4", "prop-types": "^15.7.2" } }, "react-dom": { - "version": "15.6.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.6.2.tgz", - "integrity": "sha1-Qc+t9pO3V/rycIRDodH9WgK+9zA=", + "version": "15.7.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.7.0.tgz", + "integrity": "sha512-mpjXqC2t1FuYsILOLCj0kg6pbg460byZkVA/80VtDmKU/pYmoTdHOtaMcTRIDiyXLz4sIur0cQ04nOC6iGndJg==", "requires": { "fbjs": "^0.8.9", "loose-envify": "^1.1.0", @@ -10066,18 +11209,18 @@ } }, "react-immutable-proptypes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.1.0.tgz", - "integrity": "sha1-Aj1vObsVyXwHHp5g0A0TbqxfoLQ=" - }, - "react-immutable-pure-component": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/react-immutable-pure-component/-/react-immutable-pure-component-1.2.3.tgz", - "integrity": "sha512-kNy2A/fDrSuR8TKwB+4ynmItmp1vgF87tWxxfmadwDYo2J3ANipHqTjDIBvJvJ7libvuh76jIbvmK0krjtKH1g==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz", + "integrity": "sha512-Vf4gBsePlwdGvSZoLSBfd4HAP93HDauMY4fDjXhreg/vg6F3Fj/MXDNyTbltPC/xZKmZc+cjLu3598DdYK6sgQ==", "requires": { - "@types/react": "16.4.6" + "invariant": "^2.2.2" } }, + "react-immutable-pure-component": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/react-immutable-pure-component/-/react-immutable-pure-component-1.2.4.tgz", + "integrity": "sha512-zPXaFWxaF4+ztVMFNMlCFkrhjpb9MPcL3JnXUpb6wKGF1+vBoSgClFbpbOsZAji7gm+RHBE24H44Lday2xxPjw==" + }, "react-inspector": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-2.3.1.tgz", @@ -10101,13 +11244,6 @@ "performance-now": "^0.2.0", "prop-types": "^15.5.8", "raf": "^3.1.0" - }, - "dependencies": { - "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" - } } }, "react-redux": { @@ -10124,21 +11260,21 @@ } }, "react-syntax-highlighter": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-13.5.0.tgz", - "integrity": "sha512-2nKo8spFxe9shcjbdUiqxkrf/IMDqKUZLx7JVIxEJ17P+fYFGL4CRsZZC66UPeQ2o/f29eKu31CrkKGCK1RHuA==", + "version": "15.4.3", + "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.4.3.tgz", + "integrity": "sha512-TnhGgZKXr5o8a63uYdRTzeb8ijJOgRGe0qjrE0eK/gajtdyqnSO6LqB3vW16hHB0cFierYSoy/AOJw8z1Dui8g==", "requires": { "@babel/runtime": "^7.3.1", - "highlight.js": "^10.1.1", - "lowlight": "^1.14.0", - "prismjs": "^1.21.0", - "refractor": "^3.1.0" + "highlight.js": "^10.4.1", + "lowlight": "^1.17.0", + "prismjs": "^1.22.0", + "refractor": "^3.2.0" }, "dependencies": { "highlight.js": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.2.1.tgz", - "integrity": "sha512-A+sckVPIb9zQTUydC9lpRX1qRFO/N0OKEh0NwIr65ckvWA/oMY8v9P3+kGRK3w2ULSh9E8v5MszXafodQ6039g==" + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" } } }, @@ -10154,6 +11290,25 @@ "type-fest": "^0.6.0" } }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -10170,9 +11325,9 @@ } }, "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "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" @@ -10207,19 +11362,19 @@ } }, "refractor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.1.0.tgz", - "integrity": "sha512-bN8GvY6hpeXfC4SzWmYNQGLLF2ZakRDNBkgCL0vvl5hnpMrnyURk8Mv61v6pzn4/RBHzSWLp44SzMmVHqMGNww==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.3.1.tgz", + "integrity": "sha512-vaN6R56kLMuBszHSWlwTpcZ8KTMG6aUCok4GrxYDT20UIOXxOc5o6oDc8tNTzSlH3m2sI+Eu9Jo2kVdDcUTWYw==", "requires": { - "hastscript": "^5.0.0", + "hastscript": "^6.0.0", "parse-entities": "^2.0.0", - "prismjs": "~1.21.0" + "prismjs": "~1.23.0" } }, "regenerate": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", - "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", "dev": true }, "regenerate-unicode-properties": { @@ -10256,25 +11411,25 @@ } }, "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", + "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "regexpu-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", - "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", + "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", "dev": true, "requires": { "regenerate": "^1.4.0", @@ -10292,9 +11447,9 @@ "dev": true }, "regjsparser": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", - "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", + "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -10330,16 +11485,16 @@ "dev": true }, "renderkid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", - "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz", + "integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==", "dev": true, "requires": { - "css-select": "^1.1.0", - "dom-converter": "^0.2", - "htmlparser2": "^3.3.0", - "strip-ansi": "^3.0.0", - "utila": "^0.4.0" + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^3.0.1" }, "dependencies": { "ansi-regex": { @@ -10349,31 +11504,16 @@ "dev": true }, "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "dev": true, - "requires": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" - } - }, - "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", - "dev": true - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", + "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==", "dev": true, "requires": { - "dom-serializer": "0", - "domelementtype": "1" + "boolbase": "^1.0.0", + "css-what": "^5.0.0", + "domhandler": "^4.2.0", + "domutils": "^2.6.0", + "nth-check": "^2.0.0" } }, "strip-ansi": { @@ -10388,9 +11528,9 @@ } }, "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", "dev": true }, "repeat-string": { @@ -10398,40 +11538,18 @@ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -10464,12 +11582,20 @@ "dev": true, "requires": { "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } } }, "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "resolve-url": { @@ -10478,16 +11604,6 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -10527,49 +11643,12 @@ "glob": "^7.1.3" } }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, "run-parallel": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", "dev": true }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -10590,9 +11669,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sass": { - "version": "1.26.10", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.26.10.tgz", - "integrity": "sha512-bzN0uvmzfsTvjz0qwccN1sPm2HxxpNI/Xa+7PlUEMS+nQvbyuEK7Y0qFqxlPHhiNHb1Ze8WQJtU31olMObkAMw==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.0.tgz", + "integrity": "sha512-fhyqEbMIycQA4blrz/C0pYhv2o4x2y6FYYAH0CshBw3DXh5D5wyERgxw0ptdau1orc/GhNrhF7DFN2etyOCEng==", "dev": true, "requires": { "chokidar": ">=2.0.0 <4.0.0" @@ -10619,12 +11698,6 @@ } } }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, "schema-utils": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.1.tgz", @@ -10648,9 +11721,9 @@ "dev": true }, "selfsigned": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz", - "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==", + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.11.tgz", + "integrity": "sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA==", "dev": true, "requires": { "node-forge": "^0.10.0" @@ -10715,14 +11788,24 @@ } }, "serialize-error": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", - "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=" + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", + "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", + "requires": { + "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + } + } }, "serialize-javascript": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", - "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -10887,9 +11970,19 @@ } }, "shvl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shvl/-/shvl-2.0.0.tgz", - "integrity": "sha512-WbpzSvI5XgVGJ3A4ySGe8hBxj0JgJktfnoLhhJmvITDdK21WPVWwgG8GPlYEh4xqdti3Ff7PJ5G0QrRAjNS0Ig==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/shvl/-/shvl-2.0.3.tgz", + "integrity": "sha512-V7C6S9Hlol6SzOJPnQ7qzOVEWUQImt3BNmmzh40wObhla3XOYMe4gGiYzLrJd5TFa+cI2f9LKIRJTTKZSTbWgw==" + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } }, "signal-exit": { "version": "3.0.2", @@ -10897,38 +11990,64 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "sirv": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.12.tgz", + "integrity": "sha512-+jQoCxndz7L2tqQL4ZyzfDhky0W/4ZJip3XoOuxyQWnAwMxindLl3Xv1qT4x1YX/re0leShvTm8Uk0kQspGhBg==", "dev": true, "requires": { - "is-arrayish": "^0.3.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "dev": true - } + "@polka/url": "^1.0.0-next.15", + "mime": "^2.3.1", + "totalist": "^1.0.0" } }, "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "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 + } } }, "snapdragon": { @@ -11054,64 +12173,45 @@ } }, "sockjs": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", - "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz", + "integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==", "dev": true, "requires": { - "faye-websocket": "^0.10.0", + "faye-websocket": "^0.11.3", "uuid": "^3.4.0", - "websocket-driver": "0.6.5" + "websocket-driver": "^0.7.4" } }, "sockjs-client": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", - "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.1.tgz", + "integrity": "sha512-VnVAb663fosipI/m6pqRXakEOw7nvd7TUgdr3PlR/8V2I95QIdwT8L4nMxhyU8SmDBHYXU1TOElaKOmKLfYzeQ==", "dev": true, "requires": { - "debug": "^3.2.5", + "debug": "^3.2.6", "eventsource": "^1.0.7", - "faye-websocket": "~0.11.1", - "inherits": "^2.0.3", - "json3": "^3.3.2", - "url-parse": "^1.4.3" + "faye-websocket": "^0.11.3", + "inherits": "^2.0.4", + "json3": "^3.3.3", + "url-parse": "^1.5.1" }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { "ms": "^2.1.1" } - }, - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } } } }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" - } - }, "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" }, "source-map": { "version": "0.5.7", @@ -11119,6 +12219,11 @@ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, + "source-map-js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", + "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==" + }, "source-map-resolve": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", @@ -11151,9 +12256,9 @@ } }, "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", "dev": true }, "space-separated-tokens": { @@ -11188,9 +12293,9 @@ } }, "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", "dev": true }, "spdy": { @@ -11247,30 +12352,13 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, "ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", "dev": true, "requires": { - "figgy-pudding": "^3.5.1" + "minipass": "^3.1.1" } }, "stable": { @@ -11320,51 +12408,6 @@ "emitter-component": "^1.1.1" } }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true - }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -11392,26 +12435,6 @@ } } }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -11457,33 +12480,19 @@ "dev": true }, "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "stylehacks": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", - "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.1.tgz", + "integrity": "sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA==", "dev": true, "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } + "browserslist": "^4.16.0", + "postcss-selector-parser": "^6.0.4" } }, "supports-color": { @@ -11502,38 +12511,89 @@ "dev": true }, "svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.3.0.tgz", + "integrity": "sha512-fz4IKjNO6HDPgIQxu4IxwtubtbSfGEAJUq/IXyTPIkGhWck/faiiwfkvsB8LnBkKLvSoyNNIY6d13lZprJMc9Q==", "dev": true, "requires": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" + "@trysound/sax": "0.1.1", + "chalk": "^4.1.0", + "commander": "^7.1.0", + "css-select": "^3.1.2", + "css-tree": "^1.1.2", + "csso": "^4.2.0", + "stable": "^0.1.8" + }, + "dependencies": { + "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" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "swagger-client": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.11.1.tgz", - "integrity": "sha512-/D4I9lnGKaRmiNFTSY6xBBWYgPCHcDw7J9m4mcyeSOmZs7yGHVSFa7ozNyc7TAjNY0x2zQKjivGMUNkJ72W7ZQ==", + "version": "3.13.5", + "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.13.5.tgz", + "integrity": "sha512-n4+yS0+jvx7PNq95TulWhjN+v9Cz6GRkdloF3LL0JV2eQ8E8a3a+0/XEppsYGIzb7i2/h7ZMcM5hIxIr7Gr1RA==", "requires": { "@babel/runtime-corejs3": "^7.11.2", "btoa": "^1.2.1", - "buffer": "^5.6.0", + "buffer": "^6.0.3", "cookie": "~0.4.1", "cross-fetch": "^3.0.6", "deep-extend": "~0.6.0", - "fast-json-patch": "^2.2.1", + "fast-json-patch": "^3.0.0-1", "isomorphic-form-data": "~2.0.0", "js-yaml": "^3.14.0", "lodash": "^4.17.19", @@ -11543,85 +12603,75 @@ "url": "~0.11.0" }, "dependencies": { - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, "cookie": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" }, "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" } - }, - "qs": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", - "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" } } }, "swagger-ui": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/swagger-ui/-/swagger-ui-3.35.0.tgz", - "integrity": "sha512-RkIBsEjtVq8aze1Nz8bCO4UkH7SDoRqgp//sEUEKkidy0I4POJ8bZQBWzk0xdSRkMeUL3EqJETiFVrVRrV9c/g==", + "version": "3.50.0", + "resolved": "https://registry.npmjs.org/swagger-ui/-/swagger-ui-3.50.0.tgz", + "integrity": "sha512-4OOCjWKQdSH4rSA28vGIEdEp8yrhniuvJRFNBO1aLftqpeg85OKU5sOTnNh5xdFhCSJwzkWq8PTUVlcsQTM+EQ==", "requires": { - "@babel/runtime-corejs3": "^7.11.2", - "@braintree/sanitize-url": "^5.0.0", + "@babel/runtime-corejs3": "^7.14.0", + "@braintree/sanitize-url": "^5.0.1", "@kyleshockey/object-assign-deep": "^0.4.2", "@kyleshockey/xml": "^1.0.2", - "base64-js": "^1.2.0", - "classnames": "^2.2.6", - "core-js": "^2.6.11", + "base64-js": "^1.5.1", + "classnames": "^2.3.1", "css.escape": "1.5.1", "deep-extend": "0.6.0", - "dompurify": "^2.0.7", - "ieee754": "^1.1.13", + "dompurify": "^2.2.8", + "ieee754": "^1.2.1", "immutable": "^3.x.x", - "js-file-download": "^0.4.1", + "js-file-download": "^0.4.12", "js-yaml": "^3.13.1", - "lodash": "^4.17.19", - "memoizee": "^0.4.12", + "lodash": "^4.17.21", + "memoizee": "^0.4.15", "prop-types": "^15.7.2", "randombytes": "^2.1.0", - "react": "^15.6.2", - "react-copy-to-clipboard": "5.0.1", - "react-debounce-input": "^3.2.0", - "react-dom": "^15.6.2", - "react-immutable-proptypes": "2.1.0", + "react": "=15.7.0", + "react-copy-to-clipboard": "5.0.3", + "react-debounce-input": "^3.2.3", + "react-dom": "=15.7.0", + "react-immutable-proptypes": "2.2.0", "react-immutable-pure-component": "^1.1.1", "react-inspector": "^2.3.0", "react-motion": "^0.5.2", "react-redux": "=4.4.10", - "react-syntax-highlighter": "=13.5.0", + "react-syntax-highlighter": "^15.4.3", "redux": "=3.7.2", "redux-immutable": "3.1.0", "remarkable": "^2.0.1", "reselect": "^4.0.0", - "serialize-error": "^2.1.0", + "serialize-error": "^8.1.0", "sha.js": "^2.4.11", - "swagger-client": "=3.11.1", - "url-parse": "^1.4.7", + "swagger-client": "^3.13.5", + "url-parse": "^1.5.1", "xml-but-prettier": "^1.0.1", "zenscroll": "^4.0.2" }, "dependencies": { - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" } } }, @@ -11631,55 +12681,72 @@ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" }, "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "ajv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz", + "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "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 + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } } } }, "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", "dev": true }, "tar": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz", - "integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", "dev": true, "requires": { "chownr": "^2.0.0", @@ -11690,23 +12757,11 @@ "yallist": "^4.0.0" }, "dependencies": { - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "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 } } }, @@ -11730,31 +12785,84 @@ } }, "terser-webpack-plugin": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz", - "integrity": "sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.3.tgz", + "integrity": "sha512-cxGbMqr6+A2hrIB5ehFIF+F/iST5ZOxvOmy9zih9ySbP1C2oEWQSOUS+2SNBTjzx5xLKO4xnod9eywdfq1Nb9A==", "dev": true, "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^3.1.0", + "jest-worker": "^27.0.2", + "p-limit": "^3.1.0", + "schema-utils": "^3.0.0", + "serialize-javascript": "^5.0.1", "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" + "terser": "^5.7.0" }, "dependencies": { + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "jest-worker": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.2.tgz", + "integrity": "sha512-EoBdilOTTyOgmHXtw/cPc+ZrCA0KJMrkXzkrPGNwLmnvvlN1nj7MPrxpT7m+otSv2e1TLaVffzDnE/LB14zJMg==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", "dev": true, "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" } }, "source-map": { @@ -11762,6 +12870,34 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "terser": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.0.tgz", + "integrity": "sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } } } }, @@ -11790,14 +12926,82 @@ } }, "thread-loader": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-2.1.3.tgz", - "integrity": "sha512-wNrVKH2Lcf8ZrWxDF/khdlLlsTMczdcwPA9VEK4c2exlEPynYWxi9op3nPTo5lAnDIkE0rQEB3VBP+4Zncc9Hg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-3.0.4.tgz", + "integrity": "sha512-ByaL2TPb+m6yArpqQUZvP+5S1mZtXsEP7nWKKlAUTm7fCml8kB5s1uI3+eHRP2bk5mVYfRSBI7FFf+tWEyLZwA==", "dev": true, "requires": { - "loader-runner": "^2.3.1", - "loader-utils": "^1.1.0", - "neo-async": "^2.6.0" + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.1.0", + "loader-utils": "^2.0.0", + "neo-async": "^2.6.2", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } } }, "through": { @@ -11806,31 +13010,12 @@ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, "thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, "timers-ext": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", @@ -11861,12 +13046,6 @@ "os-tmpdir": "~1.0.2" } }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -11926,77 +13105,34 @@ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "dev": true }, - "toposort": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", - "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", + "totalist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", + "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", "dev": true }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, "traverse": { "version": "0.6.6", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=" }, - "tryer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", - "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", - "dev": true - }, - "ts-pnp": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", - "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==", - "dev": true - }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, "type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, "type-fest": { @@ -12015,40 +13151,10 @@ "mime-types": "~2.1.24" } }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, "ua-parser-js": { - "version": "0.7.22", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.22.tgz", - "integrity": "sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q==" - }, - "uglify-js": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", - "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", - "dev": true, - "requires": { - "commander": "~2.19.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } + "version": "0.7.28", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz", + "integrity": "sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g==" }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", @@ -12090,12 +13196,6 @@ "set-value": "^2.0.1" } }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, "uniqs": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", @@ -12121,9 +13221,9 @@ } }, "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true }, "unpipe": { @@ -12132,12 +13232,6 @@ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", "dev": true }, - "unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", - "dev": true - }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", @@ -12184,17 +13278,10 @@ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", - "dev": true - }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, "requires": { "punycode": "^2.1.0" } @@ -12221,17 +13308,77 @@ } } }, - "url-loader": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-2.3.0.tgz", - "integrity": "sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog==", - "dev": true, - "requires": { - "loader-utils": "^1.2.3", - "mime": "^2.4.4", - "schema-utils": "^2.5.0" - } - }, + "url-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, "url-parse": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", @@ -12247,41 +13394,12 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - } - }, "utila": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", @@ -12300,6 +13418,12 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, "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", @@ -12322,32 +13446,15 @@ "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", "dev": true }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, "vue": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz", - "integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==" + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz", + "integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==" }, "vue-cli-plugin-vuetify": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/vue-cli-plugin-vuetify/-/vue-cli-plugin-vuetify-2.0.7.tgz", - "integrity": "sha512-4riK5bzyvkZ4CxpQk/Vl6z8n8tmJUhuxh+k8xc/MZRdCt9RxAm3G4SxcEweroqKGXg+CRRfhqysaEQVtd4D40Q==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/vue-cli-plugin-vuetify/-/vue-cli-plugin-vuetify-2.4.1.tgz", + "integrity": "sha512-ZfhvQ13X41atsCSKdSGiHnSJlhAccv4QIFOZmd8kyq6NktpeeWlvQz/dEKBf6u1AWKmKdwiCDuxS2VNT9fxhOA==", "dev": true, "requires": { "null-loader": "^3.0.0", @@ -12355,11 +13462,35 @@ "shelljs": "^0.8.3" }, "dependencies": { + "null-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-3.0.0.tgz", + "integrity": "sha512-hf5sNLl8xdRho4UPBOOeoIwT3WhjYcMUQm0zj44EhD6UscMAz72o2udpoDFBgykucdEDGIcd6SXbc/G6zssbzw==", + "dev": true, + "requires": { + "loader-utils": "^1.2.3", + "schema-utils": "^1.0.0" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, @@ -12397,40 +13528,98 @@ "dev": true }, "vue-json-pretty": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/vue-json-pretty/-/vue-json-pretty-1.6.5.tgz", - "integrity": "sha512-6iW3Jk4/swNG+orb4VfjfekkYF+I/UXa8rGRNque9j5r2MnrbaP8+DlGVHMqrxPcsS59eMV/SpMlB2zNBzPDww==" + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/vue-json-pretty/-/vue-json-pretty-1.8.0.tgz", + "integrity": "sha512-0qyGHLBdQFIwVP04kjcEA7zmQ78w7hptjSz3zAZ/crIerLuHd/EXnBQzEJGz+eQHG7k3pJrZlEqVmhTDS70BoA==" }, "vue-loader": { - "version": "15.9.3", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.3.tgz", - "integrity": "sha512-Y67VnGGgVLH5Voostx8JBZgPQTlDQeOVBLOEsjc2cXbCYBKexSKEpOA56x0YZofoDOTszrLnIShyOX1p9uCEHA==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.2.0.tgz", + "integrity": "sha512-TitGhqSQ61RJljMmhIGvfWzJ2zk9m1Qug049Ugml6QP3t0e95o0XJjk29roNEiPKJQBEi8Ord5hFuSuELzSp8Q==", "dev": true, "requires": { - "@vue/component-compiler-utils": "^3.1.0", - "hash-sum": "^1.0.2", - "loader-utils": "^1.1.0", - "vue-hot-reload-api": "^2.3.0", - "vue-style-loader": "^4.1.0" + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "loader-utils": "^2.0.0" }, "dependencies": { - "hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", + "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" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, "vue-router": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.3.4.tgz", - "integrity": "sha512-SdKRBeoXUjaZ9R/8AyxsdTqkOfMcI5tWxPZOUX5Ie1BTL5rPSZ0O++pbiZCeYeythiZIdLEfkDiQPKIaWk5hDg==" + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.1.tgz", + "integrity": "sha512-RRQNLT8Mzr8z7eL4p7BtKvRaTSGdCbTy2+Mm5HTJvLGYSSeG9gDzNasJPP/yOYKLy+/cLG/ftrqq5fvkFwBJEw==" }, "vue-style-loader": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz", - "integrity": "sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz", + "integrity": "sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg==", "dev": true, "requires": { "hash-sum": "^1.0.2", @@ -12446,9 +13635,9 @@ } }, "vue-template-compiler": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz", - "integrity": "sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA==", + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz", + "integrity": "sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==", "dev": true, "requires": { "de-indent": "^1.0.2", @@ -12462,173 +13651,72 @@ "dev": true }, "vuetify": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-2.3.7.tgz", - "integrity": "sha512-9PNorMNNcn0okT78ZpN86qL5Zx4xu0yzcO2w1IdN3ECdbAP00rHe8CEYCThakwXGUuTZ8Iv7gAMDqH6zfxSMtA==" + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-2.5.3.tgz", + "integrity": "sha512-c0oX063PzWrIV29Mi7Pyi63OcF0FlCDJcgMvu0woTt4GL4yVmNQMh5hyKS5NEwlsS66HcjKJERMoY0JJc1bYGA==" }, "vuetify-loader": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vuetify-loader/-/vuetify-loader-1.6.0.tgz", - "integrity": "sha512-1bx3YeZ712dT1+QMX+XSFlP0O5k5O5Ui9ysBBmUZ9bWkAEHWZJQI9soI+qG5qmeFxUC0L9QYMCIKP0hOL/pf3Q==", - "dev": true, - "requires": { - "file-loader": "^4.0.0", - "loader-utils": "^1.2.0" - } - }, - "vuex": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.5.1.tgz", - "integrity": "sha512-w7oJzmHQs0FM9LXodfskhw9wgKBiaB+totOdb8sNzbTB2KDCEEwEs29NzBZFh/lmEK1t5tDmM1vtsO7ubG1DFw==", - "dev": true - }, - "vuex-persistedstate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/vuex-persistedstate/-/vuex-persistedstate-3.0.1.tgz", - "integrity": "sha512-2dH77+fIecAXO8GeJEXiYnC++gx48PFGUayB5d7rWrN3fblRCOHQoVnmu/VV9DXbHHJcJth/0W/ofl8vw12j1A==", - "requires": { - "deepmerge": "^4.2.2", - "shvl": "^2.0.0" - }, - "dependencies": { - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" - } - } - }, - "watchpack": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", - "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", - "dev": true, - "requires": { - "chokidar": "^3.4.1", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.0" - } - }, - "watchpack-chokidar2": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", - "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/vuetify-loader/-/vuetify-loader-1.7.2.tgz", + "integrity": "sha512-2GSo4KvRAOThBsj8mvtIEeIoyBAZx38GDfh8D90e/or7Hzx4813krJKvcQAllyLO/Ln0eQWrq2IuvBXnZ55cSA==", "dev": true, - "optional": true, "requires": { - "chokidar": "^2.1.8" + "decache": "^4.6.0", + "file-loader": "^6.2.0", + "loader-utils": "^2.0.0" }, "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "optional": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "optional": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true, - "optional": true - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "optional": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "optional": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "optional": true, - "requires": { - "binary-extensions": "^1.0.0" - } + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", "dev": true, - "optional": true, "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" } } } }, + "vuex": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz", + "integrity": "sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==", + "dev": true + }, + "vuex-persistedstate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vuex-persistedstate/-/vuex-persistedstate-3.2.0.tgz", + "integrity": "sha512-1Q4zV9cNaJtl59jN6rXbndemEtXKywZr0OFZnqgpYdwvdyy+64KNsEltKldQW+i03st5LuDwHsdOEevXIZUgdg==", + "requires": { + "deepmerge": "^4.2.2", + "shvl": "^2.0.2" + }, + "dependencies": { + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + } + } + }, + "watchpack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", + "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, "wbuf": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", @@ -12648,75 +13736,211 @@ } }, "webpack": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.1.tgz", - "integrity": "sha512-4UOGAohv/VGUNQJstzEywwNxqX417FnjZgZJpJQegddzPmTvph37eBIRbRTfdySXzVtJXLJfbMN3mMYhM6GdmQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.4.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.39.0.tgz", + "integrity": "sha512-25CHmuDj+oOTyteI13sUqNlCnjCnySuhiKWE/cRYPQYeoQ3ijHgyWX27CiyUKLNGq27v8S0mrksyTreT/xo7pg==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.47", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/wasm-edit": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0", + "acorn": "^8.2.1", + "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.3.0", - "eslint-scope": "^4.0.3", + "enhanced-resolve": "^5.8.0", + "es-module-lexer": "^0.4.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.3", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.7.4", - "webpack-sources": "^1.4.1" + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.0.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.1", + "watchpack": "^2.2.0", + "webpack-sources": "^2.3.0" }, "dependencies": { + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "acorn": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.0.tgz", + "integrity": "sha512-ULr0LDaEqQrMFGyQ3bhJkLsbtrQ8QibAseGZeaSUiT/6zb9IvIkomWHJIvgvwad+hinRAgsI51JcWk2yvwyL+w==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", "dev": true, "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "webpack-sources": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.0.tgz", + "integrity": "sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" } } } }, "webpack-bundle-analyzer": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.8.0.tgz", - "integrity": "sha512-PODQhAYVEourCcOuU+NiYI7WdR8QyELZGgPvB1y2tjbUpbmcQOt5Q7jEK+ttd5se0KSBKD9SXHCEozS++Wllmw==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1", - "bfj": "^6.1.1", - "chalk": "^2.4.1", - "commander": "^2.18.0", - "ejs": "^2.6.1", - "express": "^4.16.3", - "filesize": "^3.6.1", - "gzip-size": "^5.0.0", - "lodash": "^4.17.15", - "mkdirp": "^0.5.1", - "opener": "^1.5.1", - "ws": "^6.0.0" + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.4.2.tgz", + "integrity": "sha512-PIagMYhlEzFfhMYOzs5gFT55DkUdkyrJi/SxJp8EF3YMWhS+T9vvs2EoTetpk5qb6VsCq02eXTlRDOydRhDFAQ==", + "dev": true, + "requires": { + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "chalk": "^4.1.0", + "commander": "^6.2.0", + "gzip-size": "^6.0.0", + "lodash": "^4.17.20", + "opener": "^1.5.2", + "sirv": "^1.0.7", + "ws": "^7.3.1" }, "dependencies": { "acorn": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", - "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.0.tgz", + "integrity": "sha512-ULr0LDaEqQrMFGyQ3bhJkLsbtrQ8QibAseGZeaSUiT/6zb9IvIkomWHJIvgvwad+hinRAgsI51JcWk2yvwyL+w==", + "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" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, @@ -12731,9 +13955,9 @@ } }, "webpack-dev-middleware": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", - "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", + "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", "dev": true, "requires": { "memory-fs": "^0.4.1", @@ -12744,9 +13968,9 @@ } }, "webpack-dev-server": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", - "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", + "version": "3.11.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz", + "integrity": "sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -12769,11 +13993,11 @@ "p-retry": "^3.0.1", "portfinder": "^1.0.26", "schema-utils": "^1.0.0", - "selfsigned": "^1.10.7", + "selfsigned": "^1.10.8", "semver": "^6.3.0", "serve-index": "^1.9.1", - "sockjs": "0.3.20", - "sockjs-client": "1.4.0", + "sockjs": "^0.3.21", + "sockjs-client": "^1.5.0", "spdy": "^4.0.2", "strip-ansi": "^3.0.1", "supports-color": "^6.1.0", @@ -12817,6 +14041,12 @@ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, "chokidar": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", @@ -12871,6 +14101,15 @@ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, "fsevents": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", @@ -12903,11 +14142,17 @@ } } }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", - "dev": true + "http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "dev": true, + "requires": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + } }, "is-binary-path": { "version": "1.0.1", @@ -12918,6 +14163,31 @@ "binary-extensions": "^1.0.0" } }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "readdirp": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", @@ -13020,6 +14290,15 @@ } } }, + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, "yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", @@ -13061,19 +14340,19 @@ } }, "webpack-merge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", - "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", "dev": true, "requires": { - "lodash": "^4.17.15" + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" } }, "webpack-sources": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, "requires": { "source-list-map": "^2.0.0", "source-map": "~0.6.1" @@ -13082,17 +14361,24 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, + "webpack-virtual-modules": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.4.3.tgz", + "integrity": "sha512-5NUqC2JquIL2pBAAo/VfBP6KuGkHIZQXW/lNKupLPfhViwh8wNsu0BObtl09yuKZszeEUfbXz8xhrHvSG16Nqw==", + "dev": true + }, "websocket-driver": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", - "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dev": true, "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, @@ -13103,9 +14389,9 @@ "dev": true }, "whatwg-fetch": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.4.1.tgz", - "integrity": "sha512-sofZVzE1wKwO+EYPbWfiwzaKovWiZXf4coEzjGP9b2GBVgQRLQUZ2QcuPpQExGDAW5GItpEm6Tl4OU5mywnAoQ==" + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" }, "which": { "version": "1.3.1", @@ -13122,25 +14408,22 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "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", @@ -13149,12 +14432,11 @@ }, "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -13180,9 +14462,9 @@ "dev": true }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -13198,23 +14480,11 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "ws": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", - "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true }, "xml-but-prettier": { "version": "1.0.1", @@ -13230,98 +14500,74 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true }, "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, "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 }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.0" } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true } } }, "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.7", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", + "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true }, "yorkie": { "version": "2.0.0", diff --git a/ui/package.json b/ui/package.json index 25f8585a1..797c3c2f4 100644 --- a/ui/package.json +++ b/ui/package.json @@ -9,36 +9,46 @@ }, "dependencies": { "axios": "^0.21.1", - "core-js": "^3.6.5", - "highlight.js": ">=10.4.1", + "core-js": "^3.14.0", + "css-what": "5.0.1", + "glob-parent": "5.1.2", + "highlight.js": "^11.0.1", "kind-of": "^6.0.3", + "mini-css-extract-plugin": "1.6.0", "minimist": "^1.2.5", - "swagger-ui": "^3.35.0", - "vue": "^2.6.10", - "vue-json-pretty": "^1.6.5", - "vue-router": "^3.3.4", - "vuetify": "^2.3.7", - "vuex-persistedstate": "^3.0.1" + "normalize-url": "6.0.1", + "postcss": "8.3.4", + "swagger-ui": "^3.50.0", + "vue": "^2.6.14", + "vue-json-pretty": "^1.8.0", + "vue-router": "^3.5.1", + "vuetify": "^2.5.3", + "vuex-persistedstate": "^3.2.0" }, "devDependencies": { - "@fortawesome/fontawesome-free": "^5.14.0", + "@fortawesome/fontawesome-free": "^5.15.3", "@mdi/font": "^4.9.95", - "@vue/cli-plugin-babel": "^4.4.6", - "@vue/cli-plugin-eslint": "^4.4.6", - "@vue/cli-plugin-router": "^4.4.6", - "@vue/cli-service": "^4.4.6", + "@vue/cli-plugin-babel": "5.0.0-beta.2", + "@vue/cli-plugin-eslint": "5.0.0-beta.2", + "@vue/cli-plugin-router": "5.0.0-beta.2", + "@vue/cli-service": "5.0.0-beta.2", "babel-eslint": "^10.1.0", - "copy-webpack-plugin": "^6.2.0", - "eslint": "^5.16.0", + "copy-webpack-plugin": "^6.4.1", + "eslint": "7.28.0", "eslint-plugin-vue": "^5.0.0", + "glob-parent": "5.1.2", "material-design-icons-iconfont": "^5.0.1", - "sass": "^1.26.10", + "mini-css-extract-plugin": "1.6.0", + "node-forge": ">=0.10.0", + "normalize-url": "6.0.1", + "null-loader": "4.0.1", + "postcss": "8.3.4", + "sass": "^1.32.0", "sass-loader": "^8.0.0", - "vue-cli-plugin-vuetify": "^2.0.7", - "vue-template-compiler": "^2.6.10", - "vuetify-loader": "^1.6.0", - "vuex": "^3.5.1", - "node-forge": ">=0.10.0" + "vue-cli-plugin-vuetify": "^2.4.1", + "vue-template-compiler": "^2.6.14", + "vuetify-loader": "^1.7.2", + "vuex": "^3.6.2" }, "eslintConfig": { "root": true, diff --git a/version b/version index 39e898a4f..a3df0a695 100644 --- a/version +++ b/version @@ -1 +1 @@ -0.7.1 +0.8.0