diff --git a/.gitignore b/.gitignore index fa61001..f78b895 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,9 @@ *.csv *.log *__pycache__* -.vscode +.vscode/settings.json +resources/dist +resources/node_modules +resources/lib-* +resources/res/*.map +resources/types diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..fc8508c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,34 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Edge", + "request": "launch", + "type": "msedge", + "url": "http://localhost:8000/res/index.html?W20230318-080858", + "runtimeArgs": [ + "--allow-file-access-from-files", + "--disable-web-security" + ], + "webRoot": "${workspaceFolder}/resources/res" + }, + { + "name": "localhost", + "type": "ecl", + "request": "launch", + "protocol": "http", + "serverAddress": "localhost", + "port": 8010, + "path": "", + "targetCluster": "thor", + "rejectUnauthorized": true, + "resultLimit": 100, + "timeoutSecs": 60, + "user": "vscode_user", + "password": "" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..56b0552 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,17 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "serve", + "path": "resources", + "problemMatcher": [], + "label": "npm: serve - resources", + "detail": "npm run esbuild -- --watch --serve --servedir=.", + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} \ No newline at end of file diff --git a/Bundle.ecl b/Bundle.ecl index e500c8e..90c1eb3 100644 --- a/Bundle.ecl +++ b/Bundle.ecl @@ -9,6 +9,6 @@ EXPORT Bundle := MODULE(Std.BundleBase) EXPORT License := 'http://www.apache.org/licenses/LICENSE-2.0'; EXPORT Copyright := 'Copyright (C) 2022 HPCC Systems®'; EXPORT DependsOn := ['ML_Core']; - EXPORT Version := '1.0'; - EXPORT PlatformVersion := '8.4.0'; + EXPORT Version := '2.0'; + EXPORT PlatformVersion := '8.10.6'; END; diff --git a/Causality.ecl b/Causality.ecl index f0f40b3..cd1384d 100644 --- a/Causality.ecl +++ b/Causality.ecl @@ -3,13 +3,19 @@ IMPORT HPCC_Causality.Types; IMPORT ML_Core.Types AS cTypes; IMPORT HPCC_Causality.internal.cModel; +powerDefault := 1; + cModelTyp := Types.cModel; validationReport := Types.validationReport; +MetricQuery := Types.MetricQuery; cMetrics := Types.cMetrics; ProbQuery := Types.ProbQuery; Distr := Types.Distribution; -DiscoveryReport := Types.DiscoveryReport; - +ScanReport := Types.ScanReport; +DiscResult := Types.DiscoveryResult; +nlQuery := Types.nlQuery; +nlQueryRslt := Types.nlQueryRslt; +AnyField := Types.AnyField; NumericField := cTypes.NumericField; /** @@ -20,22 +26,26 @@ NumericField := cTypes.NumericField; * Methods include: * - ValidateModel -- Analyze the data against the provided causal model and * evaluate the degree of correspondence between the two. - * - Intervene -- Simulate the effect on a target variable of a causal - * intervention on one or more variable + * - Causal (or Probabilistic) Query. This is a superset of probability queries, + * adding support for causal interventions that simulate the effect on a target variable of a causal + * intervention on one or more variable. See Query for details. * - Metrics -- Evaluate various causal metrics on desgnated pairs * [source, destination] of variables. + * - DiscoverModel -- Utilize a range of causal discovery methods to discover causal relationships + * between variables. * * @param mod A causal model in DATASET(cModel) format. The dataset should * contain only a single record, defining the model. - * @param dat The data in NumericField format. The field number should - * correspond to the order of variables specified in the model. + * @param PS The id of a Probability Space or Subspace containing the + * dataset. This is obtained by .PS, or as returned from + * a probability.SubSpace() call. * * @see Types.cModel * @see ML_Core.Types.NumericField * */ -EXPORT Causality(DATASET(cModelTyp) mod, DATASET(NumericField) dat) := MODULE - SHARED CM := cModel.Init(mod, dat); +EXPORT Causality(DATASET(cModelTyp) mod, UNSIGNED PS) := MODULE + SHARED CM := cModel.Init(mod, PS); /** * Validate the causal model relative to the data. * @@ -43,15 +53,16 @@ EXPORT Causality(DATASET(cModelTyp) mod, DATASET(NumericField) dat) := MODULE * Higher values lead to exponentially increasing run times, and diminishing * evaluation accuracy. Very large datasets are required in order to evaluate * higher order evaluations (default=3, recommended). - * @param strength The thoroughness to be used in conditionalizing on variables. - * Allows a tradeoff between run-time and certainty of discrimination. Strength + * @param pwr Power. The thoroughness to be used in conditionalizing on variables. + * Allows a tradeoff between run-time and certainty of discrimination. Power * = 1 is sufficient to distinguish linear relationships, where higher numbers * are needed to distinguish subtle non-linear relationships. Range [1,100]. - * For practical purposes, strength > 5 should not be needed. Default = 1. + * For practical purposes, power > 5 should not be needed. Default = 1. + * @param sensitivity * @return A detailed validation report in Types.ValidationReport format * @see Types.ValidationReport */ - EXPORT ValidationReport ValidateModel(UNSIGNED order=3, UNSIGNED strength=1) := FUNCTION + EXPORT ValidationReport ValidateModel(UNSIGNED order=3, REAL pwr=powerDefault, REAL sensitivity=10) := FUNCTION ValidationReport rollupReport(ValidationReport l, ValidationReport r) := TRANSFORM SELF.confidence := 0.0; SELF.NumTotalTests := l.NumTotalTests + r.NumTotalTests; @@ -73,7 +84,7 @@ EXPORT Causality(DATASET(cModelTyp) mod, DATASET(NumericField) dat) := MODULE SELF.Errors := l.Errors + r.Errors; SELF.Warnings := l.Warnings + r.Warnings; END; - results0 := cModel.TestModel(order, strength, CM); + results0 := cModel.TestModel(order, pwr, sensitivity, CM); results1 := ROLLUP(results0, TRUE, rollupReport(LEFT, RIGHT)); resultsRec := results1[1]; score := cModel.ScoreModel(resultsRec.NumTestsPerType, @@ -87,7 +98,22 @@ EXPORT Causality(DATASET(cModelTyp) mod, DATASET(NumericField) dat) := MODULE END; /** - * Calculate the results of a Causal Intervention. + * Calculate the distributions resulting from a set of Causal Probability Queries. + * + * Causal Proabability queries are a superset of probability queries that may + * contain an intervention (i.e. do()) clause. + * + * If no do() clause is present, then the results will be the same as a normal + * probability query. + * + * The target portion must specify a bare (unbound) variable, as we are looking + * for a distribution as a result. + * + * Do() clauses are specified within the "given" portion of the query, and + * can only use equality designation. For example: + * 'P(A | do(B=1, C=2), D between [-1,3])' + * This is the probability distribution of A given that D is between -1 and 3, + * and that we intervened to force the value of B to 1 and the value of C to 2. * * Interventions simulate the effect of setting a variable or variables * to fixed values, while breaking the links from those variables' parents. @@ -95,23 +121,75 @@ EXPORT Causality(DATASET(cModelTyp) mod, DATASET(NumericField) dat) := MODULE * for each query. This is roughly equivalent to performing a randomized * study. * - * Interventions are of the form: - * - Distribution = (Var | List of interventions) * * @param queries A list of queries. Exactly 1 target per query must be specified, - * and the target must be unbound (i.e. with zero arguments). One or more + * and the target must be unbound (i.e. with no comparitor). One or more * interventions can be provided for each variable. Interventions must be - * of an exact value (e.g. do(var = value)). This is indicated by a single - * arg in the intervention ProbSpec. + * of an exact value (e.g. do(var = value)). * * @return A set of Types.Distr records, describing each of the queried distributions. * */ - EXPORT DATASET(Distr) Intervene(DATASET(ProbQuery) queries, UNSIGNED pwr=1) := FUNCTION - queries_D := DISTRIBUTE(queries, id); - distrs := cModel.Intervene(queries_D, pwr, CM); - distrs_S := SORT(distrs, id); - RETURN distrs_S; + EXPORT DATASET(Distr) QueryDistr(SET OF STRING queries, REAL pwr=powerDefault) := FUNCTION + dummy := DATASET([{1}], {UNSIGNED d}); + queryRecs := NORMALIZE(dummy, COUNT(queries), TRANSFORM(nlQuery, SELF.id:=COUNTER, + SELF.query:=queries[COUNTER])); + queries_D := DISTRIBUTE(queryRecs, id); + distrs := cModel.QueryDistr(queries_D, CM); + distrs_S := SORT(distrs, id); + RETURN distrs_S; + END; + + /** + * Calculate the probabilities or expectations resulting from a set of + * Causal Probability Queries. + * + * Causal Proabability queries are a superset of probability queries that may + * contain an intervention (i.e. do()) specification. + * + * If no do() clause is present, then the results will be the same as a normal + * probability query. + * + * Probabilities or expectations may be requested by the query. For example: + * 'P(A between [1,3] | B < 0)' # The probability that A is between 1 and 3 given + * # that B is less than zero. + * 'E(A | B < 0)' # The expected value of A given that B is less than + * # zero. + * + * Note that for probability queries that the target must be "bound" (i.e. includes a + * comparison), while for expectation queries, the target must be "unbound" (i.e. a bare + * variable name). + * + * For details of the query syntax, see the README file. + * + * Do() clauses are specified within the "given" portion of the query, and + * can only use equality designation. For example: + * 'E(A | do(B=1, C=2), D between [-1,3])' + * This is the expected value of A given that D is between -1 and 3, + * and that we intervened to force the value of B to 1 and the value of C to 2. + * + * Interventions simulate the effect of setting a variable or variables + * to fixed values, while breaking the links from those variables' parents. + * The distribution of a target variable given the interventions is returned + * for each query. This is roughly equivalent to performing a randomized + * study. + * + * @param queries A list of queries. One or more + * interventions can be provided for each variable. Interventions must be + * of an exact value (e.g. do(var = value)). + * + * @return A set of Types.AnyField records, containing the numeric (or textual). + * result of each query. + * + */ + EXPORT DATASET(nlQueryRslt) Query(SET OF STRING queries, REAL pwr=powerDefault) := FUNCTION + dummy := DATASET([{1}], {UNSIGNED d}); + queryRecs := NORMALIZE(dummy, COUNT(queries), TRANSFORM(nlQuery, SELF.id:=COUNTER, + SELF.query:=queries[COUNTER])); + queries_D := DISTRIBUTE(queryRecs, id); + results := cModel.Query(queries_D, CM); + results_S := SORT(results, id); + RETURN results_S; END; /** @@ -133,14 +211,40 @@ EXPORT Causality(DATASET(cModelTyp) mod, DATASET(NumericField) dat) := MODULE * id of the original query. * */ - EXPORT DATASET(cMetrics) Metrics(DATASET(ProbQuery) queries, UNSIGNED pwr=1) := FUNCTION + EXPORT DATASET(cMetrics) Metrics(DATASET(MetricQuery) queries, REAL pwr=powerDefault) := FUNCTION queries_D := DISTRIBUTE(queries, id); metrics := cModel.Metrics(queries_D, pwr, CM); metrics_S := SORT(metrics, id); RETURN metrics_S; END; + /** + * Analyze the data to estimate the causal relationships between variables. + * + * @param vars A set of variable names among which to discover relationships. If omitted, + * will use all variables in dataset. + * + * @param pwr The power to use for statisitical queries. Range [1, 100]. The higher power, + * the more accuracy, but longer runtime. Power=1 suffices for liner relationships. + * Power > 10 is not recommended due to very long runtimes. Default = 1. + * @param sensitivity The sensitivity of dependence detection to use. Range 1.0 -10.0. Default is 10 + * (Maximum Sensitivity). It can be useful to reduce sensitivity in real-world datasets, + * to restrict the number of relationships found. + * @param depth Determines how many simultaneous conditional variables will be evaluated. Default = 2. + * values above 3 may be problematic due to long run times, and possibly exceding the sensitivity + * of the instruments. + * @return A DATASET(DiscResult) with a single record representing the results + * of the discovery. + * @see Types.DiscResult + */ + EXPORT DATASET(DiscResult) DiscoverModel(SET OF STRING vars=[], REAL pwr=powerDefault, REAL sensitivity=10, UNSIGNED depth=2) := FUNCTION + result := cModel.DiscoverModel(vars, pwr, sensitivity, depth, CM); + RETURN result; + END; + + /** + * This function is Deprecated. Use DiscoverModel instead. * Analyze the data to estimate the causal relationships between variables. * * Produces information that is useful for understanding the variables' relationships, @@ -163,8 +267,9 @@ EXPORT Causality(DATASET(cModelTyp) mod, DATASET(NumericField) dat) := MODULE * * */ - EXPORT DATASET(DiscoveryReport) DiscoverModel( UNSIGNED pwr=1) := FUNCTION - discRpt := cModel.DiscoverModel(pwr, CM); - RETURN discRpt; + EXPORT DATASET(ScanReport) ScanModel( REAL pwr=powerDefault) := FUNCTION + rpt := cModel.ScanModel(pwr, CM); + RETURN rpt; END; + END; \ No newline at end of file diff --git a/Probability.ecl b/Probability.ecl index 2574a6e..9f89543 100644 --- a/Probability.ecl +++ b/Probability.ecl @@ -7,6 +7,7 @@ IMPORT HPCC_Causality.internal.ProbSpace; ProbQuery := Types.ProbQuery; ProbSpec := Types.ProbSpec; Distr := Types.Distribution; +DatasetSummary := Types.DatasetSummary; NumericField := cTypes.NumericField; AnyField := Types.AnyField; nlQuery := Types.nlQuery; @@ -21,24 +22,114 @@ nlQuery := Types.nlQuery; * the order of the variable names. * * Probability functions include: - * - P(...) -- Unconditional, Conditional and Joint Numerical Probabilities. - * - E(...) -- Unconditional and Conditional Expectations - * - Distr(...) -- Unconditional and Conditional Distributions + * - "Natural Language" probability queries. These queries are much easier to specify + * than the "structured" queries below. See README.md for query syntax. + * - Query(...) -- Queries for probabilities or expectations, returning scalar values. + * - QueryDistr(...) -- Queries returning a univariate distribution. + * - "Structured probability queries. These use nested structures to represent the + * query. They are more difficult to use, but may lend themselves to programmatically + * built queries. + * - P(...) -- Unconditional, Conditional and Joint Numerical Probabilities. + * - E(...) -- Unconditional and Conditional Expectations + * - Distr(...) -- Unconditional and Conditional Distributions * - Dependence(...) -- Test of Dependence and Conditional Dependence Between Variables * - isIndependent(...) -- Boolean Independence and Conditional Independence Test. * - Predict(...) -- Machine Learning style regression without training required. * - Classify(...) -- Machine Learning style classification without training required. * - * @param ds -- Set of multivariate observations in NumericField format. Each observation + * @param ds -- Set of multivariate observations in AnyField format. Each observation * shares an id (1 - numObservations), and field numbers correspond to the - * order of variable names in the varNames parameter. - * @param varNames -- An ordered list of variable name strings. + * order of variable names in the varNames parameter. This dataset can + * be produced from a record-oriented dataset using the ToAnyField() macro. + * See README.md for details. + * @param varNames -- An ordered list of variable name strings. This set may be extracted + * from the AnyField() macro. See README.md. */ EXPORT Probability(DATASET(AnyField) ds, SET OF STRING varNames, SET OF STRING categoricals=[]) := MODULE // This is a module-level initialized ProbSpace. Initialization happens when // The first probability function is called. At that point, the dataset // is sent to each node. EXPORT PS := ProbSpace.Init(ds, varNames, categoricals); + /** + * Summary + */ + EXPORT DatasetSummary Summary(UNSIGNED psId=PS) := FUNCTION + RETURN ProbSpace.getSummary(psId); + END; + + /** + * Produce a Subspace from the indicated probability space by applying + * a filter. The filter is specified the same as the conditional portion + * of a Natural probability query. + * The returned ProbabilitySpace Id can be used in subsequent calls to + * any of the probability functions. + * SubSpaces essentially create a multivariate conditional distribution + * of the original Probability Space, but filtering the set of records. + * This can be useful for cleaning a probability space (i.e. by eliminating + * records where certain attributes have certain values), or for generating + * a conditional space to issue multiple queries against. + * + * Example: + * // Generate a subspace of married men in very good or excellent health. + * new_psid := prob.SubSpace('gender=male, married=yes, genhealth in [4-verygood, 5-excellent]', prob.PS); + * + * @param filter A bound query condition. + * @param psid The probability space id of the space to be subspaced. + * @return A new probability space id for use in future queries. + * + */ + EXPORT UNSIGNED SubSpace(STRING filter, UNSIGNED psId=PS) := FUNCTION + filtDS := DATASET([{1, filter}], nlQuery); + filtDS_D := DISTRIBUTE(filtDS, ALL); + psidDS := ProbSpace.SubSpace(filtDS_D, psId); + newPsid := MAX(psidDS, id); + RETURN newPsid; + END; + + // Natural Language Queries + /** + * Natural Language Probability or Expectation query. + * + * @param gueries A set of "natural" mathematical query strings. See README.md + * for details on query syntax. + * @param psid An UNSIGNED identifier from the main probability space (probspace.PS) + * or a SubSpace. + * @return A list of numeric or string results in Types.AnyField format. + * + */ + EXPORT DATASET(AnyField) Query(SET OF STRING queries, UNSIGNED psid=PS) := FUNCTION + dummy := DATASET([{1}], {UNSIGNED d}); + queryRecs := NORMALIZE(dummy, COUNT(queries), TRANSFORM(nlQuery, SELF.id:=COUNTER, + SELF.query:=queries[COUNTER])); + queries_D := DISTRIBUTE(queryRecs, id); + results := ProbSpace.Query(queries_D, psid); + return SORT(results, id); + END; + + /** + * Natural Language Probability Distribution query + * + * @param gueries A set of "natural" mathematical query strings. See README.md + * for details on query syntax. + * @param psid An UNSIGNED identifier from the main probability space (probspace.PS) + * or a SubSpace. + * @return A dataset of Types.Distribution records, summarizing each requested + * distribution. + * + */ + EXPORT DATASET(Distr) QueryDistr(SET OF STRING queries, UNSIGNED psid=PS) := FUNCTION + dummy := DATASET([{1}], {UNSIGNED d}); + queryRecs := NORMALIZE(dummy, COUNT(queries), TRANSFORM(nlQuery, SELF.id:=COUNTER, + SELF.query:=queries[COUNTER])); + queries_D := DISTRIBUTE(queryRecs, id); + results := ProbSpace.QueryDistr(queries_D, psid); + return SORT(results, id); + END; + + // End Natural Language Queries + + // Structured Queries + /** * Calculate a series of numerical probabilities. * @@ -53,12 +144,13 @@ EXPORT Probability(DATASET(AnyField) ds, SET OF STRING varNames, SET OF STRING c * @return A set of NumericField records, with value being the probability * of the query as field-number 1. */ - EXPORT DATASET(NumericField) P(DATASET(ProbQuery) queries) := FUNCTION + EXPORT DATASET(NumericField) P(DATASET(ProbQuery) queries, UNSIGNED psid=PS) := FUNCTION queries_D := DISTRIBUTE(queries, id); - probs := ProbSpace.P(queries_D, PS); + probs := ProbSpace.P(queries_D, psid); probs_S := SORT(probs, id); RETURN probs_S; END; + /** * Calculate a series of numerical expected values. * @@ -71,34 +163,13 @@ EXPORT Probability(DATASET(AnyField) ds, SET OF STRING varNames, SET OF STRING c * @return A set of NumericField records, with value being the Expected Value of each * query. */ - EXPORT DATASET(NumericField) E(DATASET(ProbQuery) queries) := FUNCTION + EXPORT DATASET(NumericField) E(DATASET(ProbQuery) queries, UNSIGNED psid=PS) := FUNCTION queries_D := DISTRIBUTE(queries, id); - exps := ProbSpace.E(queries_D, PS); + exps := ProbSpace.E(queries_D, psid); exps_S := SORT(exps, id); RETURN exps_S; END; - /** - * Natural Language Probability or Expectation query - * Natural Language Probability query - * - */ - EXPORT DATASET(AnyField) Query(DATASET(nlQuery) queries) := FUNCTION - queries_D := DISTRIBUTE(queries, id); - results := ProbSpace.Query(queries_D, PS); - return SORT(results, id); - END; - - /** - * Natural Language Probability Distribution query - * - */ - EXPORT DATASET(Distr) QueryDistr(DATASET(nlQuery) queries) := FUNCTION - queries_D := DISTRIBUTE(queries, id); - results := ProbSpace.QueryDistr(queries_D, PS); - return SORT(results, id); - END; - /** * Calculate a series of Distributions. * @@ -110,12 +181,15 @@ EXPORT Probability(DATASET(AnyField) ds, SET OF STRING varNames, SET OF STRING c * * @return A set of Types.Distr records, describing each of the queried distributions. */ - EXPORT DATASET(Distr) Distr(DATASET(ProbQuery) queries) := FUNCTION + EXPORT DATASET(Distr) Distr(DATASET(ProbQuery) queries, UNSIGNED psid=PS) := FUNCTION queries_D := DISTRIBUTE(queries, id); - distrs := ProbSpace.Distr(queries_D, PS); + distrs := ProbSpace.Distr(queries_D, psid); distrs_S := SORT(distrs, id); RETURN distrs_S; END; + + // End Structured Queries + /** * Perform a series of dependency tests. * @@ -129,9 +203,9 @@ EXPORT Probability(DATASET(AnyField) ds, SET OF STRING varNames, SET OF STRING c * Values less than .5 indicate probable independence. * Values greater than .5 indicate probable dependence */ - EXPORT DATASET(NumericField) Dependence(DATASET(ProbQuery) queries) := FUNCTION + EXPORT DATASET(NumericField) Dependence(DATASET(ProbQuery) queries, UNSIGNED psid=PS) := FUNCTION queries_D := DISTRIBUTE(queries, id); - deps := ProbSpace.Dependence(queries_D, PS); + deps := ProbSpace.Dependence(queries_D, psid); deps_S := SORT(deps, id); RETURN deps_S; END; @@ -148,9 +222,9 @@ EXPORT Probability(DATASET(AnyField) ds, SET OF STRING varNames, SET OF STRING c * targets are most likely independent. 0 indicates probable dependence. * */ - EXPORT DATASET(NumericField) isIndependent(DATASET(ProbQuery) queries) := FUNCTION + EXPORT DATASET(NumericField) isIndependent(DATASET(ProbQuery) queries, UNSIGNED psid=PS) := FUNCTION queries_D := DISTRIBUTE(queries, id); - deps := ProbSpace.Dependence(queries_D, PS); + deps := ProbSpace.Dependence(queries_D, psid); deps_B := PROJECT(deps, TRANSFORM(RECORDOF(LEFT), SELF.value := IF(LEFT.value > .5, 0, 1), SELF := LEFT), LOCAL); @@ -172,10 +246,10 @@ EXPORT Probability(DATASET(AnyField) ds, SET OF STRING varNames, SET OF STRING c * @return A DATASET(NumericField) with the prediction values in field number 1. * */ - EXPORT DATASET(NumericField) Predict(STRING target, SET OF STRING varNames, DATASET(NumericField) varDat) := FUNCTION + EXPORT DATASET(NumericField) Predict(STRING target, SET OF STRING varNames, DATASET(NumericField) varDat, UNSIGNED psid=PS) := FUNCTION dat_D := DISTRIBUTE(varDat, id); dat_S := SORT(dat_D, id, number, LOCAL); - preds := ProbSpace.Predict(dat_S, varNames, target, PS); + preds := ProbSpace.Predict(dat_S, varNames, target, psid); preds_S := SORT(preds, id); RETURN preds_S; END; @@ -193,10 +267,10 @@ EXPORT Probability(DATASET(AnyField) ds, SET OF STRING varNames, SET OF STRING c * @return A DATASET(NumericField) with the prediction values in field number 1. * */ - EXPORT DATASET(NumericField) Classify(STRING target, SET OF STRING varNames, DATASET(NumericField) varDat) := FUNCTION + EXPORT DATASET(NumericField) Classify(STRING target, SET OF STRING varNames, DATASET(NumericField) varDat, UNSIGNED psid=PS) := FUNCTION dat_D := DISTRIBUTE(varDat, id); dat_S := SORT(dat_D, id, number, LOCAL); - preds := ProbSpace.Classify(dat_S, varNames, target, PS); + preds := ProbSpace.Classify(dat_S, varNames, target, psid); preds_S := SORT(preds, id); RETURN preds_S; END; diff --git a/README.md b/README.md index 74f0992..16a6bc7 100644 --- a/README.md +++ b/README.md @@ -3,15 +3,23 @@ Causality Bundle for HPCC Systems Platform This bundle supports research into Causal Analysis of data. -It provides three main modules: +It provides four main modules: - Synth -- Allows the generation of complex synthetic datasets with known causal relationships, using structural equation models. These can be used with the other layers of this toolkit or with other HPCC Machine Learning bundles. - Probability -- Provides a rich probability analysis system, supporting conditional probabilities, conditionalizing, independence testing, and predictive capabilities. - Causality -- Provides a range of Causal Analysis algorithms. This layer requires a Causal Model, which combined with a dataset, allows questions to be asked that are beyond the realm of Statistics. Specifically, this module allows: Model Hypothesis Testing, Causal Analysis, Causal Metrics, Counterfactual Analysis (future), and limited Causal Discovery. +- Visualization -- Visualize probabilistic and Causal relationships. Provides a range of Plots showing probabilities, joint probabilities, conditional probabilities, and causal relationships. The above methods are computationally intense, and are fully parallelized when running on an HPCC Systems Cluster. It is built on the underlying capabilities of the Python-based "Because" Causal Analytic Library. +## New in Version 2.0 +- Support for textual as well as numeric data fields. +- Expanded set of supported data types: Continuous, Discrete Numeric, Ordered Text, Categorical Numeric, Categorical Text. +- Natural text based queries provide a simplified interface. +- Extensive visualization library providing a wide range of plots. +- Enhanced probabiliistic and causal algorithms. + ## Installation This bundle requires python3, PIP, and "Because" on each HPCC Node @@ -20,9 +28,9 @@ This bundle requires python3, PIP, and "Because" on each HPCC Node Clone the repository https://github.com/RogerDev/Because.git -Run: sudo pip3 install +Run: sudo -H pip3 install -Example: sudo pip3 install ~/source/Because +Example: sudo -H pip3 install ~/source/Because This must be done on each HPCC Cluster node. It is important to use sudo so that the bundle is installed for all users. Since HPCC nodes run as special user hpcc, installing as the current user would not allow the module to be found by hpcc. @@ -35,3 +43,25 @@ ecl bundle install https://github.com/RogerDev/HPCC_Causality.git Each of the main modules provides documentation and examples of use. Documentation is provided within the module and examples are in the test folder. +For an in-depth tutorial, please see: https://hpccsystems.com/resources/hpcc-causality-tookit-version-2-0. + +### Probability Queries +The probability, causality, and Visualization modules share a common query format. Natural textual queries are used as they allow both simple and sophisticated queries to be composed without complex nested data structures. + +These queries are provided as close as possible to standard statistical notation, with causal extensions as used by Pearl[1]. + +For example: +- **'P(height > 65 | gender = female)'** -- The probability that height is greater than 65 (inches) given that gender is female. +- **'P(height > 65, weight between [100,150] | gender = female, age >= 20)'** -- The joint probability that height is > 65 and weight is between + 100 and 150 (pounds) given that gender is female and age is greater than or equal 20. +- **'E(income | genhealth in [good, verygood, excellent])'** -- The expectation of income given that general health is good, verygood, or excellent. +- **'E(income | age > 50, controlFor(gender, genhealth))'** -- The expectation of income given that age > 50, controlling for gender and general health. +- **'E(income | do(age=50))'** -- The expectation of income given that we perform a causal intervention, setting the age to 50, and correcting for non-causal influences. + +There are minor differences in the query semantics between the three use cases: probability, causal query, and visualizations. +- Probability supports two types of query: + - Scalar Query -- Returns a single value. For example: P(A = 5), E(A) + - Distribution Query -- Returns a 'distribution' structure. For example: P(A), P(A | B > 0). +- Causality provides a superset of probability queries, that may also contain a 'do()' clause, specifying one or more causal intervention. Causal queries require the specification of a 'causal model' in addtion to the query. + + diff --git a/Test/Causality/discoverTest.ecl b/Test/Causality/discoverTest.ecl index 305e8ce..50c7f6a 100644 --- a/Test/Causality/discoverTest.ecl +++ b/Test/Causality/discoverTest.ecl @@ -12,13 +12,14 @@ * E <- C * */ -IMPORT $.^.^ AS HPCC_Causality; -IMPORT HPCC_Causality.Types; +IMPORT $.^.^ AS HC; +IMPORT HC.Types; IMPORT ML_CORE.Types AS cTypes; +Probability := HC.Probability; +Causality := HC.Causality; -NumericField := cTypes.NumericField; SEM := Types.SEM; // Number of test records. @@ -42,7 +43,7 @@ semRow := ROW({ mySEM := DATASET([semRow], SEM); -testDat := HPCC_Causality.Synth(mySEM).Generate(nTestRecs); +testDat := HC.Synth(mySEM).Generate(nTestRecs); // Note: The order of variables in the model much match the order of varNames in the SEM. RVs := DATASET([ @@ -58,8 +59,8 @@ mod := DATASET([{'M8', RVs}], Types.cModel); OUTPUT(mySEM, NAMED('SEM')); OUTPUT(mod, NAMED('Model')); +prob := Probability(testDat, semRow.VarNames); +cm := Causality(mod, prob.PS); -cm := HPCC_Causality.Causality(mod, testDat); - -rept := cm.DiscoverModel(); -OUTPUT(rept, NAMED('DiscoveryReport')); +rept := cm.DiscoverModel([], pwr:=5, sensitivity:=10); +OUTPUT(rept, NAMED('DiscoveryResult')); diff --git a/Test/Causality/inferenceTest.ecl b/Test/Causality/inferenceTest.ecl index ed0e909..86c2cb7 100644 --- a/Test/Causality/inferenceTest.ecl +++ b/Test/Causality/inferenceTest.ecl @@ -1,8 +1,9 @@ /** - * Test Intervention Layer features: - * - Intervene - * - Average Causal Effect - * - Controlled Direct Effect + * Using a simulated "IceCream <- Temperature -> Crime model, + * test causal interventions and metrics. + * - Assess the apparent effect of ice cream on crime + * - Assess the causal effect of ice cream on crime using intervention + * - Use metrics to measure the causal effects */ IMPORT $.^.^ AS HPCC_Causality; @@ -13,72 +14,90 @@ IMPORT ML_CORE.Types AS cTypes; ProbSpec := Types.ProbSpec; ProbQuery := Types.ProbQuery; -NumericField := cTypes.NumericField; +MetricQuery := Types.MetricQuery; +//umericField := cTypes.NumericField; SEM := Types.SEM; // Number of test records. -nTestRecs := 50000; +nTestRecs := 100000; // SEM should be a dataset containing a single row. // SEM is Model M8. semRow := ROW({ [], - ['A', 'B', 'C', 'D', 'E', 'F', 'G'], // Variable names + ['Temperature', 'IceCream', 'Crime'], // Variable names // Equations - ['B = logistic(0,1)', // Can use any distribution defined in numpy.random - 'F = logistic(0,1)', - 'G = logistic(0,1)', - 'A = (B + F) / 2.0 + logistic(0,.1)', - 'D = (A + G) / 2.0 + logistic(0,.1)', - 'C = (B + A + D) / 3.0 + logistic(0,.1)', - 'E = C + logistic(0,.1)' + [ 'ce = 0.0', // The causal effect we expect to observe + 'Day = uniform(0, 364)', + 'Temperature = sin(Day / (2*pi)) * 30 + 40 + normal(0,5)', + 'IceCream = 1000 + 10 * Temperature + normal(0,300)', + 'Crime = ce * IceCream + 50 + 3 * Temperature + normal(0, 2)' ]}, SEM); mySEM := DATASET([semRow], SEM); +// Use Synth to generate a dataset from the SEM. testDat := HPCC_Causality.Synth(mySEM).Generate(nTestRecs); // Note: The order of variables in the model much match the order of varNames in the SEM. +// Create a causal model that assumes there is an effect between IceCream and Crime. RVs := DATASET([ - {'A', ['B','F']}, - {'B', []}, - {'C', ['B', 'A', 'D']}, - {'D', ['A','G']}, - {'E', ['C']}, - {'F', []}, - {'G', []} + {'Temperature', []}, + {'IceCream', ['Temperature']}, + {'Crime', ['Temperature', 'IceCream']} ], Types.RV); -mod := DATASET([{'M8', RVs}], Types.cModel); +mod := DATASET([{'Ice Cream', RVs}], Types.cModel); OUTPUT(mySEM, NAMED('SEM')); OUTPUT(mod, NAMED('Model')); - -cm := HPCC_Causality.Causality(mod, testDat); - -testsD := DATASET([{1, DATASET([{'C'}], ProbSpec), DATASET([], ProbSpec), DATASET([{'A',[1]}], ProbSpec)}, - {2, DATASET([{'C'}], ProbSpec), DATASET([], ProbSpec), DATASET([{'A',[1]},{'B',[1]}], ProbSpec)}, - {3, DATASET([{'E'}], ProbSpec), DATASET([], ProbSpec), DATASET([{'C',[.5]}], ProbSpec)} - ], ProbQuery); - - - -distrs := cm.Intervene(testsD); -OUTPUT(distrs, NAMED('Interventions')); - -// Test all combinations of variables for causal effects -numVars := COUNT(semRow.varNames); -ProbQuery makeSpec(UNSIGNED ctr) := TRANSFORM - SELF.id := ctr; - var1 := semRow.varNames[(ctr - 1) DIV numVars + 1]; - var2 := semRow.varNames[(ctr - 1) % numVars + 1]; - targDat := DATASET([{var1}, {var2}], ProbSpec); - SELF.target := targDat; -END; -// Note: we filter out any with the same variable for source and dest. -testsM := DATASET(numVars * numVars, makeSpec(COUNTER))(target[1].varName != target[2].varName); -OUTPUT(testsM, NAMED('testsM')); - -metrics := cm.Metrics(testsM); - +OUTPUT(testDat[..1000], ALL, NAMED('Data')); + +// Create a probability model using the data +prob := HPCC_Causality.Probability(testDat, semRow.varNames); +// Create a causal graph with the causal model and the probabililty model +cg := HPCC_Causality.Causality(mod, prob.PS); + +// Distribution tests. Assess the distribution of each variable +testsD := ['P(Temperature)', 'P(IceCream)', 'P(Crime)']; +distrs := cg.QueryDistr(testsD); +OUTPUT(distrs, Named('QDistResults')); + +// Look at the exppectations of: +// - Each Variable +// - The apparent effect of ice cream on crime (Using a high and low level for ice cream) +// - The causal effect of ice cream on crime using interventions. +iHigh := 1700; +iLow := 1300; +testsP := ['E(Temperature)', 'E(IceCream)', 'E(Crime)', 'E(Crime | IceCream = ' + (STRING)iHigh + ')', + 'E(Crime | IceCream = ' + (STRING)iLow + ')', 'E(Crime | do(IceCream=' + (STRING)iHigh + '))', + 'E(Crime | do(IceCream='+ (STRING)iLow+ '))']; + +// Calculate +rslts := cg.Query(testsP); +OUTPUT(rslts, NAMED('Qresults')); + +// Calcumate some metrics +h1 := rslts[4].value; +l1 := rslts[5].value; +h2 := rslts[6].value; +l2 := rslts[7].value; +// Note: apparent effect (appEff) should be non-zero, due to correlation with Temp. +// Causal Effect (causEff) should be appoximately the value of "ce" in the SEM (above), +// which we usually set to zero. +appEff := (h1 - l1) / (iHigh - iLow); +causEff := (h2 - l2) / (iHigh - iLow); +OUTPUT(appEff, NAMED('ApparentEffect')); +OUTPUT(causEff, NAMED('CausalEffect')); + +metricQueries := DATASET([ + {1, 'Temperature', 'IceCream'}, + {2, 'Temperature', 'Crime'}, + {3, 'IceCream', 'Temperature'}, + {4, 'Crime', 'Temperature'}, + {5, 'IceCream', 'Crime'}, + {6, 'Crime', 'IceCream'} +], MetricQuery); + +metrics := cg.Metrics(metricQueries); OUTPUT(metrics, NAMED('Metrics')); diff --git a/Test/Causality/queryTest.ecl b/Test/Causality/queryTest.ecl new file mode 100644 index 0000000..e69de29 diff --git a/Test/Causality/scanTest.ecl b/Test/Causality/scanTest.ecl new file mode 100644 index 0000000..305e8ce --- /dev/null +++ b/Test/Causality/scanTest.ecl @@ -0,0 +1,65 @@ +/** + * Test and example for Model Validation. + * + * Uses the Synth module to generate M8 model. + * Tests against the M8 model definition: + * B is Exogenous + * F is Exogenous + * G is Exogenous + * A <- B,F + * D <- A,G + * C <- B,A,D + * E <- C + * + */ +IMPORT $.^.^ AS HPCC_Causality; +IMPORT HPCC_Causality.Types; + +IMPORT ML_CORE.Types AS cTypes; + + +NumericField := cTypes.NumericField; +SEM := Types.SEM; + +// Number of test records. +nTestRecs := 100000; + + +// SEM should be a dataset containing a single row. +// SEM is Model M8. +semRow := ROW({ + [], + ['A', 'B', 'C', 'D', 'E', 'F', 'G'], // Variable names + // Equations + ['B = logistic(0,1)', // Can use any distribution defined in numpy.random + 'F = logistic(0,1)', + 'G = logistic(0,1)', + 'A = (B + F) / 2.0 + logistic(0,.4)', + 'D = (A + G) / 2.0 + logistic(0,.4)', + 'C = (B + A + D) / 3.0 + logistic(0,.4)', + 'E = C + logistic(0,.4)' + ]}, SEM); + +mySEM := DATASET([semRow], SEM); + +testDat := HPCC_Causality.Synth(mySEM).Generate(nTestRecs); + +// Note: The order of variables in the model much match the order of varNames in the SEM. +RVs := DATASET([ + {'A', ['B','F']}, + {'B', []}, + {'C', ['B', 'A', 'D']}, + {'D', ['A','G']}, + {'E', ['C']}, + {'F', []}, + {'G', []} + ], Types.RV); +mod := DATASET([{'M8', RVs}], Types.cModel); + +OUTPUT(mySEM, NAMED('SEM')); +OUTPUT(mod, NAMED('Model')); + +cm := HPCC_Causality.Causality(mod, testDat); + +rept := cm.DiscoverModel(); +OUTPUT(rept, NAMED('DiscoveryReport')); diff --git a/Test/Causality/validateTest.ecl b/Test/Causality/validateTest.ecl index 304d971..6362da5 100644 --- a/Test/Causality/validateTest.ecl +++ b/Test/Causality/validateTest.ecl @@ -1,8 +1,7 @@ /** * Test and example for Model Validation. * - * Uses the Synth module to generate M2 model. - * Tests against the M8 model definition: + * Uses the Synth module to generate M8 model: * B is Exogenous * F is Exogenous * G is Exogenous @@ -32,12 +31,12 @@ semRow := ROW({ ['A', 'B', 'C', 'D', 'E', 'F', 'G'], // Variable names // Equations ['B = logistic(0,1)', // Can use any distribution defined in numpy.random - 'F = logistic(0,1)', - 'G = logistic(0,1)', - 'A = (B + F) / 2.0 + logistic(0,.1)', - 'D = (A + G) / 2.0 + logistic(0,.1)', - 'C = (B + A + D) / 3.0 + logistic(0,.1)', - 'E = C + logistic(0,.1)' + 'F = logistic(-1,1)', + 'G = logistic(1,1)', + 'A = (B + F) / 2.0 + logistic(0,.5)', + 'D = (A + G) / 2.0 + logistic(0,.5)', + 'C = (B + A + D) / 3.0 + logistic(0,.5)', + 'E = C + logistic(0,.5)' ]}, SEM); mySEM := DATASET([semRow], SEM); @@ -58,8 +57,12 @@ mod := DATASET([{'M8', RVs}], Types.cModel); OUTPUT(mySEM, NAMED('SEM')); OUTPUT(mod, NAMED('Model')); +OUTPUT(testDat, NAMED('DATA')); -cm := HPCC_Causality.Causality(mod, testDat); +// Create a Probability Space (ProbSpace) given the test data. +prob := HPCC_Causality.Probability(testDat, semRow.varNames); +// Create a causal graph given the ProbSpace and the Causal Module +cg := HPCC_Causality.Causality(mod, prob.PS); -rept := cm.ValidateModel(order:=1, strength:=1); +rept := cg.ValidateModel(order:=2, pwr:=1); OUTPUT(rept, NAMED('ValidationReport')); diff --git a/Test/Probability/continuousTest.ecl b/Test/Probability/continuousTest.ecl index d491111..fcafc3a 100644 --- a/Test/Probability/continuousTest.ecl +++ b/Test/Probability/continuousTest.ecl @@ -85,7 +85,7 @@ testsD := DATASET([{1, DATASET([{'X1'}], ProbSpec), DATASET([], ProbSpec)}, // S {3, DATASET([{'Y1'}], ProbSpec), DATASET([], ProbSpec)}, {4, DATASET([{'Y1'}], ProbSpec), DATASET([{'X1', [2]}], ProbSpec)}, {5, DATASET([{'Y2'}], ProbSpec), DATASET([], ProbSpec)}, - {6, DATASET([{'Y5'}], ProbSpec), DATASET([{'X2',[-100,0]},{'X3',[1]}], ProbSpec)} + {6, DATASET([{'Y5'}], ProbSpec), DATASET([{'X2',[-100,0]},{'X3',[3]}], ProbSpec)} ], ProbQuery); resultsD := prob.Distr(testsD); @@ -135,8 +135,8 @@ targetVar := 'Y3'; //OUTPUT(indDat, NAMED('indDat')); preds := prob.Predict(targetVar, predVars, indDat); -OUTPUT(preds, ALL, NAMED('Predictions')); +//OUTPUT(preds, ALL, NAMED('Predictions')); accuracy := ML_Core.Analysis.Regression.Accuracy(preds, depDat); -OUTPUT(accuracy, NAMED('PredAccuracy')); \ No newline at end of file +//OUTPUT(accuracy, NAMED('PredAccuracy')); \ No newline at end of file diff --git a/Test/Probability/failModeTest.ecl b/Test/Probability/failModeTest.ecl new file mode 100644 index 0000000..18a4c2e --- /dev/null +++ b/Test/Probability/failModeTest.ecl @@ -0,0 +1,93 @@ +/** + * Test continuous probabilities using a samples from various distributions with + * non-linear interdependence. + * + * Uses the Synth module to generate the test data. + */ +IMPORT $.^.^ AS HPCC_Causality; +IMPORT HPCC_Causality.Types; +IMPORT ML_CORE.Types AS cTypes; +IMPORT ML_CORE; + +numRecs := 100000; +numTestRecs := TRUNCATE(numRecs * .1); + +NumericField := cTypes.NumericField; +SEM := Types.SEM; +Probability := HPCC_Causality.Probability; +ProbSpec := Types.ProbSpec; +ProbQuery := Types.ProbQuery; + +// SEM for a roll of 2 dice (ala Craps). +semRow := ROW({ + [], // Init + ['Y1', 'Y2', 'Y3', 'Y4', 'Y5', 'X1', 'X2', 'X3', 'X4', 'X5', 'IV1', 'IV2'], // Variable names + // Equations + [ + // Y1 is dependent on X1, Y2 is dependent on X1 and X2, ... + // Y5 is dependent on X1, ... ,X5 + 'X1 = normal(2.5, 1)', + 'X2 = logistic(0, 2)', + 'X3 = beta(2,5)', + 'X4 = abs(normal(0, 2))', + 'X5 = exponential() * .2', + 'Y1 = 2 * X1 + normal(0, .1)', + 'Y2 = -Y1 + tanh(X2*3) + normal(0,.1)', + 'Y3 = -2 * X1 + tanh(X2*3) + sin(X3) + normal(0,.1)', + 'Y4 = Y3 + log(X4, 2) + normal(0, .1)', + 'Y5 = Y4 + 1.1**X5 + normal(0,.1)', + // IV1 and IV2 create an inverted-v formation + // IV1 <- X1 -> IV2 so that we can test conditionalization + 'IV1 = .5 * X1 + normal(0,.1)', + 'IV2 = tanh(-.75 * X1) + normal(0,.1)' + ]}, SEM); + +mySEM := DATASET([semRow], SEM); + +// Generate the records to test with +dat := HPCC_Causality.Synth(mySEM).Generate(numRecs); + +OUTPUT(dat[..10000], ALL, NAMED('Samples')); + +prob := Probability(dat, semRow.VarNames); + +tests := DATASET([{1, DATASET([{'X2', [-100, 0]}], ProbSpec), DATASET([], ProbSpec)}, + {2, DATASET([{'X3', [.6, 6.5]}], ProbSpec), DATASET([], ProbSpec)}, + {3, DATASET([{'X3', [.65, 7.0]}], ProbSpec), DATASET([], ProbSpec)}, + {4, DATASET([{'X2', [-100, 0]},{'X3', [3, 3.5]}], ProbSpec), DATASET([], ProbSpec)} + ], ProbQuery); + +results := prob.P(tests); + +OUTPUT(results, ALL, NAMED('Probabilities')); + +// Now test some Expected Values + +testsE := DATASET([ + //{4, DATASET([{'Y1'}], ProbSpec), DATASET([{'X1', [1]}], ProbSpec)} // exp=2 + //{5, DATASET([{'ROLL'}], ProbSpec), DATASET([{'D1', [1,4]}, {'D2', [6]}], ProbSpec)} // exp=8 + {1, DATASET([{'Y5'}], ProbSpec), DATASET([{'X2',[-100,0]},{'X3',[3,3.5]}], ProbSpec)} + ], ProbQuery); + +resultsE := prob.E(testsE); + +OUTPUT(resultsE, ALL, NAMED('Expectations')); + +resultsEQ := prob.Query(['E(Y5 | X2 between [-100, 0], X3 between [3, 3.5])']); +OUTPUT(resultsEQ, NAMED('ExpectationQueries')); + +// Test Full Distributions + +testsD := DATASET([ + {1, DATASET([{'X3'}], ProbSpec), DATASET([], ProbSpec)}, + {2, DATASET([{'Y5'}], ProbSpec), DATASET([{'X2',[-100,0]},{'X3',[3,3.5]}], ProbSpec)} + ], ProbQuery); + +resultsD := prob.Distr(testsD); +OUTPUT(resultsD, ALL, NAMED('Distributions')); + +resultsDQ := prob.QueryDistr(['P(Y5 | X2 between [-100, 0], X3 between [3, 3.5])']); +OUTPUT(resultsDQ, NAMED('DistributionQueries')); + + + diff --git a/Test/Probability/queryTest.ecl b/Test/Probability/queryTest.ecl index 51bf739..0311277 100644 --- a/Test/Probability/queryTest.ecl +++ b/Test/Probability/queryTest.ecl @@ -55,31 +55,17 @@ OUTPUT(dat[..10000], ALL, NAMED('Samples')); // Treat TV as a categorical variable so that expectations come out as strings. prob := Probability(dat, semRow.VarNames, categoricals:=['TV']); -// Include various use of spacing around terms to check the parser's -// resilience to spacing variations. -tests := DATASET([{1, 'P(X1 >= 2)'}, - {2, 'P(TV = medium | X5 between [.4,.8])'}, - {3, 'E(Y4)'}, - {4, 'E(TV| X2 < -.75)'}, - {5, 'P(X2 between[-.5, .5] | TV in [medium, large])'}, - {6, 'P(TV=medium)'}, - {7, 'E(TV |X2 between[-1.1, 1.1])'} - //{8, 'P(TV)'} // Should fail - ], nlQuery); + +tests := ['P(X1 >= 2 )', 'P(TV = medium | X5 between [.4,.8])', + 'E(Y4)', 'E(TV| X2 < -.75)', + 'P(X2 between [-.5, .5] | TV in [medium, large])', + 'P(TV=medium)', 'E(TV |X2 between [-1.1, 1.1])']; results := prob.Query(tests); OUTPUT(results, ALL, NAMED('Probabilities')); -// Now do Distribution queries. -dtests := DATASET([ - {1, 'P(X1)'}, - {2, 'P(TV)'}, - {3, 'P(TV|X2 > -.5)'}, - {4, 'P(Y1 | X1=1)'}, - {5, 'P(X2)'}, - {6, 'P(X4)'} - ], nlQuery); +dtests := ['P(X1)', 'P(TV)', 'P(TV|X2 > -.5)', 'P(Y1 | X1=1)', 'P(X2)', 'P(X4)']; dresults := prob.QueryDistr(dtests); diff --git a/Test/Probability/subspaceTest.ecl b/Test/Probability/subspaceTest.ecl new file mode 100644 index 0000000..9c6dd28 --- /dev/null +++ b/Test/Probability/subspaceTest.ecl @@ -0,0 +1,86 @@ +/** + * Test the probability.SubSpace capability. Make sure + * queries deliver different results agains different subspaces. + * Uses the Synth module to generate the test data. + */ +IMPORT $.^.^ AS HPCC_Causality; +IMPORT HPCC_Causality.Types; +IMPORT ML_CORE.Types AS cTypes; +IMPORT ML_CORE; + +numRecs := 10000; +numTestRecs := TRUNCATE(numRecs * .1); + +NumericField := cTypes.NumericField; +SEM := Types.SEM; +Probability := HPCC_Causality.Probability; +nlQuery := Types.nlQuery; + +semRow := ROW({ + [], // Init + ['Y1', 'Y2', 'Y3', 'Y4', 'Y5', 'X1', 'X2', 'X3', 'X4', 'X5', 'IV1', 'IV2', 'TV'], // Variable names + // Equations + [ + // Y1 is dependent on X1, Y2 is dependent on X1 and X2, ... + // Y5 is dependent on X1, ... ,X5 + 'X1 = normal(2.5, 1)', + 'X2 = choice([logistic(-2, .5), logistic(2,.5)])', + 'X3 = beta(2,5)', + 'X4 = truncated("normal(0, 2)", .5, None)', + 'X5 = exponential() * .2', + 'Y1 = 2 * X1 + normal(0, .1)', + 'Y2 = -Y1 + tanh(X2*3) + normal(0,.1)', + 'Y3 = -2 * X1 + tanh(X2*3) + sin(X3) + normal(0,.1)', + 'Y4 = Y3 + log(X4, 2) + normal(0, .1)', + 'Y5 = Y4 + 1.1**X5 + normal(0,.1)', + // IV1 and IV2 create an inverted-v formation + // IV1 <- X1 -> IV2 so that we can test conditionalization + 'IV1 = .5 * X1 + normal(0,.1)', + 'IV2 = tanh(-.75 * X1) + normal(0,.1)', + // TV is a textual variable. + 'TV = "small" if X2 < -1 else "large" if X2 > 1 else "medium"' + ]}, SEM); + +mySEM := DATASET([semRow], SEM); + + +// First test Probabilities and Expectations. + +// Generate the records to test with +dat := HPCC_Causality.Synth(mySEM).Generate(numRecs); + +OUTPUT(dat[..10000], ALL, NAMED('Samples')); + +// Treat TV as a categorical variable so that expectations come out as strings. +prob := Probability(dat, semRow.VarNames, categoricals:=['TV']); + +summ := prob.Summary(); +OUTPUT(summ, NAMED('DatasetSummary')); + +tests := ['P(X1 >= 2 )', 'P(TV = medium | X5 between [.4,.8])', + 'E(Y4)', 'E(TV| X2 < -.75)', + 'P(X2 between [-.5, .5] | TV in [medium, large])', + 'P(TV=medium)', 'E(TV |X2 between [-1.1, 1.1])']; + +results := prob.Query(tests); + +OUTPUT(results, ALL, NAMED('Probabilities')); + +dtests := ['P(X1)', 'P(TV)', 'P(TV|X2 > -.5)', 'P(Y1 | X1=1)', 'P(X2)', 'P(X4)']; + +dresults := prob.QueryDistr(dtests); + +OUTPUT(dresults, ALL, NAMED('Distributions')); + +ss1 := prob.SubSpace('X2 < 0'); + +ss1summ := prob.Summary(ss1); +OUTPUT(ss1summ, NAMED('DatasetSummarySS')); + +ss1results := prob.Query(tests, ss1); + +OUTPUT(ss1results, ALL, NAMED('ProbabilitiesSS')); + +ss1dresults := prob.QueryDistr(dtests, ss1); + +OUTPUT(ss1dresults, ALL, NAMED('DistributionsSS')); diff --git a/Test/Visualization/vizTest.ecl b/Test/Visualization/vizTest.ecl index 2c8881c..62c4c3c 100644 --- a/Test/Visualization/vizTest.ecl +++ b/Test/Visualization/vizTest.ecl @@ -4,7 +4,7 @@ * * Uses the Synth module to generate the test data. */ -IMPORT HPCC_Causality AS HC; +IMPORT $.^.^ AS HC; IMPORT HC.Types; numRecs := 10000; diff --git a/Test/Visualization/vizTest2.ecl b/Test/Visualization/vizTest2.ecl index 05f19f1..3478a7e 100644 --- a/Test/Visualization/vizTest2.ecl +++ b/Test/Visualization/vizTest2.ecl @@ -1,4 +1,4 @@ -IMPORT HPCC_causality AS HC; +IMPORT $.^.^ AS HC; IMPORT HC.Types; Probability := HC.Probability; @@ -46,28 +46,64 @@ ds0 := DATASET('llcp.csv', fmt, CSV(HEADING(1))); hc.AddID(ds0, ds); -dst := ds[1..10000]; +dst := ds; -hc.ToAnyField(dst, dsf, ,'gender,height,weight,income,age,veteran,genhealth'); +//hc.ToAnyField(dst, dsf, ,'gender,height,weight,income,age,veteran,genhealth,state'); +hc.ToAnyField(dst, dsf); -prob := Probability(dsf, dsf_fields); -tests := DATASET([{1, 'P(height <= 66)'} - ], nlQuery); +categoricals := ['state', 'smokertype']; + +prob := Probability(dsf, dsf_fields, categoricals); + +summary := prob.Summary(); + +OUTPUT(summary, NAMED('DatasetSummary')); + +malesPS := prob.SubSpace('gender=male', prob.PS); + +summary2 := prob.Summary(malesPS); + +OUTPUT(summary2, NAMED('DatasetSummaryMales')); + +femalesPS := prob.SubSpace('gender=female', prob.PS); + +summary3 := prob.Summary(femalesPS); + +OUTPUT(summary3, NAMED('DatasetSummaryFemales')); + +tests := ['E(height | gender=male)', + 'E(height | gender=female)']; results := prob.Query(tests); -query := 'P(height < 66.0 | weight)'; +OUTPUT(results, NAMED('ProbResults')); +//query := 'P(genhealth in [4,5] | state)'; +query := 'P(age)'; +queries := [ + //'E(weight | height, age, gender=male)' + //'E(genhealth | state, controlFor(age, income))' + //'E(genhealth | state)' + //'P(genhealth = 5-excellent |age)', + //'P(genhealth in [3-good, 4-verygood, 5-excellent] | age, income)' + //'P(age > 65, gender=male, married=no | genhealth)' + //'P(genhealth in [4-verygood, 5-excellent] | state, controlFor(age, income))' + //'CORRELATION(gender, income, genhealth, physicalactivity, age, diabetes)', + //'DEPENDENCE(gender, income, genhealth, physicalactivity, age, diabetes)' + //'CMODEL(gender, age, income, height, weight, physicalactivity, education, genhealth)', + //'CMODEL(gender, age, income, height, weight, physicalactivity, education, genhealth | $power=8, $sensitivity=6, $depth=3)' + //'P(age | genhealth in [1-poor, 2-fair])', + //'P(weight | height, gender=male)' + 'P(age)', + 'P(weight | gender=male)', + 'P(weight | gender = female)' + ]; pr := viz.parseQuery(query, prob.PS); -OUTPUT(pr); -vars := viz.getVarNames(pr); -//OUTPUT(vars); -g := viz.GetGrid(pr, prob.PS); -OUTPUT(g); -fg := viz.fillDataGrid(g, ['weight', 'height'], 'bprob', prob.PS); -OUTPUT(fg); +//OUTPUT(pr); +gr := viz.getGrid(pr, prob.PS); +OUTPUT(gr, NAMED('Grid')); cd := viz.GetDataGrid(query, prob.PS); -OUTPUT(cd); -viz.Plot(['E(height | weight)',query], prob.PS); \ No newline at end of file +//OUTPUT(cd); +viz.Plot(queries, prob.PS); \ No newline at end of file diff --git a/Test/Visualization/vizTest3.ecl b/Test/Visualization/vizTest3.ecl new file mode 100644 index 0000000..4b407e8 --- /dev/null +++ b/Test/Visualization/vizTest3.ecl @@ -0,0 +1,92 @@ +/** + * Test and example for Model Validation. + * + * Uses the Synth module to generate M8 model. + * Tests against the M8 model definition: + * B is Exogenous + * F is Exogenous + * G is Exogenous + * A <- B,F + * D <- A,G + * C <- B,A,D + * E <- C + * + */ + +IMPORT HPCC_causality AS HC; + +IMPORT HC.Types; + +IMPORT ML_CORE.Types AS cTypes; + +Probability := HC.Probability; +Causality := HC.Causality; +viz := HC.viz; + +SEM := Types.SEM; + +// Number of test records. +nTestRecs := 100000; + + +// SEM should be a dataset containing a single row. +// SEM is Model M8. +semRow := ROW({ + [], + ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'], // Variable names + // Equations + ['B = logistic(0,1)', // Can use any distribution defined in numpy.random + 'F = logistic(0,1)', + 'G = logistic(0,1)', + 'A = sin(B + F) + logistic(0,.4)', + 'D = tanh(A + G * 2.0) + logistic(0,.4)', + 'C = tanh(B + A + D) + logistic(0,.4)', + 'E = C + logistic(0,.4)', + 'H = "small" if E < 0 else "med" if E < 1 else "large"', + 'I = beta(2,5)', + 'J = int(abs(B * 5)) % 5' + ]}, SEM); + +mySEM := DATASET([semRow], SEM); + +testDat := HC.Synth(mySEM).Generate(nTestRecs); + +OUTPUT(testDat, NAMED('Dat')); + +// Note: The order of variables in the model much match the order of varNames in the SEM. +// RVs := DATASET([ +// {'A', ['B','F']}, +// {'B', []}, +// {'C', ['B', 'A', 'D']}, +// {'D', ['A','G']}, +// {'E', ['C']}, +// {'F', []}, +// {'G', []} +// 'H', +// ], Types.RV); +// mod := DATASET([{'M8', RVs}], Types.cModel); + +OUTPUT(mySEM, NAMED('SEM')); + +prob := Probability(testDat, semRow.VarNames, categoricals:=['H', 'J']); + +// queries := [ +// 'P(A)', +// 'P(A|B)', +// 'E(D | A)', +// 'E(D | A, G)', +// 'P(H = med | E)', +// 'Correlation(A,B,C,D,E,F,G,H)', +// 'CModel()' +// ]; +pq := viz.parseQuery('P(I)', prob.PS); +gr := viz.getGrid(pq, prob.PS); + +OUTPUT(gr, NAMED('grid')); + +queries := [ + 'P(B > .5 | J)', + 'P(A|B)' + ]; +viz.Plot(queries, prob.PS); + \ No newline at end of file diff --git a/Types.ecl b/Types.ecl index 60b023b..db71d87 100644 --- a/Types.ecl +++ b/Types.ecl @@ -24,11 +24,24 @@ EXPORT Types := MODULE * Natural Language Query. * * Supports probability queries in a simple format. + * @field id A unique id for this query. + * @field query A string representing the probability query e.g. 'P(A=1)'. */ EXPORT nlQuery := RECORD UNSIGNED id; STRING query; END; + + /** + * Result of a causal query. Includes the orginal query in addition + * to the AnyField result. + * + * @field query The original query that produced this result. + */ + EXPORT nlQueryRslt := RECORD(AnyField) + STRING query; + END; + /** * Record layout for Probability Query parameters * @@ -101,11 +114,26 @@ EXPORT Types := MODULE REAL P; END; + /** + * Child dataset of Distribution to hold the mapping between string values and + * their numeric eqivalent + */ EXPORT StrValEntry := RECORD UNSIGNED numVal; STRING strVal; END; + /** + * Input to a causal metric query. + * @field id A unique id for this query + * @field cause The name of the causal variable for the query + * @field effect The name of the effect variable for the query + */ + EXPORT MetricQuery := RECORD + UNSIGNED id; + STRING cause; + STRING effect; + END; /** * Record to represent the Distribution of a single random variable * @@ -291,7 +319,7 @@ EXPORT Types := MODULE END; /** - * Results of the DiscoverModel function. + * Results of the ScanModel function. * * Provides the information about what was discovered * from analyzing the dataset. @@ -305,7 +333,7 @@ EXPORT Types := MODULE * @field VarGraph A list of variables and the set of parents for * each, representing a Directed Acyclic Graph (DAG) of variable relationships. */ - EXPORT DiscoveryReport := RECORD + EXPORT ScanReport := RECORD SET OF STRING Exos; SET OF STRING Clusters; DATASET(SetMembers) ClustMembers; @@ -313,11 +341,73 @@ EXPORT Types := MODULE DATASET(SetMembers) VarGraph; END; + /** + * Results of the DiscoveryModel function + * Provides the discovered causal model as a list of edges [cause, effect], and + * associated metrics. + * + * @field causeVar The name of the causal variable in the relationship + * @field effectVar The name of the effect variable in the relationship + * @field strength The strength of the dependence between the variables + * @field correlation The statistical correlation between the variables + * @field MDE The Maximum Direct Effect of the cause on the effect variable. + */ + EXPORT DiscoveryResult := RECORD + STRING causeVar; + STRING effectVar; + REAL strength; + REAL correlation; + REAL MDE; + END; + +/** + * Child data type for DatasetSummary below. Describes a single variable + * in the dataset. + * + * @field name The name of the variable. + * @field isDiscrete True if the variable is discrete, otherwise False. + * @field isCategorical True if the variable is categorical, otherwise False. + * @field isTextual True if the variable is a text-based categorical, otherwise False. + * @field cardinality The number of unique values which the discrete variable takes in the dataset. + * @field numValues The numeric values the discrete variable takes in the dataset. + * @field textValues The textual values the textual categorical variables takes in the dataset + */ + EXPORT VarSummary := RECORD + STRING name; + BOOLEAN isDiscrete; + BOOLEAN isCategorical; + BOOLEAN isTextual; + UNSIGNED cardinality; + SET OF REAL numValues; + SET OF STRING textValues; + END; + /** + * Dataset Summary returned from Probability.Summary. + * + * Provides an overview of the dataset. + * @field numRecords The number of records in the dataset. + * @field varNames A set of the variable names in the dataset + * @field varDetails A set of Var Summary records describing each variable in the dataset. + */ + EXPORT DatasetSummary := RECORD + UNSIGNED numRecords; + SET OF STRING varNames; + DATASET(VarSummary) varDetails; + END; + + + /** + * @internal + * Internal data type used by visualization + */ EXPORT ChartGrid := RECORD UNSIGNED id; DATASET(AnyField) gridItem; END; - + /** + * @internal + * Internal data type used by visualization + */ EXPORT ChartData := RECORD UNSIGNED id; STRING x_; @@ -328,11 +418,15 @@ EXPORT Types := MODULE REAL range2low := 0.0; REAL range2high := 0.0; END; - + /** + * @internal + * Internal data type used by visualization + */ EXPORT ChartInfo := RECORD STRING dataname; STRING qtype; UNSIGNED dims; + STRING title; STRING xlabel; STRING ylabel; STRING zlabel; @@ -342,4 +436,5 @@ EXPORT Types := MODULE REAL range2low; REAL range2high; END; + END; diff --git a/internal/ProbSpace.ecl b/internal/ProbSpace.ecl index cd54307..8ba0fb6 100644 --- a/internal/ProbSpace.ecl +++ b/internal/ProbSpace.ecl @@ -12,6 +12,7 @@ ProbQuery := Types.ProbQuery; PDist := Types.Distribution; AnyField := Types.AnyField; nlQuery := Types.nlQuery; +DatasetSummary := Types.DatasetSummary; globalScope := 'probspace' + node + '.ecl'; @@ -39,8 +40,6 @@ EXPORT ProbSpace := MODULE EMBED(Python: globalscope(globalScope), persist('query'), activity) from because.probability import ProbSpace from because.hpcc_utils import globlock # Global lock - globlock.allocate() - globlock.acquire() global extractSpec def _extractSpec(inSpecs): """ @@ -71,13 +70,12 @@ EXPORT ProbSpace := MODULE outSpecs.append(outSpec) return outSpecs extractSpec = _extractSpec - global PS - if 'PS' in globals(): - # Probspace already allocated on this node (by another thread). We're done. - # Release the global lock - globlock.release() - return [(1,)] + globlock.allocate() + globlock.acquire() + global PSDict try: + if 'PSDict' not in globals(): + PSDict = {} DS = {} varMap = {} for i in range(len(vars)): @@ -96,9 +94,11 @@ EXPORT ProbSpace := MODULE ids.append(id) lastId = id PS = ProbSpace(DS, categorical=pycategoricals) + psID = len(PSDict) + 1 + PSDict[psID] = PS # Release the global lock globlock.release() - return [(1,)] + return [(psID,)] except: from because.hpcc_utils import format_exc # Release the global lock @@ -108,10 +108,79 @@ EXPORT ProbSpace := MODULE ds_distr := DISTRIBUTE(ds, ALL); ds_S := SORT(NOCOMBINE(ds_distr), id, number, LOCAL); psds := pyInit(NOCOMBINE(ds_S), varNames, categoricals, node, nNodes); - ps := SUM(psds, id); - RETURN ps; + psid := MAX(psds, id); + RETURN psid; END; + /** + * Dataset Summary + */ + EXPORT DatasetSummary getSummary(UNSIGNED ps) := + EMBED(Python: globalscope(globalScope), persist('query')) + assert 'PSDict' in globals(), 'ProbSpace.DatasetSummary: PSDict is not initialized.' + assert ps in PSDict, 'ProbSpace.DatasetSummary: invalid probspace id = ' + str(ps) + PS = PSDict[ps] + try: + nRecs = PS.N + vars = PS.getVarNames() + varDetails = [] + for var in vars: + vals = [] + strVals = [] + isDisc = PS.isDiscrete(var) + isCat = PS.isCategorical(var) + isStr = PS.isStringVal(var) + if isDisc: + card = PS.cardinality(var) + rawvals = PS.getValues(var) + if isStr: + strVals = rawvals + for val in rawvals: + nval = PS.strToNum(var, val) + vals.append(float(nval)) + else: + vals = [float(rawval) for rawval in rawvals] + else: + card = nRecs + varDetails.append((var, isDisc, isCat, isStr, card, vals, strVals)) + return ((nRecs, vars, varDetails)) + except: + from because.hpcc_utils import format_exc + assert False, format_exc.format('ProbSpace.getSummary') + + ENDEMBED; + + EXPORT STREAMED DATASET(dummyRec) SubSpace(STREAMED DATASET(nlQuery) filters, UNSIGNED ps) := + EMBED(Python: globalscope(globalScope), persist('query'), activity) + from because.hpcc_utils.parseQuery import Parser + assert 'PSDict' in globals(), 'ProbSpace.SubSpace: PSDict is not initialized.' + assert ps in PSDict, 'ProbSpace.SubSpace: invalid probspace id = ' + str(ps) + PS = PSDict[ps] + # Should only be one query in the dataset + try: + for filter in filters: + id, filt = filter + # We modify the filter to make it look like a probability query so that + # we can re-use the parser + query = 'P(' + filt + ')' + qs = [query] + PARSER = Parser() + specList = PARSER.parse(qs) + spec = specList[0] + cmd, targs, conds, ctrlfor, intervs, cfac = spec + # We only care about the target clause, which is now a structured filter. + sfilt = targs + ss = PS.SubSpace(sfilt) + psid = len(PSDict) + 1 + PSDict[psid] = ss + return ([(psid,)]) + except: + from because.hpcc_utils import format_exc + assert False, format_exc.format('ProbSpace.SubSpace') + ENDEMBED; + + + /** * Call the ProbSpace.P() function with a set of queries. * @@ -120,7 +189,9 @@ EXPORT ProbSpace := MODULE */ EXPORT STREAMED DATASET(NumericField) P(STREAMED DATASET(ProbQuery) queries, UNSIGNED ps) := EMBED(Python: globalscope(globalScope), persist('query'), activity) - assert 'PS' in globals(), 'ProbSpace.P: PS is not initialized.' + assert 'PSDict' in globals(), 'ProbSpace.P: PSDict is not initialized.' + assert ps in PSDict, 'ProbSpace.P: invalid probspace id = ' + str(ps) + PS = PSDict[ps] try: results = [] for query in queries: @@ -147,7 +218,9 @@ EXPORT ProbSpace := MODULE */ EXPORT STREAMED DATASET(AnyField) E(STREAMED DATASET(ProbQuery) queries, UNSIGNED ps) := EMBED(Python: globalscope(globalScope), persist('query'), activity) - assert 'PS' in globals(), 'ProbSpace.E: PS is not initialized.' + assert 'PSDict' in globals(), 'ProbSpace.E: PSDict is not initialized.' + assert ps in PSDict, 'ProbSpace.E: invalid probspace id = ' + str(ps) + PS = PSDict[ps] try: results = [] for query in queries: @@ -158,10 +231,14 @@ EXPORT ProbSpace := MODULE targets = targets[0] conditions = extractSpec(conds) result = PS.E(targets, conditions) - if type(result) == type(''): - results.append((1, id, 1, 0, result)) + if result is None: + # No data fits the condition. Numeric answer cannot be returned. + results.append((1, id, 1, 0.0, 'Expectation Error -- No data fits condition')) + result + elif type(result) == type(''): + results.append((1, id, 1, 0.0, result)) else: - results.append((1, id, 1, result, '')) + results.append((1, id, 1, float(result), '')) return results except: from because.hpcc_utils import format_exc @@ -171,7 +248,9 @@ EXPORT ProbSpace := MODULE EXPORT STREAMED DATASET(AnyField) Query(STREAMED DATASET(nlQuery) queries, UNSIGNED ps) := EMBED(Python: globalscope(globalScope), persist('query'), activity) from because.probability import probquery - assert 'PS' in globals(), 'ProbSpace.E: PS is not initialized.' + assert 'PSDict' in globals(), 'ProbSpace.Query: PSDict is not initialized.' + assert ps in PSDict, 'ProbSpace.Query: invalid probspace id = ' + str(ps) + PS = PSDict[ps] try: inQueries = [] inIds = [] @@ -202,10 +281,11 @@ EXPORT ProbSpace := MODULE */ EXPORT STREAMED DATASET(PDist) QueryDistr(STREAMED DATASET(nlQuery) queries, UNSIGNED ps) := EMBED(Python: globalscope(globalScope), persist('query'), activity) - from because.hpcc_utils import formatQuery - import numpy as np from because.probability import probquery - assert 'PS' in globals(), 'ProbSpace.Distr: PS is not initialized.' + import numpy as np + assert 'PSDict' in globals(), 'ProbSpace.QueryDistr: PSDict is not initialized.' + assert ps in PSDict, 'ProbSpace.QueryDistr: invalid probspace id = ' + str(ps) + PS = PSDict[ps] try: inQueries = [] inIds = [] @@ -217,6 +297,131 @@ EXPORT ProbSpace := MODULE for i in range(len(results)): id = inIds[i] dist = results[i] + if dist is None: + # No distribution can be created. + yield ( id, + inQueries[i], + 0, + False, + False, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + [False, False], + [0.0, 0.0], + 0, + [], + [], + [(0, 'Distribution Error -- Not enough data points to assess distribution.')] + ) + else: + hist = [] + for entry in dist.ToHistTuple(): + minv, maxv, p = entry + hist.append((float(minv), float(maxv), float(p))) + isDiscrete = dist.isDiscrete + isCategorical = PS.isCategorical(dist.rvName) + deciles = [] + if not isDiscrete: + # Only do deciles for continuous data. + for p in range(10, 100, 10): + decile = float(dist.percentile(p)) + deciles.append((float(p), float(p), decile)) + stringVals = [] + if PS.isStringVal(dist.rvName): + strVals = PS.getValues(dist.rvName) + for j in range(len(strVals)): + strVal = strVals[j] + numVal = int(PS.getNumValue(dist.rvName, strVal)) + stringVals.append((numVal, strVal)) + stringVals.sort() + bounds = dist.truncation() + isBoundedL = not isDiscrete and bounds[0] is not None + isBoundedU = not isDiscrete and bounds[1] is not None + boundL = boundU = 0.0 + if isBoundedL: + boundL = bounds[0] + if isBoundedU: + boundU = bounds[1] + modality = dist.modality() + + yield ( id, + inQueries[i], + dist.N, + isDiscrete, + isCategorical, + float(dist.minVal()), + float(dist.maxVal()), + dist.E(), + dist.stDev(), + dist.skew(), + dist.kurtosis(), + float(dist.median()), + float(dist.mode()), + [isBoundedL, isBoundedU], + [boundL, boundU], + modality, + hist, + deciles, + stringVals + ) + except: + from because.hpcc_utils import format_exc + assert False, format_exc.format('QueryDistr') + ENDEMBED; + + /** + * Call the ProbSpace.distr() function with a set of queries. + * + * Queries are distributed among nodes so that the run in parallel. + * Returns distributions as Types.Distribution dataset + * + */ + EXPORT STREAMED DATASET(PDist) Distr(STREAMED DATASET(ProbQuery) queries, UNSIGNED ps) := + EMBED(Python: globalscope(globalScope), persist('query'), activity) + from because.hpcc_utils import formatQuery + import numpy as np + assert 'PSDict' in globals(), 'ProbSpace.Distr: PSDict is not initialized.' + assert ps in PSDict, 'ProbSpace.Distr: invalid probspace id = ' + str(ps) + PS = PSDict[ps] + try: + results = [] + for query in queries: + targets = [] + id, targs, conds = query[:3] + targets = extractSpec(targs) + assert len(targets) == 1 and len(targets[0]) == 1, 'ProbSpace.Distr: Target must be single and unbound (i.e. No arguments provided).' + targets = targets[0] + conditions = extractSpec(conds) + dist = PS.distr(targets, conditions) + if dist is None: + # No distribution can be created. + yield ( id, + formatQuery.format('distr', [targets], conditions), + 0, + False, + False, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + [False, False], + [0.0, 0.0], + 0, + [], + [], + [(0, 'Distribution Error -- Not enough data points to assess distribution.')] + ) + continue hist = [] for entry in dist.ToHistTuple(): minv, maxv, p = entry @@ -248,7 +453,7 @@ EXPORT ProbSpace := MODULE modality = dist.modality() yield ( id, - inQueries[i], + formatQuery.format('distr', [targets], conditions), dist.N, isDiscrete, isCategorical, @@ -267,71 +472,7 @@ EXPORT ProbSpace := MODULE deciles, stringVals ) - except: - from because.hpcc_utils import format_exc - assert False, format_exc.format('QueryDistr') - ENDEMBED; - - /** - * Call the ProbSpace.distr() function with a set of queries. - * - * Queries are distributed among nodes so that the run in parallel. - * Returns distributions as Types.Distribution dataset - * - */ - EXPORT STREAMED DATASET(PDist) Distr(STREAMED DATASET(ProbQuery) queries, UNSIGNED ps) := - EMBED(Python: globalscope(globalScope), persist('query'), activity) - from because.hpcc_utils import formatQuery - import numpy as np - assert 'PS' in globals(), 'ProbSpace.Distr: PS is not initialized.' - try: - results = [] - for query in queries: - targets = [] - id, targs, conds = query[:3] - targets = extractSpec(targs) - assert len(targets) == 1 and len(targets[0]) == 1, 'ProbSpace.Distr: Target must be single and unbound (i.e. No arguments provided).' - targets = targets[0] - conditions = extractSpec(conds) - dist = PS.distr(targets, conditions) - hist = [] - for entry in dist.ToHistTuple(): - minv, maxv, p = entry - hist.append((float(minv), float(maxv), float(p))) - isDiscrete = dist.isDiscrete - isCategorical = PS.isCategorical(dist.rvName) - deciles = [] - if not isDiscrete: - # Only do deciles for continuous data. - for p in range(10, 100, 10): - decile = float(dist.percentile(p)) - deciles.append((float(p), float(p), decile)) - stringVals = [] - if PS.isStringVal(dist.rvName): - strVals = PS.getValues(rvName) - for i in range(len(strVals)): - strVal = strVals[i] - numVal = int(PS.getNumValue(dist.rvName, strVal)) - stringVals.append((numVal, strVal)) - stringVals.sort() - results.append((id, - formatQuery.format('distr', [(targets,)], conditions), - dist.N, - isDiscrete, - isCategorical, - float(dist.minVal()), - float(dist.maxVal()), - dist.E(), - dist.stDev(), - dist.skew(), - dist.kurtosis(), - float(dist.median()), - float(dist.mode()), - hist, - deciles, - stringVals - )) return results except: from because.hpcc_utils import format_exc @@ -347,15 +488,17 @@ EXPORT ProbSpace := MODULE EXPORT STREAMED DATASET(NumericField) Dependence(STREAMED DATASET(ProbQuery) queries, UNSIGNED ps) := EMBED(Python: globalscope(globalScope), persist('query'), activity) - assert 'PS' in globals(), 'ProbSpace.Dependence: PS is not initialized.' + assert 'PSDict' in globals(), 'ProbSpace.Dependence: PSDict is not initialized.' + assert ps in PSDict, 'ProbSpace.Dependnce: invalid probspace id = ' + str(ps) + PS = PSDict[ps] try: results = [] for query in queries: targets = [] id, targs, conds = query[:3] for targ in targs: - var, args = targ - assert len(args) == 0, 'ProbSpace.Dependence: Target must be unbound (i.e. No arguments provided).' + var, args, strArgs = targ[:3] + assert len(args) == 0 and len(strArgs) == 0, 'ProbSpace.Dependence: Target must be unbound (i.e. No arguments provided).' targSpec = var targets.append(targSpec) assert len(targets) == 2, 'ProbSpace.Dependence: Dependence requires two targets. ' + str(len(targets)) + ' were given.' @@ -363,11 +506,16 @@ EXPORT ProbSpace := MODULE v2 = targets[1] conditions = [] for cond in conds: - cVar, cArgs = cond - if len(cArgs) >= 1: - condition = (cVar,) + tuple(cArgs) + cVar, cNumArgs, cStrArgs, cIsList = cond + if len(cStrArgs) > 0: + cArgs = cStrArgs else: - condition = cVar + cArgs = cNumArgs + + if cIsList: + condition = (cVar,) + (tuple(cArgs),) + else: + condition = (cVar,) + tuple(cArgs) conditions.append(condition) result = PS.dependence(v1, v2, conditions) results.append((1, id, 1, result)) @@ -383,8 +531,12 @@ EXPORT ProbSpace := MODULE * Queries are distributed among nodes so that the run in parallel. * */ - EXPORT STREAMED DATASET(NumericField) Predict(STREAMED DATASET(NumericField) ds, SET OF STRING varNames, STRING target, UNSIGNED ps) := + EXPORT STREAMED DATASET(NumericField) Predict(STREAMED DATASET(NumericField) ds, + SET OF STRING varNames, STRING target, UNSIGNED ps) := EMBED(Python: globalscope(globalScope), persist('query'), activity) + assert 'PSDict' in globals(), 'ProbSpace.Predict: PSDict is not initialized.' + assert ps in PSDict, 'ProbSpace.Predict: invalid probspace id = ' + str(ps) + PS = PSDict[ps] try: ids = [] prevId = None @@ -423,6 +575,9 @@ EXPORT ProbSpace := MODULE */ EXPORT STREAMED DATASET(NumericField) Classify(STREAMED DATASET(NumericField) ds, SET OF STRING varNames, STRING target, UNSIGNED ps) := EMBED(Python: globalscope(globalScope), persist('query'), activity) + assert 'PSDict' in globals(), 'ProbSpace.Classify: PSDict is not initialized.' + assert ps in PSDict, 'ProbSpace.Classify: invalid probspace id = ' + str(ps) + PS = PSDict[ps] try: ids = [] prevId = None diff --git a/internal/cModel.ecl b/internal/cModel.ecl index 60ba13f..d97dfd3 100644 --- a/internal/cModel.ecl +++ b/internal/cModel.ecl @@ -9,12 +9,17 @@ nNodes := Thorlib.nodes(); node := Thorlib.node(); NumericField := cTypes.NumericField; +AnyField := Types.AnyField; +nlQuery := Types.nlQuery; +nlQueryRslt := Types.nlQueryRslt; cModelTyp := Types.cModel; PDist := Types.Distribution; ValidationReport := Types.ValidationReport; ProbQuery := Types.ProbQuery; +MetricQuery := Types.MetricQuery; cMetrics := Types.cMetrics; -DiscoveryReport := Types.DiscoveryReport; +ScanReport := Types.ScanReport; +DiscResult := Types.DiscoveryResult; globalScope := 'probspace' + node + '.ecl'; @@ -32,6 +37,10 @@ varMetrics := RECORD DATASET(varMetricsItem) directions; END; +varsRec := RECORD + SET OF STRING vars; +END; + /** * Internal Module to provide access to the Causality methods of the python "Because.causality" package. * @@ -45,23 +54,23 @@ EXPORT cModel := MODULE * It returns an UNSIGNED, which is passed on to all other functions to make sure * that Init is run before them. */ - EXPORT UNSIGNED Init(DATASET(cModelTyp) mod, DATASET(NumericField) ds) := FUNCTION + EXPORT UNSIGNED Init(DATASET(cModelTyp) mod, UNSIGNED PS) := FUNCTION - STREAMED DATASET(dummyRec) pyInit(STREAMED DATASET(NumericField) ds, STREAMED DATASET(cModelTyp) mods, + STREAMED DATASET(dummyRec) pyInit(STREAMED DATASET(cModelTyp) mods, UNSIGNED ps, UNSIGNED pynode, UNSIGNED pynnodes) := EMBED(Python: globalscope(globalScope), persist('query'), activity) from because.causality import cgraph from because.causality import rv from because.hpcc_utils import globlock - global CM, NODE, NNODES + global CMDict, NODE, NNODES globlock.allocate() globlock.acquire() - if 'CM' in globals(): - # Already Initialized. We are done. - # Release the global lock - globlock.release() - return [(1,)] try: + assert 'PSDict' in globals(), 'CModel.Init: PSDict is not initialized.' + assert ps in PSDict, 'CModel.Init: invalid probspace id = ' + str(ps) + PS = PSDict[ps] + if 'CMDict' not in globals(): + CMDict = {} # Save the node number and the number of nodes NODE = pynode NNODES = pynnodes @@ -82,29 +91,21 @@ EXPORT cModel := MODULE varMap[i+1] = rvName newrv = rv.RV(rvName, rvParents, rvIsDiscrete, rvType) RVs.append(newrv) - ids = [] - lastId = None - for rec in ds: - wi, id, num, val = rec - DS[varMap[num]].append(val) - if id != lastId: - ids.append(id) - lastId = id - CM = cgraph.cGraph(RVs, DS) + CM = cgraph.cGraph(RVs, ps=PS) + cmID = len(CMDict) + 1 + CMDict[cmID] = CM # Release the global lock globlock.release() - return [(1,)] + return [(cmID,)] except: from because.hpcc_utils import format_exc # Release the global lock globlock.release() assert False, format_exc.format('cModel.Init') ENDEMBED; - ds_distr := DISTRIBUTE(ds, ALL); - ds_S := SORT(NOCOMBINE(ds_distr), id, number, LOCAL); mod_distr := DISTRIBUTE(mod, ALL); - cmds := pyInit(ds_S, mod_distr, node, nNodes); - cm := SUM(cmds, id); + cmds := pyInit(mod_distr, PS, node, nNodes); + cm := MAX(cmds, id); RETURN cm; END; /** @@ -118,8 +119,11 @@ EXPORT cModel := MODULE * is fully paralellized. Calculating the final score is light weight. * */ - EXPORT STREAMED DATASET(ValidationReport) TestModel(UNSIGNED order, UNSIGNED power, UNSIGNED cm) := + EXPORT STREAMED DATASET(ValidationReport) TestModel(UNSIGNED order, REAL pwr, REAL sensitivity, UNSIGNED cm) := EMBED(Python: globalscope(globalScope), persist('query'), activity) + assert 'CMDict' in globals(), 'cModel.TestModel: CMDict is not initialized.' + assert cm in CMDict, 'cModel.TestModel: invalid cModel id = ' + str(ps) + CM = CMDict[cm] try: rep = None deps = CM.computeDependencies(order) @@ -136,29 +140,8 @@ EXPORT cModel := MODULE # by one node. if NODE == i % NNODES: myEdges.append(edges[i]) - rep = CM.TestModel(order = order, power=power, deps = myDeps, edges = myEdges) - # - confidence is an estimate of the likelihood that the data generating process defined - # by the model produced the data being tested. Ranges from 0.0 to 1.0. - # - numTotalTests is the number of independencies and dependencies implied by the model. - # - numTestsPerType is a list, for each error type, 0 - nTypes, of the number of tests that - # test for the given error type. - # - numErrsPerType is a list, for each error type, of the number of failed tests. - # - numWarnsPerType is a list, for each error type, of the number of tests with warnings. - # - errorDetails is a list of failed tests, each with the following format: - # [(errType, x, y, z, isDep, errStr)] - # Where: - # errType = 0 (Exogenous variables not independent) or; - # 1 (Expected independence not observed) or; - # 2 (Expected dependence not observed) - # x, y, z are each a list of variable names that - # comprise the statement x _||_ y | z. - # That is x is independent of y given z. - # isDep True if a dependence is expected. False for - # independence - # pval -- The p-val returned from the independence test - # errStr A human readable error string describing the error - # - warningDetails is a list of tests with warnings. Format is the same as - # for errorDetails above. + rep = CM.TestModel(order = order, power=pwr, sensitivity=sensitivity, deps = myDeps, edges = myEdges) + #assert(False, 'rep = ' + str(rep)) conf, numTotal, numPerType, numErrsPerType, numWarnsPerType, errorDetails, warnDetails = rep errStrs = [err[6] for err in errorDetails] warnStrs = [warn[6] for warn in warnDetails] @@ -177,6 +160,9 @@ EXPORT cModel := MODULE EXPORT REAL ScoreModel(SET OF UNSIGNED numtestspertype, SET OF UNSIGNED numerrspertype, SET OF UNSIGNED numwarnspertype, UNSIGNED cm) := EMBED(Python: globalscope(globalScope), persist('query')) + assert 'CMDict' in globals(), 'cModel.ScoreModel: CMDict is not initialized.' + assert cm in CMDict, 'cModel.ScoreModel: invalid cModel id = ' + str(ps) + CM = CMDict[cm] try: confidence = CM.scoreModel(numtestspertype, numerrspertype, numwarnspertype) return confidence @@ -189,7 +175,9 @@ EXPORT cModel := MODULE EMBED(Python: globalscope(globalScope), persist('query'), activity) import numpy as np from because.hpcc_utils import formatQuery - assert 'CM' in globals(), 'cModel.Intervene: CM is not initialized.' + assert 'CMDict' in globals(), 'cModel.Intervene: CMDict is not initialized.' + assert cm in CMDict, 'cModel.Intervene: invalid cModel id = ' + str(ps) + CM = CMDict[cm] try: results = [] for query in queries: @@ -250,6 +238,153 @@ EXPORT cModel := MODULE assert False, format_exc.format('cModel.Intervene') ENDEMBED; + /** + * Call the causality.P() (Probability) function or E() (Expectation) + * function with a set of natural language causal queries. Returns a + * value (numeric or string). + * + * Causal Queries are a superset of probability queries. They allow + * an intervention clause (i.e. do(...)) to be specified. A mixture + * of probability and causal queries may be provided. + * + * Queries should be of type Probability (i.e. P), or Expectation (i.e. E), + * and the target variable(s) must be bound (i.e. include a comparator) for P(...) or + * unbound (i.e. have no comparison operator -- a bare variable name) for E(...). + * Multiple targets may be specified in the case of P(...), indicating joint probabilities. + * + * Examples: + * P(Income > 3, Employed=no | Age > 65) -- The probability that income is greater than 3 + * and unemployed for people over 65 (Joint conditional probability). + * E(Income | Age > 65 do('Employed=yes')) -- The Expected value of income + * for people over 65, if we intervened such that + * everyone was employed. (Conditional expectation plus intervention) + * + * Queries are distributed among nodes so that they run in parallel. + * Returns values as Types.nlQueryRslt dataset + * + */ + EXPORT STREAMED DATASET(nlQueryRslt) Query(STREAMED DATASET(nlQuery) queries, UNSIGNED cm) := + EMBED(Python: globalscope(globalScope), persist('query'), activity) + from because.causality import cquery + assert 'CMDict' in globals(), 'cModel.Query: CMDict is not initialized.' + assert cm in CMDict, 'cModel.Query: invalid cModel id = ' + str(ps) + CM = CMDict[cm] + try: + inQueries = [] + inIds = [] + for item in queries: + id, query = item + inQueries.append(query) + inIds.append(id) + results = cquery.queryList(CM, inQueries, allowedResults=['P','E']) + for i in range(len(results)): + result = results[i] + q = inQueries[i] + id = inIds[i] + if type(result) == type(''): + yield (1, id, 1, 0.0, result, q) + else: + yield (1, id, 1, float(result), '', q) + except: + from because.hpcc_utils import format_exc + assert False, format_exc.format('ProbSpace.Query') + ENDEMBED; + + /** + * Call the causality.distr() function with a set of natural language + * causal queries. Returns a distribution. + * + * Causal Queries are a superset of probability queries. They allow + * an intervention clause (i.e. do(...)) to be specified. A mixture + * of probability and causal queries may be provided. + * + * Queries should be of type Probability (i.e. P), and the target variable + * must be unbound (i.e. have no comparison operator -- a bare variable name). + * + * Examples: + * 'P(Income | Age > 65)' -- The probability distribution of income + * for people over 65. + * 'P(Income | Age > 65, do(Employed=yes))' -- The probability distribution + * for people over 65, if we intervened such that + * everyone was employed. + * + * Queries are distributed among nodes so that they run in parallel. + * Returns distributions as Types.Distribution dataset + * + */ + EXPORT STREAMED DATASET(PDist) QueryDistr(STREAMED DATASET(nlQuery) queries, UNSIGNED cm) := + EMBED(Python: globalscope(globalScope), persist('query'), activity) + from because.causality import cquery + import numpy as np + assert 'CMDict' in globals(), 'cModel.Query: CMDict is not initialized.' + assert cm in CMDict, 'cModel.Query: invalid cModel id = ' + str(cm) + CM = CMDict[cm] + PS = CM.prob + try: + inQueries = [] + inIds = [] + for item in queries: + id, query = item + inQueries.append(query) + inIds.append(id) + results = cquery.queryList(CM, inQueries, allowedResults=['D']) + for i in range(len(results)): + id = inIds[i] + dist = results[i] + hist = [] + for entry in dist.ToHistTuple(): + minv, maxv, p = entry + hist.append((float(minv), float(maxv), float(p))) + isDiscrete = dist.isDiscrete + isCategorical = PS.isCategorical(dist.rvName) + deciles = [] + if not isDiscrete: + # Only do deciles for continuous data. + for p in range(10, 100, 10): + decile = float(dist.percentile(p)) + deciles.append((float(p), float(p), decile)) + stringVals = [] + if PS.isStringVal(dist.rvName): + strVals = PS.getValues(dist.rvName) + for j in range(len(strVals)): + strVal = strVals[j] + numVal = int(PS.getNumValue(dist.rvName, strVal)) + stringVals.append((numVal, strVal)) + stringVals.sort() + bounds = dist.truncation() + isBoundedL = not isDiscrete and bounds[0] is not None + isBoundedU = not isDiscrete and bounds[1] is not None + boundL = boundU = 0.0 + if isBoundedL: + boundL = bounds[0] + if isBoundedU: + boundU = bounds[1] + modality = dist.modality() + + yield ( id, + inQueries[i], + dist.N, + isDiscrete, + isCategorical, + float(dist.minVal()), + float(dist.maxVal()), + dist.E(), + dist.stDev(), + dist.skew(), + dist.kurtosis(), + float(dist.median()), + float(dist.mode()), + [isBoundedL, isBoundedU], + [boundL, boundU], + modality, + hist, + deciles, + stringVals + ) + except: + from because.hpcc_utils import format_exc + assert False, format_exc.format('QueryDistr') + ENDEMBED; /** * Calculate causal metrics: Average Causal Effect, Controlled Direct Affect, and Indirect Effect * for a list of variable pairs. @@ -257,26 +392,17 @@ EXPORT cModel := MODULE * The work is divvied up among the nodes, so is fully parallelized. * */ - EXPORT STREAMED DATASET(cMetrics) Metrics(STREAMED DATASET(ProbQuery) queries, UNSIGNED pwr, UNSIGNED cm) := + EXPORT STREAMED DATASET(cMetrics) Metrics(STREAMED DATASET(MetricQuery) queries, UNSIGNED pwr, UNSIGNED cm) := EMBED(Python: globalscope(globalScope), persist('query'), activity) import numpy as np - assert 'CM' in globals(), 'cModel.Metrics: CM is not initialized.' + assert 'CMDict' in globals(), 'cModel.Metrics: CMDict is not initialized.' + assert cm in CMDict, 'cModel.Metrics: invalid cModel id = ' + str(cm) + CM = CMDict[cm] try: results = [] for query in queries: targets = [] - id, targs, conds, dolist = query[:4] - for targ in targs: - var, args = targ - assert len(args) == 0, 'cModel.Metrics: Target must be unbound (i.e. No arguments provided).' - targSpec = var - targets.append(targSpec) - assert len(targets) == 2, 'cModel.Metrics: Metrics require two unbound targets ' + str(len(targets)) + ' were given.' - interventions = [] - assert len(conds) == 0, 'cModel.Metrics: Conditions are not allowed in metrics query.' - assert len(dolist) == 0, 'cModel.Metrics: Interventions are not allowed in metrics query.' - cause = targets[0] - effect = targets[1] + id, cause, effect = query ace = CM.ACE(cause, effect, power=pwr) cde = CM.CDE(cause, effect, power=pwr) cie = ace - cde @@ -312,13 +438,21 @@ EXPORT cModel := MODULE * The workload is automatically allocated among the nodes, so that each variable pairing * is executed on only one node. */ - EXPORT DATASET(Cache) pyGetCache(DATASET(dummyRec) dummy, UNSIGNED cm, UNSIGNED pynode, UNSIGNED pynnodes, UNSIGNED order=3, UNSIGNED pwr=1) := + EXPORT DATASET(Cache) pyGetCache(STREAMED DATASET(varsRec) vars, UNSIGNED cm, UNSIGNED pynode, UNSIGNED pynnodes, UNSIGNED order=3, UNSIGNED pwr=1) := EMBED(Python: globalscope(globalScope), persist('query'), activity) - assert 'CM' in globals(), 'cModel.getCache: CM is not initialized.' + assert 'CMDict' in globals(), 'cModel.pyGetCache: CMDict is not initialized.' + assert cm in CMDict, 'cModel.pyGetCache: invalid cModel id = ' + str(cm) + CM = CMDict[cm] try: indCache = {} dirCache = {} - vars = CM.varNames() + vars = [] + for rec in vars: + # Should be exactly one RECORD + vars = rec.vars + if not vars: + # If not supplied, use all vars. + vars = CM.prob.getVarNames() item = 0 for i in range(len(vars)): v1 = vars[i] @@ -351,23 +485,26 @@ EXPORT cModel := MODULE * The work is automatically distributed among nodes using pyGetCache (above). * */ - EXPORT getCache(UNSIGNED cm, UNSIGNED order=3, UNSIGNED pwr=1) := FUNCTION - d := DATASET([], dummyRec); - cache := pyGetCache(d, cm, node, nnodes, order, pwr); + EXPORT getCache(SET OF STRING vars, UNSIGNED cm, UNSIGNED order=3, UNSIGNED pwr=1) := FUNCTION + // Create a vars record on each node + varsDat := DATASET([{vars}], varsRec, LOCAL); + cache := pyGetCache(varsDat, cm, node, nnodes, order, pwr); return cache; END; /** - * Embedded function to execute a causal scan (discovery) on a single node. + * Embedded function to execute a causal scan on a single node. * * The cache parameter allows much of the heavy lifting to be done in parallel * using getCache (above). There is still quite a bit of work that is done on a single * node and cannot be distributed. */ - SHARED DiscoveryReport pyDiscoverModel(UNSIGNED pwr, UNSIGNED cm, DATASET(cache) pycache=DATASET([], cache)) := + SHARED ScanReport pyScanModel(UNSIGNED pwr, UNSIGNED cm, DATASET(cache) pycache=DATASET([], cache)) := EMBED(Python: globalscope(globalScope), persist('query')) from because.causality import cscan - assert 'CM' in globals(), 'cModel.pyDiscoverModel: CM is not initialized.' + assert 'CMDict' in globals(), 'cModel.pyScanModel: CMDict is not initialized.' + assert cm in CMDict, 'cModel.pyScanModel: invalid cModel id = ' + str(cm) + CM = CMDict[cm] try: dirCache = {} for rec in pycache: @@ -413,18 +550,87 @@ EXPORT cModel := MODULE from because.hpcc_utils import format_exc assert False, format_exc.format('cModel.pyDiscoverModel') - ENDEMBED; + ENDEMBED; // PyScanModel + + /** + * Embedded function to execute a causal discovery on a single node. + * + * The cache parameter allows much of the heavy lifting to be done in parallel + * using getCache (above). There is still quite a bit of work that is done on a single + * node and cannot be distributed. + */ + SHARED DATASET(DiscResult) pyDiscModel(SET OF STRING vars, REAL pwr, REAL sensitivity, UNSIGNED depth, UNSIGNED cm, DATASET(cache) pycache=DATASET([], cache)) := + EMBED(Python: globalscope(globalScope), persist('query')) + from because.causality import cdisc + assert 'CMDict' in globals(), 'cModel.pyDiscModel: CMDict is not initialized.' + assert cm in CMDict, 'cModel.pyDiscModel: invalid cModel id = ' + str(cm) + CM = CMDict[cm] + #assert False, 'disc: vars, pwr, sens, depth = ' + str(vars) + ',' + str(pwr) + ',' + str(sensitivity) + ',' + str(depth) + #assert False, 'pwr, sensitivity, depth = ' + repr(pwr) + ', ' + repr(sensitivity) + ', ' + repr(depth) + try: + dirCache = {} + for rec in pycache: + dirC = rec[1] + for item in dirC: + key, val = item + cacheKey = tuple(key) + dirCache[cacheKey] = val + if dirCache: + CM.setDirCache(dirCache) + ps = CM.prob # Get the probspace instance from CM + #assert False, 'ps.N = ' + str(ps.N) + if not vars: + vars = ps.getVarNames() + newCM = cdisc.discover(ps, vars, maxLevel=depth, power=pwr, sensitivity=sensitivity) + edges = newCM.getEdges() + edgeNodes = {} + for edge in edges: + cause, effect = edge + edgeNodes[cause] = True + edgeNodes[effect] = True + strength = newCM.getEdgeProp(edge, 'dir_rho') + corr = ps.corrCoef(cause, effect) + MDE = 0.0; + yield (cause, effect, float(strength), float(corr), float(MDE)) + # If any variable was not in an edge, add a pseudo-edge, so + # that it shows in the graph. + for var in vars: + edgeVar = edgeNodes.get(var, None) + if edgeVar is None: + # Not in any edge + yield(var, '', 0.0, 0.0, 0.0) + except: + from because.hpcc_utils import format_exc + assert False, format_exc.format('cModel.pyDiscModel') + + ENDEMBED; // pyDiscModel + /** - * Function to execute a causal scan (discovery) on a single node. + * Function to execute a causal scan on a single node. * * The cache parameter allows much of the heavy lifting to be done in parallel * using getCache (above). There is still quite a bit of work that is done on a single * node and cannot be distributed. * Uses pyDiscoverModel above to communicate with the python package. */ - EXPORT DiscoveryReport DiscoverModel(UNSIGNED pwr, UNSIGNED cm) := FUNCTION - cache := getCache(CM, pwr:=pwr); - rpt := pyDiscoverModel(pwr, cm, cache); + EXPORT ScanReport ScanModel(UNSIGNED pwr, UNSIGNED cm) := FUNCTION + vars := []; + cache := getCache(vars, CM, pwr:=pwr); + rpt := pyScanModel(pwr, cm, cache); RETURN rpt; END; + + /** + * Function to execute a discovery on a single node. + * + * The cache parameter allows much of the heavy lifting to be done in parallel + * using getCache (above). There is still quite a bit of work that is done on a single + * node and cannot be distributed. + * Uses pyDiscoverModel above to communicate with the python package. + */ + EXPORT DATASET(DiscResult) DiscoverModel(SET OF STRING vars, REAL pwr, REAL sensitivity, UNSIGNED depth, UNSIGNED cm) := FUNCTION + //cache := getCache(vars, cm, pwr:=pwr); + rslt := pyDiscModel(vars, pwr, sensitivity, depth, cm); + RETURN rslt; + END; END; \ No newline at end of file diff --git a/resources/esbuild.serve.js b/resources/esbuild.serve.js new file mode 100644 index 0000000..f6b233e --- /dev/null +++ b/resources/esbuild.serve.js @@ -0,0 +1,16 @@ +import * as esbuild from 'esbuild' + +let ctx = await esbuild.context({ + entryPoints: ['src/index.ts'], + bundle: true, + outdir: 'res', +}) + +await ctx.watch() + +let { host, port } = await ctx.serve({ + servedir: 'res', + +}) + +console.log(host, port); \ No newline at end of file diff --git a/resources/package-lock.json b/resources/package-lock.json new file mode 100644 index 0000000..24c78eb --- /dev/null +++ b/resources/package-lock.json @@ -0,0 +1,3870 @@ +{ + "name": "hpcc_causality", + "version": "0.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "hpcc_causality", + "version": "0.0.0", + "license": "Apache-2.0", + "dependencies": { + "@hpcc-js/comms": "2.82.1", + "@hpcc-js/observablehq-compiler": "1.2.5", + "@hpcc-js/util": "2.50.2", + "@observablehq/runtime": "5.5.1" + }, + "devDependencies": { + "esbuild": "0.17.11", + "npm-run-all": "4.1.5", + "rimraf": "4.4.0", + "tslib": "2.5.0", + "typescript": "4.9.5" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.11.tgz", + "integrity": "sha512-CdyX6sRVh1NzFCsf5vw3kULwlAhfy9wVt8SZlrhQ7eL2qBjGbFhRBWkkAzuZm9IIEOCKJw4DXA6R85g+qc8RDw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.11.tgz", + "integrity": "sha512-QnK4d/zhVTuV4/pRM4HUjcsbl43POALU2zvBynmrrqZt9LPcLA3x1fTZPBg2RRguBQnJcnU059yKr+bydkntjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.11.tgz", + "integrity": "sha512-3PL3HKtsDIXGQcSCKtWD/dy+mgc4p2Tvo2qKgKHj9Yf+eniwFnuoQ0OUhlSfAEpKAFzF9N21Nwgnap6zy3L3MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.11.tgz", + "integrity": "sha512-pJ950bNKgzhkGNO3Z9TeHzIFtEyC2GDQL3wxkMApDEghYx5Qers84UTNc1bAxWbRkuJOgmOha5V0WUeh8G+YGw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.11.tgz", + "integrity": "sha512-iB0dQkIHXyczK3BZtzw1tqegf0F0Ab5texX2TvMQjiJIWXAfM4FQl7D909YfXWnB92OQz4ivBYQ2RlxBJrMJOw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.11.tgz", + "integrity": "sha512-7EFzUADmI1jCHeDRGKgbnF5sDIceZsQGapoO6dmw7r/ZBEKX7CCDnIz8m9yEclzr7mFsd+DyasHzpjfJnmBB1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.11.tgz", + "integrity": "sha512-iPgenptC8i8pdvkHQvXJFzc1eVMR7W2lBPrTE6GbhR54sLcF42mk3zBOjKPOodezzuAz/KSu8CPyFSjcBMkE9g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.11.tgz", + "integrity": "sha512-M9iK/d4lgZH0U5M1R2p2gqhPV/7JPJcRz+8O8GBKVgqndTzydQ7B2XGDbxtbvFkvIs53uXTobOhv+RyaqhUiMg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.11.tgz", + "integrity": "sha512-Qxth3gsWWGKz2/qG2d5DsW/57SeA2AmpSMhdg9TSB5Svn2KDob3qxfQSkdnWjSd42kqoxIPy3EJFs+6w1+6Qjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.11.tgz", + "integrity": "sha512-dB1nGaVWtUlb/rRDHmuDQhfqazWE0LMro/AIbT2lWM3CDMHJNpLckH+gCddQyhhcLac2OYw69ikUMO34JLt3wA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.11.tgz", + "integrity": "sha512-aCWlq70Q7Nc9WDnormntGS1ar6ZFvUpqr8gXtO+HRejRYPweAFQN615PcgaSJkZjhHp61+MNLhzyVALSF2/Q0g==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.11.tgz", + "integrity": "sha512-cGeGNdQxqY8qJwlYH1BP6rjIIiEcrM05H7k3tR7WxOLmD1ZxRMd6/QIOWMb8mD2s2YJFNRuNQ+wjMhgEL2oCEw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.11.tgz", + "integrity": "sha512-BdlziJQPW/bNe0E8eYsHB40mYOluS+jULPCjlWiHzDgr+ZBRXPtgMV1nkLEGdpjrwgmtkZHEGEPaKdS/8faLDA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.11.tgz", + "integrity": "sha512-MDLwQbtF+83oJCI1Cixn68Et/ME6gelmhssPebC40RdJaect+IM+l7o/CuG0ZlDs6tZTEIoxUe53H3GmMn8oMA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.11.tgz", + "integrity": "sha512-4N5EMESvws0Ozr2J94VoUD8HIRi7X0uvUv4c0wpTHZyZY9qpaaN7THjosdiW56irQ4qnJ6Lsc+i+5zGWnyqWqQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.11.tgz", + "integrity": "sha512-rM/v8UlluxpytFSmVdbCe1yyKQd/e+FmIJE2oPJvbBo+D0XVWi1y/NQ4iTNx+436WmDHQBjVLrbnAQLQ6U7wlw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.11.tgz", + "integrity": "sha512-4WaAhuz5f91h3/g43VBGdto1Q+X7VEZfpcWGtOFXnggEuLvjV+cP6DyLRU15IjiU9fKLLk41OoJfBFN5DhPvag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.11.tgz", + "integrity": "sha512-UBj135Nx4FpnvtE+C8TWGp98oUgBcmNmdYgl5ToKc0mBHxVVqVE7FUS5/ELMImOp205qDAittL6Ezhasc2Ev/w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.11.tgz", + "integrity": "sha512-1/gxTifDC9aXbV2xOfCbOceh5AlIidUrPsMpivgzo8P8zUtczlq1ncFpeN1ZyQJ9lVs2hILy1PG5KPp+w8QPPg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.11.tgz", + "integrity": "sha512-vtSfyx5yRdpiOW9yp6Ax0zyNOv9HjOAw8WaZg3dF5djEHKKm3UnoohftVvIJtRh0Ec7Hso0RIdTqZvPXJ7FdvQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.11.tgz", + "integrity": "sha512-GFPSLEGQr4wHFTiIUJQrnJKZhZjjq4Sphf+mM76nQR6WkQn73vm7IsacmBRPkALfpOCHsopSvLgqdd4iUW2mYw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.11.tgz", + "integrity": "sha512-N9vXqLP3eRL8BqSy8yn4Y98cZI2pZ8fyuHx6lKjiG2WABpT2l01TXdzq5Ma2ZUBzfB7tx5dXVhge8X9u0S70ZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@hpcc-js/comms": { + "version": "2.82.1", + "resolved": "https://registry.npmjs.org/@hpcc-js/comms/-/comms-2.82.1.tgz", + "integrity": "sha512-4Hko5lyQIizwFa/aQDRUmDkWntCJOpX1ARzwA9Fq7yxAzcJ9Q0HhRifJhfSFoy0xhmZA6pSJm4C9PeLUaWfoHQ==", + "dependencies": { + "@hpcc-js/ddl-shim": "^2.20.2", + "@hpcc-js/util": "^2.50.2", + "@xmldom/xmldom": "0.8.6", + "abort-controller": "3.0.0", + "node-fetch": "2.6.7", + "safe-buffer": "5.2.1", + "tmp": "0.2.1" + } + }, + "node_modules/@hpcc-js/comms/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@hpcc-js/ddl-shim": { + "version": "2.20.2", + "resolved": "https://registry.npmjs.org/@hpcc-js/ddl-shim/-/ddl-shim-2.20.2.tgz", + "integrity": "sha512-fCIQVHLOi5FidWfQO+Kr0HklhEZ/M0E/BjGTHUcZR5Hr2iU4aHv15acyxed0u+jIJf9UofzbxkA0UkMTvPY0HA==", + "hasInstallScript": true, + "dependencies": { + "ajv": "6.12.6" + }, + "bin": { + "ddl-shim": "dist/cli.js" + } + }, + "node_modules/@hpcc-js/observable-shim": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@hpcc-js/observable-shim/-/observable-shim-2.5.0.tgz", + "integrity": "sha512-wHOkxxLFQxOUo0g/ewpfNUTKx3/EoAdSLsOUB2ueTdeGnM2yoKXbBoZ18zQb3AEKV4okqQE/Cay60aWRKMnxDQ==" + }, + "node_modules/@hpcc-js/observablehq-compiler": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@hpcc-js/observablehq-compiler/-/observablehq-compiler-1.2.5.tgz", + "integrity": "sha512-FC2OwsGM4KmmtPC0BSw6uS9fS8jzyWv/uZvabZ3Bsp/pVujttoRfFgsCD4YiK9KUGGew2GSRTEpWrsGDD6aUHQ==", + "dependencies": { + "@hpcc-js/observable-shim": "^2.5.0", + "node-fetch": "3.3.0", + "yargs": "17.6.2" + }, + "bin": { + "ojscc": "bin/ojscc.mjs" + } + }, + "node_modules/@hpcc-js/util": { + "version": "2.50.2", + "resolved": "https://registry.npmjs.org/@hpcc-js/util/-/util-2.50.2.tgz", + "integrity": "sha512-dTs3AVuCT7DatC2X76ljOXG+WMSWJgd3RM97HKuzNNL7ubzyWoSxSqzNjGL0ClDMV1UlNXdH7oDyubwoRxZEQQ==", + "dependencies": { + "tslib": "2.4.1" + } + }, + "node_modules/@hpcc-js/util/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/@observablehq/inspector": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@observablehq/inspector/-/inspector-5.0.0.tgz", + "integrity": "sha512-Vvg/TQdsZTUaeYbH0IKxYEz37FbRO6kdowoz2PrHLQif54NC1CjEihEjg+ZMSBn587GQxTFABu0CGkFZgtR1UQ==", + "dependencies": { + "isoformat": "^0.2.0" + } + }, + "node_modules/@observablehq/runtime": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@observablehq/runtime/-/runtime-5.5.1.tgz", + "integrity": "sha512-o7af1MhoR+NwZVmMJFiHOfACfedGEUF9bMg43n3jPUFJ5vDoEoLL6WoaoQcmM4yEc8XZGrZWBOeW6G2TFlC8Jw==", + "dependencies": { + "@observablehq/inspector": "^5.0.0", + "@observablehq/stdlib": "^5.0.0" + } + }, + "node_modules/@observablehq/stdlib": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@observablehq/stdlib/-/stdlib-5.5.1.tgz", + "integrity": "sha512-LvhgDsxXc00ReTCMKnAyUPfO3JEprqMbh4NMJ7Zs7S+hDmQhqoZ1MY4WLWzXlGpUvdODAfrZ4UrmKg63Wf2SHA==", + "dependencies": { + "d3-array": "^3.2.0", + "d3-dsv": "^3.0.1", + "d3-require": "^1.3.0" + }, + "engines": { + "node": ">=14.5.0" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.6.tgz", + "integrity": "sha512-uRjjusqpoqfmRkTaNuLJ2VohVr67Q5YwDATW3VU7PfzTj6IRaihGrYI7zckGZjxQPBIp63nfvJbM+Yu5ICh0Bg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-yEEyEAbDrF8C6Ob2myOBLjwBLck1Z89jMGFee0oPsn95GqjerpaOA4ch+vc2l0FNFFwMD5N7OCSEN5eAlsUbgQ==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-require": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/d3-require/-/d3-require-1.3.0.tgz", + "integrity": "sha512-XaNc2azaAwXhGjmCMtxlD+AowpMfLimVsAoTMpqrvb8CWoA4QqyV12mc4Ue6KSoDvfuS831tsumfhDYxGd4FGA==" + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "dev": true, + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.21.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", + "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.0", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/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, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.11.tgz", + "integrity": "sha512-pAMImyokbWDtnA/ufPxjQg0fYo2DDuzAlqwnDvbXqHLphe+m80eF++perYKVm8LeTuj2zUuFXC+xgSVxyoHUdg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.11", + "@esbuild/android-arm64": "0.17.11", + "@esbuild/android-x64": "0.17.11", + "@esbuild/darwin-arm64": "0.17.11", + "@esbuild/darwin-x64": "0.17.11", + "@esbuild/freebsd-arm64": "0.17.11", + "@esbuild/freebsd-x64": "0.17.11", + "@esbuild/linux-arm": "0.17.11", + "@esbuild/linux-arm64": "0.17.11", + "@esbuild/linux-ia32": "0.17.11", + "@esbuild/linux-loong64": "0.17.11", + "@esbuild/linux-mips64el": "0.17.11", + "@esbuild/linux-ppc64": "0.17.11", + "@esbuild/linux-riscv64": "0.17.11", + "@esbuild/linux-s390x": "0.17.11", + "@esbuild/linux-x64": "0.17.11", + "@esbuild/netbsd-x64": "0.17.11", + "@esbuild/openbsd-x64": "0.17.11", + "@esbuild/sunos-x64": "0.17.11", + "@esbuild/win32-arm64": "0.17.11", + "@esbuild/win32-ia32": "0.17.11", + "@esbuild/win32-x64": "0.17.11" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/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==" + }, + "node_modules/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==" + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.0.tgz", + "integrity": "sha512-EAZejC7JvnQINayvB/7BJbpZpNOJ8Lrw2OZNEvQxe0vaLn1SuwMcfV7/MNaX8L/T0wmptBFI4YMtDvSBxYDc7w==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^7.4.1", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.2.tgz", + "integrity": "sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isoformat": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/isoformat/-/isoformat-0.2.1.tgz", + "integrity": "sha512-tFLRAygk9NqrRPhJSnNGh7g7oaVWDwR0wKh/GM2LgmPa50Eg4UfyaCO4I8k6EqJHl1/uh2RAD6g06n5ygEnrjQ==" + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/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==" + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz", + "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.0.tgz", + "integrity": "sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.1.tgz", + "integrity": "sha512-OW+5s+7cw6253Q4E+8qQ/u1fVvcJQCJo/VFD8pje+dbJCF1n5ZRMV2AEHbGp+5Q7jxQIYJxkHopnj6nzdGeZLA==", + "dev": true, + "dependencies": { + "lru-cache": "^7.14.1", + "minipass": "^4.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/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, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rimraf": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.0.tgz", + "integrity": "sha512-X36S+qpCUR0HjXlkDe4NAOhS//aHH0Z+h8Ckf2auGJk3PTnx5rLmrHkwNdbVQuCSUhOyFrlRvFEllZOYE+yZGQ==", + "dev": true, + "dependencies": { + "glob": "^9.2.0" + }, + "bin": { + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-quote": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.0.tgz", + "integrity": "sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", + "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", + "dev": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.padend": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.4.tgz", + "integrity": "sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/tmp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tmp/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", + "dev": true + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + } + }, + "dependencies": { + "@esbuild/android-arm": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.11.tgz", + "integrity": "sha512-CdyX6sRVh1NzFCsf5vw3kULwlAhfy9wVt8SZlrhQ7eL2qBjGbFhRBWkkAzuZm9IIEOCKJw4DXA6R85g+qc8RDw==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.11.tgz", + "integrity": "sha512-QnK4d/zhVTuV4/pRM4HUjcsbl43POALU2zvBynmrrqZt9LPcLA3x1fTZPBg2RRguBQnJcnU059yKr+bydkntjg==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.11.tgz", + "integrity": "sha512-3PL3HKtsDIXGQcSCKtWD/dy+mgc4p2Tvo2qKgKHj9Yf+eniwFnuoQ0OUhlSfAEpKAFzF9N21Nwgnap6zy3L3MQ==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.11.tgz", + "integrity": "sha512-pJ950bNKgzhkGNO3Z9TeHzIFtEyC2GDQL3wxkMApDEghYx5Qers84UTNc1bAxWbRkuJOgmOha5V0WUeh8G+YGw==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.11.tgz", + "integrity": "sha512-iB0dQkIHXyczK3BZtzw1tqegf0F0Ab5texX2TvMQjiJIWXAfM4FQl7D909YfXWnB92OQz4ivBYQ2RlxBJrMJOw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.11.tgz", + "integrity": "sha512-7EFzUADmI1jCHeDRGKgbnF5sDIceZsQGapoO6dmw7r/ZBEKX7CCDnIz8m9yEclzr7mFsd+DyasHzpjfJnmBB1Q==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.11.tgz", + "integrity": "sha512-iPgenptC8i8pdvkHQvXJFzc1eVMR7W2lBPrTE6GbhR54sLcF42mk3zBOjKPOodezzuAz/KSu8CPyFSjcBMkE9g==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.11.tgz", + "integrity": "sha512-M9iK/d4lgZH0U5M1R2p2gqhPV/7JPJcRz+8O8GBKVgqndTzydQ7B2XGDbxtbvFkvIs53uXTobOhv+RyaqhUiMg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.11.tgz", + "integrity": "sha512-Qxth3gsWWGKz2/qG2d5DsW/57SeA2AmpSMhdg9TSB5Svn2KDob3qxfQSkdnWjSd42kqoxIPy3EJFs+6w1+6Qjg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.11.tgz", + "integrity": "sha512-dB1nGaVWtUlb/rRDHmuDQhfqazWE0LMro/AIbT2lWM3CDMHJNpLckH+gCddQyhhcLac2OYw69ikUMO34JLt3wA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.11.tgz", + "integrity": "sha512-aCWlq70Q7Nc9WDnormntGS1ar6ZFvUpqr8gXtO+HRejRYPweAFQN615PcgaSJkZjhHp61+MNLhzyVALSF2/Q0g==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.11.tgz", + "integrity": "sha512-cGeGNdQxqY8qJwlYH1BP6rjIIiEcrM05H7k3tR7WxOLmD1ZxRMd6/QIOWMb8mD2s2YJFNRuNQ+wjMhgEL2oCEw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.11.tgz", + "integrity": "sha512-BdlziJQPW/bNe0E8eYsHB40mYOluS+jULPCjlWiHzDgr+ZBRXPtgMV1nkLEGdpjrwgmtkZHEGEPaKdS/8faLDA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.11.tgz", + "integrity": "sha512-MDLwQbtF+83oJCI1Cixn68Et/ME6gelmhssPebC40RdJaect+IM+l7o/CuG0ZlDs6tZTEIoxUe53H3GmMn8oMA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.11.tgz", + "integrity": "sha512-4N5EMESvws0Ozr2J94VoUD8HIRi7X0uvUv4c0wpTHZyZY9qpaaN7THjosdiW56irQ4qnJ6Lsc+i+5zGWnyqWqQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.11.tgz", + "integrity": "sha512-rM/v8UlluxpytFSmVdbCe1yyKQd/e+FmIJE2oPJvbBo+D0XVWi1y/NQ4iTNx+436WmDHQBjVLrbnAQLQ6U7wlw==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.11.tgz", + "integrity": "sha512-4WaAhuz5f91h3/g43VBGdto1Q+X7VEZfpcWGtOFXnggEuLvjV+cP6DyLRU15IjiU9fKLLk41OoJfBFN5DhPvag==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.11.tgz", + "integrity": "sha512-UBj135Nx4FpnvtE+C8TWGp98oUgBcmNmdYgl5ToKc0mBHxVVqVE7FUS5/ELMImOp205qDAittL6Ezhasc2Ev/w==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.11.tgz", + "integrity": "sha512-1/gxTifDC9aXbV2xOfCbOceh5AlIidUrPsMpivgzo8P8zUtczlq1ncFpeN1ZyQJ9lVs2hILy1PG5KPp+w8QPPg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.11.tgz", + "integrity": "sha512-vtSfyx5yRdpiOW9yp6Ax0zyNOv9HjOAw8WaZg3dF5djEHKKm3UnoohftVvIJtRh0Ec7Hso0RIdTqZvPXJ7FdvQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.11.tgz", + "integrity": "sha512-GFPSLEGQr4wHFTiIUJQrnJKZhZjjq4Sphf+mM76nQR6WkQn73vm7IsacmBRPkALfpOCHsopSvLgqdd4iUW2mYw==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.11.tgz", + "integrity": "sha512-N9vXqLP3eRL8BqSy8yn4Y98cZI2pZ8fyuHx6lKjiG2WABpT2l01TXdzq5Ma2ZUBzfB7tx5dXVhge8X9u0S70ZQ==", + "dev": true, + "optional": true + }, + "@hpcc-js/comms": { + "version": "2.82.1", + "resolved": "https://registry.npmjs.org/@hpcc-js/comms/-/comms-2.82.1.tgz", + "integrity": "sha512-4Hko5lyQIizwFa/aQDRUmDkWntCJOpX1ARzwA9Fq7yxAzcJ9Q0HhRifJhfSFoy0xhmZA6pSJm4C9PeLUaWfoHQ==", + "requires": { + "@hpcc-js/ddl-shim": "^2.20.2", + "@hpcc-js/util": "^2.50.2", + "@xmldom/xmldom": "0.8.6", + "abort-controller": "3.0.0", + "node-fetch": "2.6.7", + "safe-buffer": "5.2.1", + "tmp": "0.2.1" + }, + "dependencies": { + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + } + } + }, + "@hpcc-js/ddl-shim": { + "version": "2.20.2", + "resolved": "https://registry.npmjs.org/@hpcc-js/ddl-shim/-/ddl-shim-2.20.2.tgz", + "integrity": "sha512-fCIQVHLOi5FidWfQO+Kr0HklhEZ/M0E/BjGTHUcZR5Hr2iU4aHv15acyxed0u+jIJf9UofzbxkA0UkMTvPY0HA==", + "requires": { + "ajv": "6.12.6" + } + }, + "@hpcc-js/observable-shim": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@hpcc-js/observable-shim/-/observable-shim-2.5.0.tgz", + "integrity": "sha512-wHOkxxLFQxOUo0g/ewpfNUTKx3/EoAdSLsOUB2ueTdeGnM2yoKXbBoZ18zQb3AEKV4okqQE/Cay60aWRKMnxDQ==" + }, + "@hpcc-js/observablehq-compiler": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@hpcc-js/observablehq-compiler/-/observablehq-compiler-1.2.5.tgz", + "integrity": "sha512-FC2OwsGM4KmmtPC0BSw6uS9fS8jzyWv/uZvabZ3Bsp/pVujttoRfFgsCD4YiK9KUGGew2GSRTEpWrsGDD6aUHQ==", + "requires": { + "@hpcc-js/observable-shim": "^2.5.0", + "node-fetch": "3.3.0", + "yargs": "17.6.2" + } + }, + "@hpcc-js/util": { + "version": "2.50.2", + "resolved": "https://registry.npmjs.org/@hpcc-js/util/-/util-2.50.2.tgz", + "integrity": "sha512-dTs3AVuCT7DatC2X76ljOXG+WMSWJgd3RM97HKuzNNL7ubzyWoSxSqzNjGL0ClDMV1UlNXdH7oDyubwoRxZEQQ==", + "requires": { + "tslib": "2.4.1" + }, + "dependencies": { + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, + "@observablehq/inspector": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@observablehq/inspector/-/inspector-5.0.0.tgz", + "integrity": "sha512-Vvg/TQdsZTUaeYbH0IKxYEz37FbRO6kdowoz2PrHLQif54NC1CjEihEjg+ZMSBn587GQxTFABu0CGkFZgtR1UQ==", + "requires": { + "isoformat": "^0.2.0" + } + }, + "@observablehq/runtime": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@observablehq/runtime/-/runtime-5.5.1.tgz", + "integrity": "sha512-o7af1MhoR+NwZVmMJFiHOfACfedGEUF9bMg43n3jPUFJ5vDoEoLL6WoaoQcmM4yEc8XZGrZWBOeW6G2TFlC8Jw==", + "requires": { + "@observablehq/inspector": "^5.0.0", + "@observablehq/stdlib": "^5.0.0" + } + }, + "@observablehq/stdlib": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@observablehq/stdlib/-/stdlib-5.5.1.tgz", + "integrity": "sha512-LvhgDsxXc00ReTCMKnAyUPfO3JEprqMbh4NMJ7Zs7S+hDmQhqoZ1MY4WLWzXlGpUvdODAfrZ4UrmKg63Wf2SHA==", + "requires": { + "d3-array": "^3.2.0", + "d3-dsv": "^3.0.1", + "d3-require": "^1.3.0" + } + }, + "@xmldom/xmldom": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.6.tgz", + "integrity": "sha512-uRjjusqpoqfmRkTaNuLJ2VohVr67Q5YwDATW3VU7PfzTj6IRaihGrYI7zckGZjxQPBIp63nfvJbM+Yu5ICh0Bg==" + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + } + }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "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" + } + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-yEEyEAbDrF8C6Ob2myOBLjwBLck1Z89jMGFee0oPsn95GqjerpaOA4ch+vc2l0FNFFwMD5N7OCSEN5eAlsUbgQ==", + "requires": { + "internmap": "1 - 2" + } + }, + "d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "requires": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + } + }, + "d3-require": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/d3-require/-/d3-require-1.3.0.tgz", + "integrity": "sha512-XaNc2azaAwXhGjmCMtxlD+AowpMfLimVsAoTMpqrvb8CWoA4QqyV12mc4Ue6KSoDvfuS831tsumfhDYxGd4FGA==" + }, + "data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==" + }, + "define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "dev": true, + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.21.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", + "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.0", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.0", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" + } + }, + "es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + } + }, + "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" + } + }, + "esbuild": { + "version": "0.17.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.11.tgz", + "integrity": "sha512-pAMImyokbWDtnA/ufPxjQg0fYo2DDuzAlqwnDvbXqHLphe+m80eF++perYKVm8LeTuj2zUuFXC+xgSVxyoHUdg==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.17.11", + "@esbuild/android-arm64": "0.17.11", + "@esbuild/android-x64": "0.17.11", + "@esbuild/darwin-arm64": "0.17.11", + "@esbuild/darwin-x64": "0.17.11", + "@esbuild/freebsd-arm64": "0.17.11", + "@esbuild/freebsd-x64": "0.17.11", + "@esbuild/linux-arm": "0.17.11", + "@esbuild/linux-arm64": "0.17.11", + "@esbuild/linux-ia32": "0.17.11", + "@esbuild/linux-loong64": "0.17.11", + "@esbuild/linux-mips64el": "0.17.11", + "@esbuild/linux-ppc64": "0.17.11", + "@esbuild/linux-riscv64": "0.17.11", + "@esbuild/linux-s390x": "0.17.11", + "@esbuild/linux-x64": "0.17.11", + "@esbuild/netbsd-x64": "0.17.11", + "@esbuild/openbsd-x64": "0.17.11", + "@esbuild/sunos-x64": "0.17.11", + "@esbuild/win32-arm64": "0.17.11", + "@esbuild/win32-ia32": "0.17.11", + "@esbuild/win32-x64": "0.17.11" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "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==" + }, + "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==" + }, + "fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "requires": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + } + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "requires": { + "fetch-blob": "^3.1.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-intrinsic": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "glob": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.0.tgz", + "integrity": "sha512-EAZejC7JvnQINayvB/7BJbpZpNOJ8Lrw2OZNEvQxe0vaLn1SuwMcfV7/MNaX8L/T0wmptBFI4YMtDvSBxYDc7w==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "minimatch": "^7.4.1", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.2.tgz", + "integrity": "sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3" + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "iconv-lite": { + "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" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==" + }, + "is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-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==" + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "isoformat": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/isoformat/-/isoformat-0.2.1.tgz", + "integrity": "sha512-tFLRAygk9NqrRPhJSnNGh7g7oaVWDwR0wKh/GM2LgmPa50Eg4UfyaCO4I8k6EqJHl1/uh2RAD6g06n5ygEnrjQ==" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "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==" + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minipass": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz", + "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" + }, + "node-fetch": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.0.tgz", + "integrity": "sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==", + "requires": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + } + }, + "object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-scurry": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.1.tgz", + "integrity": "sha512-OW+5s+7cw6253Q4E+8qQ/u1fVvcJQCJo/VFD8pje+dbJCF1n5ZRMV2AEHbGp+5Q7jxQIYJxkHopnj6nzdGeZLA==", + "dev": true, + "requires": { + "lru-cache": "^7.14.1", + "minipass": "^4.0.2" + } + }, + "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" + } + }, + "pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true + }, + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "rimraf": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.0.tgz", + "integrity": "sha512-X36S+qpCUR0HjXlkDe4NAOhS//aHH0Z+h8Ckf2auGJk3PTnx5rLmrHkwNdbVQuCSUhOyFrlRvFEllZOYE+yZGQ==", + "dev": true, + "requires": { + "glob": "^9.2.0" + } + }, + "rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, + "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==" + }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true + }, + "shell-quote": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.0.tgz", + "integrity": "sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ==", + "dev": true + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", + "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string.prototype.padend": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.4.tgz", + "integrity": "sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "requires": { + "rimraf": "^3.0.0" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", + "dev": true + }, + "typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + } + }, + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "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==", + "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==", + "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==" + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + } + } +} diff --git a/resources/package.json b/resources/package.json new file mode 100644 index 0000000..29579f0 --- /dev/null +++ b/resources/package.json @@ -0,0 +1,42 @@ +{ + "name": "hpcc_causality", + "private": true, + "version": "0.0.0", + "description": "", + "type": "module", + "main": "dist/index.js", + "scripts": { + "clean": "rimraf lib* types dist res/*.js res/*.map", + "esbuild": "esbuild ./src/index.ts --bundle --sourcemap --format=esm --outdir=./res", + "build": "npm run esbuild -- --minify", + "serve": "npm run esbuild -- --watch --serve --servedir=.", + "link-hpcc-js": "mklink /J hpcc-js ..\\hpcc-js", + "lint": "tslint --project . src/**/*.ts", + "docs": "typedoc --options tdoptions.json .", + "update": "npx npm-check-updates -u -t minor", + "update-major": "npx npm-check-updates -u" + }, + "dependencies": { + "@hpcc-js/comms": "2.82.1", + "@hpcc-js/observablehq-compiler": "1.2.5", + "@hpcc-js/util": "2.50.2", + "@observablehq/runtime": "5.5.1" + }, + "devDependencies": { + "esbuild": "0.17.11", + "npm-run-all": "4.1.5", + "rimraf": "4.4.0", + "tslib": "2.5.0", + "typescript": "4.9.5" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/hpcc-systems/DataPatterns.git" + }, + "author": "", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/hpcc-systems/DataPatterns/issues" + }, + "homepage": "https://github.com/hpcc-systems/DataPatterns" +} \ No newline at end of file diff --git a/resources/res/index.css b/resources/res/index.css new file mode 100644 index 0000000..019e0d6 --- /dev/null +++ b/resources/res/index.css @@ -0,0 +1,2 @@ +@import"https://fonts.googleapis.com/css2?family=Source+Serif+Pro:ital,wght@0,400;0,600;0,700;1,400;1,600;1,700&display=swap";:root{--syntax-normal:#1b1e23;--syntax-comment:#828282;--syntax-number:#20a5ba;--syntax-keyword:#c30771;--syntax-atom:#10a778;--syntax-string:#008ec4;--syntax-error:#ffbedc;--syntax-unknown-variable:#838383;--syntax-known-variable:#005f87;--syntax-matchbracket:#20bbfc;--syntax-key:#6636b4;--mono-fonts:82%/1.5 Menlo,Consolas,monospace}.observablehq--collapsed,.observablehq--expanded,.observablehq--function,.observablehq--gray,.observablehq--import,.observablehq--string:after,.observablehq--string:before{color:var(--syntax-normal)}.observablehq--collapsed,.observablehq--expanded.observablehq--inspect a{cursor:pointer}.observablehq--field{margin-left:1em;text-indent:-1em}.observablehq--empty{color:var(--syntax_comment)}.observablehq--blue,.observablehq--keyword,a[href]{color:#3182bd}.hljs-deletion,.hljs-variable,.observablehq--forbidden,.observablehq--pink{color:#e377c2}.observablehq--orange{color:#e6550d}.hljs-literal,.observablehq--boolean,.observablehq--null,.observablehq--undefined{color:var(--syntax-atom)}.hljs-bullet,.hljs-link,.hljs-number,.hljs-regexp,.observablehq--bigint,.observablehq--date,.observablehq--green,.observablehq--number,.observablehq--regexp,.observablehq--symbol{color:var(--syntax-number)}.observablehq--index,.observablehq--key{color:var(--syntax-key)}.observablehq--prototype-key{color:#aaa}.observablehq--empty{font-style:oblique}.hljs-addition,.hljs-meta,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable,.observablehq--purple,.observablehq--string{color:var(--syntax-string)}.observablehq--error,.observablehq--red{color:#e7040f}.observablehq--inspect,.observablehq:empty:after,.observablehq>link:only-child,.observablehq>style:only-child{display:block;font:var(--monospace-font);overflow-x:auto;padding:4px 0;white-space:pre}.observablehq--error .observablehq--inspect{white-space:pre-wrap;word-break:break-all}:root{--syntax-diff:#24292e;--syntax-diff-bg:#fff;--hr:rgba(0,0,0,.05);--monospace:Menlo,Consolas,monospace;--monospace-font:14px/1.5 var(--monospace);--serif:"Source Serif Pro","Iowan Old Style","Apple Garamond","Palatino Linotype","Times New Roman","Droid Serif",Times,serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--sans-serif:-apple-system,BlinkMacSystemFont,"avenir next",avenir,helvetica,"helvetica neue",ubuntu,roboto,noto,"segoe ui",arial,sans-serif}html{-webkit-text-size-adjust:100%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#1b1e23;font:17px/1.5 var(--serif)}body{margin:0 14px}body.fullscreen{margin:0}h1,h2,h3,h4,h5,h6{color:#333;font-weight:700;line-height:1.15;margin-bottom:.25rem;margin-top:0}h2~p,h2~table,h3~p,h3~table,h4~p,h4~table{margin-top:0}.observablehq:first-of-type h1+h2{font-size:20px;font-style:italic;font-weight:400;margin-bottom:1rem}a[href]{text-decoration:none}a[href]:hover{text-decoration:underline}h1 code,h2 code,h3 code,h4 code,h5 code,h6 code{font-size:90%}code,pre,tt{font-family:var(--monospace);font-size:14px;line-height:1.5}img{max-width:calc(100vw - 28px)}.katex-display,figcaption,figure,h1,h2,h3,h4,h5,h6,p,table{max-width:640px}blockquote,ol,ul{max-width:600px}blockquote{margin:1rem 1.5rem}ol,ul{padding-left:28px}hr{background:no-repeat 50%/100% 1px linear-gradient(to right,var(--hr),var(--hr));border:none;height:1px;margin:1rem 0;padding:1rem 0}pre{padding:2px 0}.observablehq--md-pre{overflow-x:auto}input:not([type]),input[type=email],input[type=number],input[type=password],input[type=range],input[type=search],input[type=tel],input[type=text],input[type=url]{width:240px}button,canvas,input{vertical-align:middle}button,input,textarea{accent-color:#3b5fc0}table{border-collapse:collapse;font:13px/1.2 var(--sans-serif);width:100%}table code,table pre,table tt{font-size:inherit;line-height:inherit}td>pre:only-child,th>pre:only-child{margin:0;padding:0}th{color:#111;text-align:left;vertical-align:bottom}td{color:#444;vertical-align:top}td,th{padding:3px 6.5px 3px 0}td:last-child,th:last-child{padding-right:0}tr:not(:last-child){border-bottom:1px solid #eee}thead tr{border-bottom:1px solid #ccc}figure,table{margin:1rem 0}figure img{max-width:100%}figcaption{color:var(--syntax-unknown-variable);font:small var(--sans-serif)}.observablehq--caret{margin-right:4px;vertical-align:baseline}.observablehq--field{margin-left:1rem;text-indent:-1rem}.hljs-comment,.observablehq--empty,.observablehq--prototype-key{color:var(--syntax-comment)}.hljs-built_in{color:var(--syntax-known-variable)}.observablehq--unknown{color:var(--syntax-unknown-variable)}.hljs-doctag,.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-tag,.hljs-strong,.hljs-tag,.hljs-type{color:var(--syntax-keyword)}.observablehq{margin:17px 0;min-height:1.5rem;position:relative}.observablehq:before{bottom:1px;content:"";left:-14px;position:absolute;top:0;transition:background-color .25s linear;width:4px}.observablehq--changed:before,.observablehq--running:before{background-color:#a9b0bc;transition:none}.observablehq--error:before{background-color:#e7040f}.observablehq:not(.observablehq--running):empty:after{color:var(--syntax-comment);content:"";font-style:oblique}.observablehq>link:only-child,.observablehq>style:only-child{color:var(--syntax-keyword);visibility:hidden;white-space:nowrap}.observablehq>link:only-child:before{content:"";pointer-events:none;text-decoration:none;visibility:visible}.observablehq>style:only-child:before{content:"