diff --git a/.gitignore b/.gitignore index 6a092bad..4c1a960e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ .gradle -.github .git/ .idea/ build/ @@ -10,4 +9,4 @@ out/ __pycache__/ *.pyc logs -dist/ \ No newline at end of file +dist \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 261eeb9e..00000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/build.gradle b/build.gradle index fd604d96..f419d850 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,9 @@ def defaultEncoding = 'UTF-8' buildscript { repositories { mavenLocal() - mavenCentral() + maven { + url "http://maven.aliyun.com/nexus/content/groups/public/" + } } } @@ -42,9 +44,8 @@ dependencies { repositories { mavenLocal() - mavenCentral() maven { - url "https://repo.spring.io/libs-milestone" + url "http://maven.aliyun.com/nexus/content/groups/public/" } } @@ -54,8 +55,7 @@ applicationDefaultJvmArgs = ['-Xms256M', '-Xmx2G', '-XX:+UseG1GC', '-XX:MaxGCPauseMillis=20', '-XX:InitiatingHeapOccupancyPercent=50', '-Dfile.encoding=UTF-8', "-Djava.library.path=HADOOP_COMMON_LIB_NATIVE_DIR", - "-Dlog.file=${project.name}-MY_USER-MY_HOSTNAME.log", - "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8091"] + "-Dlog.file=${project.name}-MY_USER-MY_HOSTNAME.log"] tasks.startScripts << { def scriptFile = file "${outputDir}/${applicationName}" @@ -109,10 +109,10 @@ subprojects { repositories { mavenLocal() - mavenCentral() maven { - url "https://repo.spring.io/libs-milestone" + url "http://maven.aliyun.com/nexus/content/groups/public/" } +// mavenCentral() } processResources { @@ -128,4 +128,22 @@ subprojects { } } -apply from: "profile.gradle" +configurations.all { + resolutionStrategy { + force 'org.springframework:spring-aop:5.1.15.RELEASE' + force 'org.springframework:spring-aspects:5.1.15.RELEASE' + force 'org.springframework:spring-beans:5.1.15.RELEASE' + force 'org.springframework:spring-context:5.1.15.RELEASE' + force 'org.springframework:spring-core:5.1.15.RELEASE' + force 'org.springframework:spring-expressions:5.1.15.RELEASE' + force 'org.springframework:spring-jcl:5.1.15.RELEASE' + force 'org.springframework:spring-jdbc:5.1.15.RELEASE' + force 'org.springframework:spring-orm:5.1.15.RELEASE' + force 'org.springframework:spring-test:5.1.15.RELEASE' + force 'org.springframework:spring-tx:5.1.15.RELEASE' + force 'org.springframework:spring-web:5.1.15.RELEASE' + force 'org.springframework:spring-webmvc:5.1.15.RELEASE' + } +} + +apply from: "profile.gradle" \ No newline at end of file diff --git a/core/common/src/main/java/com/webank/wedatasphere/qualitis/metadata/client/MetaDataClient.java b/core/common/src/main/java/com/webank/wedatasphere/qualitis/metadata/client/MetaDataClient.java index 7f533a9c..eac43ce6 100644 --- a/core/common/src/main/java/com/webank/wedatasphere/qualitis/metadata/client/MetaDataClient.java +++ b/core/common/src/main/java/com/webank/wedatasphere/qualitis/metadata/client/MetaDataClient.java @@ -17,23 +17,18 @@ package com.webank.wedatasphere.qualitis.metadata.client; +import com.webank.wedatasphere.qualitis.exception.UnExpectedRequestException; import com.webank.wedatasphere.qualitis.metadata.exception.MetaDataAcquireFailedException; import com.webank.wedatasphere.qualitis.metadata.request.GetClusterByUserRequest; import com.webank.wedatasphere.qualitis.metadata.request.GetColumnByUserAndTableRequest; import com.webank.wedatasphere.qualitis.metadata.request.GetDbByUserAndClusterRequest; import com.webank.wedatasphere.qualitis.metadata.request.GetTableByUserAndDbRequest; -import com.webank.wedatasphere.qualitis.metadata.response.ClusterMappingDetail; import com.webank.wedatasphere.qualitis.metadata.response.DataInfo; import com.webank.wedatasphere.qualitis.metadata.response.cluster.ClusterInfoDetail; import com.webank.wedatasphere.qualitis.metadata.response.column.ColumnInfoDetail; import com.webank.wedatasphere.qualitis.metadata.response.db.DbInfoDetail; import com.webank.wedatasphere.qualitis.metadata.response.table.TableInfoDetail; -import com.webank.wedatasphere.qualitis.exception.UnExpectedRequestException; -import com.webank.wedatasphere.qualitis.metadata.request.GetDbByUserAndClusterRequest; -import com.webank.wedatasphere.qualitis.metadata.response.DataInfo; -import com.webank.wedatasphere.qualitis.metadata.response.column.ColumnInfoDetail; -import com.webank.wedatasphere.qualitis.metadata.response.db.DbInfoDetail; -import com.webank.wedatasphere.qualitis.metadata.response.table.TableInfoDetail; +import java.util.List; /** * @author howeye @@ -69,6 +64,19 @@ DataInfo getDbByUserAndCluster(GetDbByUserAndClusterRequest reques DataInfo getTableByUserAndDb(GetTableByUserAndDbRequest request) throws MetaDataAcquireFailedException, UnExpectedRequestException; + /** + * Get table commit from table basic info. More table details can be obtained in the future + * @param clusterName + * @param dbName + * @param tableName + * @param userName + * @return + * @throws MetaDataAcquireFailedException + * @throws UnExpectedRequestException + */ + String getTableComment(String clusterName, String dbName, String tableName, String userName) + throws MetaDataAcquireFailedException, UnExpectedRequestException; + /** * Get column by user and table * @param request @@ -79,4 +87,17 @@ DataInfo getTableByUserAndDb(GetTableByUserAndDbRequest request DataInfo getColumnByUserAndTable(GetColumnByUserAndTableRequest request) throws MetaDataAcquireFailedException, UnExpectedRequestException; + /** + * Get the columns' information of the table + * @param clusterName + * @param dbName + * @param tableName + * @param userName + * @return + * @throws MetaDataAcquireFailedException + * @throws UnExpectedRequestException + */ + List getColumnInfo(String clusterName, String dbName, String tableName, String userName) + throws MetaDataAcquireFailedException, UnExpectedRequestException; + } \ No newline at end of file diff --git a/core/common/src/main/java/com/webank/wedatasphere/qualitis/metadata/response/column/ColumnInfoDetail.java b/core/common/src/main/java/com/webank/wedatasphere/qualitis/metadata/response/column/ColumnInfoDetail.java index 33f3e143..d3773423 100644 --- a/core/common/src/main/java/com/webank/wedatasphere/qualitis/metadata/response/column/ColumnInfoDetail.java +++ b/core/common/src/main/java/com/webank/wedatasphere/qualitis/metadata/response/column/ColumnInfoDetail.java @@ -27,6 +27,19 @@ public class ColumnInfoDetail { private String fieldName; @JsonProperty("data_type") private String dataType; + /** + * Extended attributes, displayed as data source rule query. + */ + @JsonProperty("column_length") + private int columnLen; + @JsonProperty("column_alias") + private String columnAlias; + @JsonProperty("column_comment") + private String columnComment; + @JsonProperty("is_primary") + private Boolean isPrimary; + @JsonProperty("is_partition") + private Boolean isPartitionField; public ColumnInfoDetail() { // Default Constructor @@ -53,4 +66,43 @@ public void setDataType(String dataType) { this.dataType = dataType; } + public int getColumnLen() { + return columnLen; + } + + public void setColumnLen(int columnLen) { + this.columnLen = columnLen; + } + + public String getColumnAlias() { + return columnAlias; + } + + public void setColumnAlias(String columnAlias) { + this.columnAlias = columnAlias; + } + + public String getColumnComment() { + return columnComment; + } + + public void setColumnComment(String columnComment) { + this.columnComment = columnComment; + } + + public Boolean getPrimary() { + return isPrimary; + } + + public void setPrimary(Boolean primary) { + isPrimary = primary; + } + + public Boolean getPartitionField() { + return isPartitionField; + } + + public void setPartitionField(Boolean partitionField) { + isPartitionField = partitionField; + } } diff --git a/core/common/src/main/java/com/webank/wedatasphere/qualitis/metadata/response/table/CsTableInfoDetail.java b/core/common/src/main/java/com/webank/wedatasphere/qualitis/metadata/response/table/CsTableInfoDetail.java new file mode 100644 index 00000000..76c3dbf5 --- /dev/null +++ b/core/common/src/main/java/com/webank/wedatasphere/qualitis/metadata/response/table/CsTableInfoDetail.java @@ -0,0 +1,34 @@ +package com.webank.wedatasphere.qualitis.metadata.response.table; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author allenzhou + */ +public class CsTableInfoDetail { + + @JsonProperty("table_name") + private String tableName; + @JsonProperty("context_Key") + private String contextKey; + + public CsTableInfoDetail() { + // Default Constructor + } + + public CsTableInfoDetail(String tableName) { + this.tableName = tableName; + } + + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + public String getContextKey() { return contextKey; } + + public void setContextKey(String contextKey) { this.contextKey = contextKey; } +} diff --git a/core/common/src/main/java/com/webank/wedatasphere/qualitis/parser/HiveSqlParser.java b/core/common/src/main/java/com/webank/wedatasphere/qualitis/parser/HiveSqlParser.java index dce51cef..15698370 100644 --- a/core/common/src/main/java/com/webank/wedatasphere/qualitis/parser/HiveSqlParser.java +++ b/core/common/src/main/java/com/webank/wedatasphere/qualitis/parser/HiveSqlParser.java @@ -95,4 +95,9 @@ private void getAndSaveTable(ASTNode node) throws HiveSqlParseException { dbAndTableMap.put(db, tableList); } } + + public static void main(String[] args) throws SemanticException, ParseException { + HiveSqlParser hiveSqlParser = new HiveSqlParser(); + System.out.println(hiveSqlParser.checkSelectSqlAndGetDbAndTable("select a from db1.table1 where ds=10")); + } } diff --git a/core/common/src/main/java/com/webank/wedatasphere/qualitis/parser/LocaleParser.java b/core/common/src/main/java/com/webank/wedatasphere/qualitis/parser/LocaleParser.java index b213bce6..4bef872f 100644 --- a/core/common/src/main/java/com/webank/wedatasphere/qualitis/parser/LocaleParser.java +++ b/core/common/src/main/java/com/webank/wedatasphere/qualitis/parser/LocaleParser.java @@ -35,7 +35,8 @@ public class LocaleParser { private static final Pattern KEY_WORD_PATTERN = Pattern.compile("\\{&.*?}"); - + private static final String ZH_CN_1 = "zh-CN"; + private static final String ZH_CN_2 = "zh_CN"; private static final Logger LOGGER = LoggerFactory.getLogger(LocaleParser.class); @Autowired @@ -46,15 +47,19 @@ public String replacePlaceHolderByLocale(String message, String localeStr) { try { locale = LocaleUtils.toLocale(localeStr); } catch (Exception e) { - LOGGER.warn("Failed to get locale: {}, set to default en_US", localeStr); - locale = Locale.US; + LOGGER.warn("Failed to get locale: {}, set according to actual parameters", localeStr.replace("\r", "").replace("\n", "")); + if (ZH_CN_1.equals(localeStr) || ZH_CN_2.equals(localeStr)) { + locale = Locale.CHINA; + } else { + locale = Locale.US; + } } if (StringUtils.isBlank(localeStr)) { - LOGGER.warn("Failed to get locale: {}, set to default en_US", localeStr); + LOGGER.warn("Failed to get locale: {}, set to default en_US", localeStr.replace("\r", "").replace("\n", "")); locale = Locale.US; } if (!locale.equals(Locale.US) && !locale.equals(Locale.CHINA)) { - LOGGER.warn("Does not support locale: {}, set to default en_US", localeStr); + LOGGER.warn("Does not support locale: {}, set to default en_US", localeStr.replace("\r", "").replace("\n", "")); locale = Locale.US; } Matcher m = KEY_WORD_PATTERN.matcher(message); diff --git a/core/converter/src/main/java/com/webank/wedatasphere/qualitis/converter/SqlTemplateConverter.java b/core/converter/src/main/java/com/webank/wedatasphere/qualitis/converter/SqlTemplateConverter.java index f11cd7ef..4a22f667 100644 --- a/core/converter/src/main/java/com/webank/wedatasphere/qualitis/converter/SqlTemplateConverter.java +++ b/core/converter/src/main/java/com/webank/wedatasphere/qualitis/converter/SqlTemplateConverter.java @@ -45,6 +45,7 @@ import com.webank.wedatasphere.qualitis.rule.entity.TemplateStatisticsInputMeta; import com.webank.wedatasphere.qualitis.translator.AbstractTranslator; import com.webank.wedatasphere.qualitis.util.DateExprReplaceUtil; +import java.util.regex.Matcher; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -73,11 +74,15 @@ public class SqlTemplateConverter extends AbstractTemplateConverter { public static final String VARIABLE_NAME_PLACEHOLDER = "${VARIABLE}"; private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile(".*\\$\\{(.*)}.*"); + private static final Pattern AGGREGATE_FUNC_PATTERN = Pattern.compile("[a-zA-Z]+\\([0-9a-zA-Z_]+\\)"); private static final String SPARK_SQL_TEMPLATE_PLACEHOLDER = "${SQL}"; private static final String SAVE_MID_TABLE_NAME_PLACEHOLDER = "${TABLE_NAME}"; private static final String FILTER_PLACEHOLDER = "${filter}"; private static final String FILTER_LEFT_PLACEHOLDER = "${filter_left}"; private static final String FILTER_RIGHT_PLACEHOLDER = "${filter_right}"; + private static final Integer COMMON_RULE = 1; + private static final Integer CUSTOM_RULE = 2; + private static final Integer MUL_SOURCE_RULE = 3; private static final String SPARK_SQL_TEMPLATE = "val " + VARIABLE_NAME_PLACEHOLDER + " = spark.sql(\"" + SPARK_SQL_TEMPLATE_PLACEHOLDER + "\");"; private static final String SAVE_MID_TABLE_SENTENCE_TEMPLATE = VARIABLE_NAME_PLACEHOLDER + ".write.saveAsTable(\"" + SAVE_MID_TABLE_NAME_PLACEHOLDER + "\");"; @@ -116,7 +121,9 @@ public DataQualityJob convert(DataQualityTask dataQualityTask) throws ConvertExc childMidTableName, dataQualityTask.getCreateTime(), dataQualityTask.getPartition(), count); job.getJobCode().addAll(codes); LOGGER.info("Succeed to convert rule into code. rule_id: {}, rul_name: {}, codes: {}", ruleTaskDetail.getRule().getId(), ruleTaskDetail.getRule().getName(), codes); - count++; + count ++; + // Fix variables' sequence when solving child rule of parent rule. Solving widget influence. + count ++; } List codes = generateSparkSqlByTask(ruleTaskDetail.getRule(), dataQualityTask.getApplicationId(), ruleTaskDetail.getMidTableName(), dataQualityTask.getCreateTime(), dataQualityTask.getPartition(), count); @@ -143,9 +150,9 @@ public DataQualityJob convert(DataQualityTask dataQualityTask) throws ConvertExc */ private List generateSparkSqlByTask(Rule rule, String applicationId, String midTableName, String createTime, String partition, Integer count) throws ConvertException, RuleVariableNotSupportException, RuleVariableNotFoundException { List sqlList = new ArrayList<>(); - // Get SQL from template String templateMidTableAction = rule.getTemplate().getMidTableAction(); + // Get input meta from template List inputMetaRuleVariables = rule.getRuleVariables().stream().filter( ruleVariable -> ruleVariable.getInputActionStep().equals(InputActionStepEnum.TEMPLATE_INPUT_META.getCode())).collect(Collectors.toList()); @@ -201,7 +208,7 @@ private List generateSparkSqlByTask(Rule rule, String applicationId, Str // Generate select statement and save into hive database sqlList.addAll(generateSparkSqlAndSaveSentence(midTableAction, midTableName, rule.getTemplate().getSaveMidTable(), count)); - + count ++; // Generate statistics statement, and save into mysql List statisticsRuleVariables = rule.getRuleVariables().stream().filter( ruleVariable -> ruleVariable.getInputActionStep().equals(InputActionStepEnum.STATISTICS_ARG.getCode())).collect(Collectors.toList()); @@ -229,6 +236,18 @@ private List generateSparkSqlAndSaveSentence(String sql, String saveTabl String sparkSqlSentence = getSparkSqlSentence(sql, count); sparkSqlList.add(sparkSqlSentence); LOGGER.info("Succeed to generate spark sql. sentence: {}", sparkSqlSentence); + // Fix bug in the workflow between widget node and qualitis node. + String variableFormer = getVariableName(count); + String str1 = "val schemas = " + variableFormer + ".schema.fields.map(f => f.name).toList"; + String str2 = "val newSchemas = schemas.map(s => s.replaceAll(\"[()]\", \"\")).toList"; + // 后续变量序号加一 + count ++; + String variableLatter = getVariableName(count); + String str3 = "val " + variableLatter + " = " + variableFormer + ".toDF(newSchemas: _*)"; + sparkSqlList.add(str1); + sparkSqlList.add(str2); + sparkSqlList.add(str3); + // if (saveMidTable) { String midTableSentence = getSaveMidTableSentence(saveTableName, count); sparkSqlList.add(midTableSentence); @@ -263,7 +282,23 @@ private String replaceVariable(String template, List variables, St LOGGER.info("Succeed to replace {} into {}", FILTER_PLACEHOLDER, filter); for (RuleVariable ruleVariable : variables) { String placeHolder = "\\$\\{" + ruleVariable.getTemplateMidTableInputMeta().getPlaceholder() + "}"; - sqlAction = sqlAction.replaceAll(placeHolder, ruleVariable.getValue()); + // Fix issue of wedget node in the front. + if ("\\$\\{field}".equals(placeHolder)) { + Matcher matcher = AGGREGATE_FUNC_PATTERN.matcher(ruleVariable.getValue()); + while(matcher.find()) { + String[] funcs = matcher.group().split("\n"); + for (String func : funcs) { + ruleVariable.setValue(ruleVariable.getValue().replace(func, "`" + func + "`")); + } + } + } + // Fix replacement issue that db is null when running workflow. + if ("".equals(ruleVariable.getValue())) { + sqlAction = sqlAction.replaceAll(placeHolder + ".", ""); + } else { + sqlAction = sqlAction.replaceAll(placeHolder, ruleVariable.getValue()); + } + LOGGER.info("Succeed to replace {} into {}", placeHolder, ruleVariable.getValue()); } if (PLACEHOLDER_PATTERN.matcher(sqlAction).matches()) { diff --git a/core/divider/src/main/java/com/webank/wedatasphere/qualitis/divider/SameDataSourceTaskDivider.java b/core/divider/src/main/java/com/webank/wedatasphere/qualitis/divider/SameDataSourceTaskDivider.java index df0641a7..70bb6cc6 100644 --- a/core/divider/src/main/java/com/webank/wedatasphere/qualitis/divider/SameDataSourceTaskDivider.java +++ b/core/divider/src/main/java/com/webank/wedatasphere/qualitis/divider/SameDataSourceTaskDivider.java @@ -97,9 +97,11 @@ public List divide(List rules, String applicationId, Stri ruleTaskDetails = new ArrayList<>(); } } - DataQualityTask tmp = new DataQualityTask(applicationId, createTime, partition, ruleTaskDetails); - result.add(tmp); - LOGGER.info("Succeed to divide rules: {} into a task {}", ruleIdList, tmp); + if (ruleTaskDetails.size() > 0) { + DataQualityTask tmp = new DataQualityTask(applicationId, createTime, partition, ruleTaskDetails); + result.add(tmp); + LOGGER.info("Succeed to divide rules: {} into a task {}", ruleIdList, tmp); + } } LOGGER.info("Succeed to divide all rules into tasks. result: {}", result); diff --git a/core/meta_data/src/main/java/com/webank/wedatasphere/qualitis/client/impl/MetaDataClientImpl.java b/core/meta_data/src/main/java/com/webank/wedatasphere/qualitis/client/impl/MetaDataClientImpl.java index 4317b599..eb5f2d38 100644 --- a/core/meta_data/src/main/java/com/webank/wedatasphere/qualitis/client/impl/MetaDataClientImpl.java +++ b/core/meta_data/src/main/java/com/webank/wedatasphere/qualitis/client/impl/MetaDataClientImpl.java @@ -18,6 +18,8 @@ import com.webank.wedatasphere.qualitis.config.LinkisConfig; import com.webank.wedatasphere.qualitis.dao.ClusterInfoDao; +import com.webank.wedatasphere.qualitis.entity.ClusterInfo; +import com.webank.wedatasphere.qualitis.exception.UnExpectedRequestException; import com.webank.wedatasphere.qualitis.metadata.client.MetaDataClient; import com.webank.wedatasphere.qualitis.metadata.exception.MetaDataAcquireFailedException; import com.webank.wedatasphere.qualitis.metadata.request.GetClusterByUserRequest; @@ -29,8 +31,11 @@ import com.webank.wedatasphere.qualitis.metadata.response.column.ColumnInfoDetail; import com.webank.wedatasphere.qualitis.metadata.response.db.DbInfoDetail; import com.webank.wedatasphere.qualitis.metadata.response.table.TableInfoDetail; -import com.webank.wedatasphere.qualitis.entity.ClusterInfo; -import com.webank.wedatasphere.qualitis.exception.UnExpectedRequestException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.ws.rs.core.UriBuilder; import org.apache.commons.collections.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,12 +47,6 @@ import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; -import javax.ws.rs.core.UriBuilder; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - /** * @author howeye * @date 2019-04-22 @@ -55,176 +54,250 @@ @Component public class MetaDataClientImpl implements MetaDataClient { - @Autowired - private ClusterInfoDao clusterInfoDao; + private final static String QUERY_CS_TABLE_PATH = "/dss/cs/tables"; + private final static String QUERY_CS_COLUMN_PATH = "/dss/cs/columns"; - @Autowired - private RestTemplate restTemplate; + @Autowired + private ClusterInfoDao clusterInfoDao; - @Autowired - private LinkisConfig linkisConfig; + @Autowired + private RestTemplate restTemplate; - private static final Logger LOGGER = LoggerFactory.getLogger(MetaDataClientImpl.class); + @Autowired + private LinkisConfig linkisConfig; - @Override - public DataInfo getClusterByUser(GetClusterByUserRequest request) { - Long total = clusterInfoDao.countAll(); - List allCluster = clusterInfoDao.findAllClusterInfo(request.getStartIndex(), request.getPageSize()); + private static final Logger LOGGER = LoggerFactory.getLogger(MetaDataClientImpl.class); - DataInfo dataInfo = new DataInfo<>(total.intValue()); - if (CollectionUtils.isEmpty(allCluster)) { - return dataInfo; - } - List details = new ArrayList<>(); - for (ClusterInfo clusterInfo : allCluster) { - ClusterInfoDetail detail = new ClusterInfoDetail(clusterInfo.getClusterName()); - details.add(detail); - } - dataInfo.setContent(details); - return dataInfo; - } - - @Override - public DataInfo getDbByUserAndCluster(GetDbByUserAndClusterRequest request) - throws UnExpectedRequestException, MetaDataAcquireFailedException { - // Check existence of cluster name - ClusterInfo clusterInfo = checkClusterNameExists( - request.getClusterName()); - String authUser = request.getLoginUser(); - // send request to get dbs - String url = getPath(clusterInfo.getLinkisAddress()).path(linkisConfig.getDbPath()).toString(); - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - headers.add("Token-User", authUser); - headers.add("Token-Code", clusterInfo.getLinkisToken()); - - HttpEntity entity = new HttpEntity<>(headers); - LOGGER.info("Start to get db by user and cluster by linkis. url: {}, method: {}, body: {}", url, javax.ws.rs.HttpMethod.GET, entity); - Map response = restTemplate.exchange(url, HttpMethod.GET, entity, Map.class).getBody(); - LOGGER.info("Start to get db by user and cluster by linkis. response: {}", response); - - if (!checkResponse(response)) { - String message = (String) response.get("message"); - throw new MetaDataAcquireFailedException("Error! Can not get meta data from linkis, exception: " + message); + @Override + public DataInfo getClusterByUser(GetClusterByUserRequest request) { + Long total = clusterInfoDao.countAll(); + List allCluster = clusterInfoDao.findAllClusterInfo(request.getStartIndex(), request.getPageSize()); + + DataInfo dataInfo = new DataInfo<>(total.intValue()); + if (CollectionUtils.isEmpty(allCluster)) { + return dataInfo; + } + List details = new ArrayList<>(); + for (ClusterInfo clusterInfo : allCluster) { + ClusterInfoDetail detail = new ClusterInfoDetail(clusterInfo.getClusterName()); + details.add(detail); + } + dataInfo.setContent(details); + return dataInfo; } - List allDbs = ((List>)((Map)response.get("data")).get("dbs")).stream() + @Override + public DataInfo getDbByUserAndCluster(GetDbByUserAndClusterRequest request) + throws UnExpectedRequestException, MetaDataAcquireFailedException { + // Check existence of cluster name + ClusterInfo clusterInfo = checkClusterNameExists( + request.getClusterName()); + String authUser = request.getLoginUser(); + // send request to get dbs + String url = getPath(clusterInfo.getLinkisAddress()).path(linkisConfig.getDbPath()).toString(); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.add("Token-User", authUser); + headers.add("Token-Code", clusterInfo.getLinkisToken()); + + HttpEntity entity = new HttpEntity<>(headers); + LOGGER.info("Start to get db by user and cluster by linkis. url: {}, method: {}, body: {}", url, javax.ws.rs.HttpMethod.GET, entity); + Map response = restTemplate.exchange(url, HttpMethod.GET, entity, Map.class).getBody(); + LOGGER.info("Start to get db by user and cluster by linkis. response: {}", response); + + if (!checkResponse(response)) { + String message = (String) response.get("message"); + throw new MetaDataAcquireFailedException("Error! Can not get meta data from linkis, exception: " + message); + } + + List allDbs = ((List>) ((Map) response.get("data")).get("dbs")).stream() .map(o -> o.get("dbName")).collect(Collectors.toList()); - DataInfo dataInfo = new DataInfo<>(allDbs.size()); - if (CollectionUtils.isEmpty(allDbs)) { - return dataInfo; - } - - List details = new ArrayList<>(); - for (String data : allDbs) { - DbInfoDetail detail = new DbInfoDetail(data); - details.add(detail); + DataInfo dataInfo = new DataInfo<>(allDbs.size()); + if (CollectionUtils.isEmpty(allDbs)) { + return dataInfo; + } + + List details = new ArrayList<>(); + for (String data : allDbs) { + DbInfoDetail detail = new DbInfoDetail(data); + details.add(detail); + } + dataInfo.setContent(details); + return dataInfo; } - dataInfo.setContent(details); - return dataInfo; - } - @Override - public DataInfo getTableByUserAndDb(GetTableByUserAndDbRequest request) - throws UnExpectedRequestException, MetaDataAcquireFailedException { - ClusterInfo clusterInfo = checkClusterNameExists(request.getClusterName()); - String authUser = request.getLoginUser(); + @Override + public DataInfo getTableByUserAndDb(GetTableByUserAndDbRequest request) + throws UnExpectedRequestException, MetaDataAcquireFailedException { + ClusterInfo clusterInfo = checkClusterNameExists(request.getClusterName()); + String authUser = request.getLoginUser(); - // send request to get dbs - String url = getPath(clusterInfo.getLinkisAddress()).path(linkisConfig.getTablePath()) + // send request to get dbs + String url = getPath(clusterInfo.getLinkisAddress()).path(linkisConfig.getTablePath()) .queryParam("database", request.getDbName()).toString(); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - headers.add("Token-User", authUser); - headers.add("Token-Code", clusterInfo.getLinkisToken()); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.add("Token-User", authUser); + headers.add("Token-Code", clusterInfo.getLinkisToken()); - HttpEntity entity = new HttpEntity<>(headers); - LOGGER.info("Start to get table by user and cluster and db by linkis. url: {}, method: {}, body: {}", url, javax.ws.rs.HttpMethod.GET, entity); - Map response = restTemplate.exchange(url, HttpMethod.GET, entity, Map.class).getBody(); - LOGGER.info("Start to get table by user and cluster and db by linkis. response: {}", response); + HttpEntity entity = new HttpEntity<>(headers); + LOGGER + .info("Start to get table by user and cluster and db by linkis. url: {}, method: {}, body: {}", url, javax.ws.rs.HttpMethod.GET, entity); + Map response = restTemplate.exchange(url, HttpMethod.GET, entity, Map.class).getBody(); + LOGGER.info("Start to get table by user and cluster and db by linkis. response: {}", response); - if (!checkResponse(response)) { - String message = (String) response.get("message"); - throw new MetaDataAcquireFailedException("Error! Can not get meta data from linkis, exception: " + message); - } + if (!checkResponse(response)) { + String message = (String) response.get("message"); + throw new MetaDataAcquireFailedException("Error! Can not get meta data from linkis, exception: " + message); + } - List allTables = ((List>)((Map)response.get("data")).get("tables")).stream() + List allTables = ((List>) ((Map) response.get("data")).get("tables")).stream() .map(o -> o.get("tableName")).collect(Collectors.toList()); - DataInfo dataInfo = new DataInfo<>(allTables.size()); - - if (CollectionUtils.isEmpty(allTables)) { - return dataInfo; + DataInfo dataInfo = new DataInfo<>(allTables.size()); + + if (CollectionUtils.isEmpty(allTables)) { + return dataInfo; + } + List details = new ArrayList<>(); + for (String data : allTables) { + TableInfoDetail detail = new TableInfoDetail(data); + details.add(detail); + } + dataInfo.setContent(details); + return dataInfo; } - List details = new ArrayList<>(); - for (String data : allTables) { - TableInfoDetail detail = new TableInfoDetail(data); - details.add(detail); + + @Override + public String getTableComment(String clusterName, String dbName, String tableName, String userName) + throws MetaDataAcquireFailedException, UnExpectedRequestException { + ClusterInfo clusterInfo = checkClusterNameExists(clusterName); + // send request to get table comment. + String url = getPath(clusterInfo.getLinkisAddress()).path(linkisConfig.getTableComment()) + .queryParam("database", dbName).queryParam("tableName", tableName).toString(); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.add("Token-User", userName); + headers.add("Token-Code", clusterInfo.getLinkisToken()); + + HttpEntity entity = new HttpEntity<>(headers); + LOGGER.info("Start to get table comment by user and cluster and db by linkis. url: {}, method: {}, body: {}", url, javax.ws.rs.HttpMethod.GET, + entity); + Map response = restTemplate.exchange(url, HttpMethod.GET, entity, Map.class).getBody(); + LOGGER.info("Finished to get table comment by user and cluster and db by linkis. response: {}", response); + + if (!checkResponse(response)) { + String message = (String) response.get("message"); + throw new MetaDataAcquireFailedException("Error! Can not get meta data from linkis, exception: " + message); + } + Object result = ((Map) ((Map) ((Map) response.get("data")).get("tableBaseInfo")).get("base")) + .get("comment"); + String comment = result == null ? "no comment" : result.toString(); + return comment; } - dataInfo.setContent(details); - return dataInfo; - } - - @Override - public DataInfo getColumnByUserAndTable(GetColumnByUserAndTableRequest request) - throws UnExpectedRequestException, MetaDataAcquireFailedException { - ClusterInfo clusterInfo = checkClusterNameExists(request.getClusterName()); - String authUser = request.getLoginUser(); - - // send request to get dbs - String url = getPath(clusterInfo.getLinkisAddress()).path(linkisConfig.getColumnPath()) + + @Override + public DataInfo getColumnByUserAndTable(GetColumnByUserAndTableRequest request) + throws UnExpectedRequestException, MetaDataAcquireFailedException { + ClusterInfo clusterInfo = checkClusterNameExists(request.getClusterName()); + String authUser = request.getLoginUser(); + + // send request to get dbs + String url = getPath(clusterInfo.getLinkisAddress()).path(linkisConfig.getColumnPath()) .queryParam("database", request.getDbName()).queryParam("table", request.getTableName()).toString(); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - headers.add("Token-User", authUser); - headers.add("Token-Code", clusterInfo.getLinkisToken()); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.add("Token-User", authUser); + headers.add("Token-Code", clusterInfo.getLinkisToken()); - HttpEntity entity = new HttpEntity<>(headers); - LOGGER.info("Start to get column by user and cluster and db and table by linkis. url: {}, method: {}, body: {}", url, + HttpEntity entity = new HttpEntity<>(headers); + LOGGER.info("Start to get column by user and cluster and db and table by linkis. url: {}, method: {}, body: {}", url, javax.ws.rs.HttpMethod.GET, entity); - Map response = restTemplate.exchange(url, HttpMethod.GET, entity, Map.class).getBody(); - LOGGER.info("Start to get table by user and cluster and and table by linkis. response: {}", response); - - if (!checkResponse(response)) { - String message = (String) response.get("message"); - throw new MetaDataAcquireFailedException("Error! Can not get meta data from linkis, exception: " + message); + Map response = restTemplate.exchange(url, HttpMethod.GET, entity, Map.class).getBody(); + LOGGER.info("Start to get table by user and cluster and and table by linkis. response: {}", response); + + if (!checkResponse(response)) { + String message = (String) response.get("message"); + throw new MetaDataAcquireFailedException("Error! Can not get meta data from linkis, exception: " + message); + } + + List> allTables = ((List>) ((Map) response.get("data")).get("columns")); + + DataInfo dataInfo = new DataInfo<>(allTables.size()); + if (CollectionUtils.isEmpty(allTables)) { + return dataInfo; + } + List details = new ArrayList<>(); + for (Map table : allTables) { + ColumnInfoDetail detail = new ColumnInfoDetail(table.get("columnName"), table.get("columnType")); + details.add(detail); + } + dataInfo.setContent(details); + return dataInfo; } - List> allTables = ((List>)((Map)response.get("data")).get("columns")); - - DataInfo dataInfo = new DataInfo<>(allTables.size()); - if (CollectionUtils.isEmpty(allTables)) { - return dataInfo; - } - List details = new ArrayList<>(); - for (Map table : allTables) { - ColumnInfoDetail detail = new ColumnInfoDetail(table.get("columnName"), table.get("columnType")); - details.add(detail); + @Override + public List getColumnInfo(String clusterName, String dbName, String tableName, String userName) + throws MetaDataAcquireFailedException, UnExpectedRequestException { + ClusterInfo clusterInfo = checkClusterNameExists(clusterName); + // send request to get table comment. + String url = getPath(clusterInfo.getLinkisAddress()).path(linkisConfig.getColumnInfo()) + .queryParam("database", dbName).queryParam("tableName", tableName).toString(); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.add("Token-User", userName); + headers.add("Token-Code", clusterInfo.getLinkisToken()); + HttpEntity entity = new HttpEntity<>(headers); + LOGGER.info("Start to get column info by user and cluster and db and table by linkis. url: {}, method: {}, body: {}", url, + javax.ws.rs.HttpMethod.GET, entity); + Map response = restTemplate.exchange(url, HttpMethod.GET, entity, Map.class).getBody(); + LOGGER.info("Finished to get column info by user and cluster and db and table by linkis. response: {}", response); + + if (!checkResponse(response)) { + String message = (String) response.get("message"); + throw new MetaDataAcquireFailedException("Error! Can not get meta data from linkis, exception: " + message); + } + + List> tableFieldInfo = (List>) ((Map) response.get("data")).get("tableFieldsInfo"); + List result = new ArrayList<>(); + for (Map map : tableFieldInfo) { + ColumnInfoDetail columnInfoDetail = new ColumnInfoDetail(); + columnInfoDetail.setFieldName(map.get("name").toString()); + columnInfoDetail.setDataType(map.get("type").toString()); + if (map.get("length") != null && ! "".equals(map.get("length").toString())) { + columnInfoDetail.setColumnLen(Integer.parseInt(map.get("length").toString())); + } + columnInfoDetail.setColumnAlias(map.get("alias") == null ? "" : map.get("alias").toString()); + columnInfoDetail.setColumnComment(map.get("comment") == null ? "" : map.get("comment").toString()); + columnInfoDetail.setPrimary((Boolean) map.get("primary")); + columnInfoDetail.setPartitionField((Boolean) map.get("partitionField")); + result.add(columnInfoDetail); + } + return result; } - dataInfo.setContent(details); - return dataInfo; - } - - private ClusterInfo checkClusterNameExists(String clusterName) throws - UnExpectedRequestException { - ClusterInfo clusterInfo = clusterInfoDao.findByClusterName(clusterName); - if (clusterInfo == null) { - throw new UnExpectedRequestException(String.format("%s 集群名称不存在", clusterName)); + + private ClusterInfo checkClusterNameExists(String clusterName) throws + UnExpectedRequestException { + ClusterInfo clusterInfo = clusterInfoDao.findByClusterName(clusterName); + if (clusterInfo == null) { + throw new UnExpectedRequestException(String.format("%s 集群名称不存在", clusterName)); + } + return clusterInfo; } - return clusterInfo; - } - private UriBuilder getPath(String linkisAddress) { - return UriBuilder.fromUri(linkisAddress).path(linkisConfig.getPrefix()); - } + private UriBuilder getPath(String linkisAddress) { + return UriBuilder.fromUri(linkisAddress).path(linkisConfig.getPrefix()); + } - private boolean checkResponse(Map response) { - Integer responseStatus = (Integer) response.get("status"); - return responseStatus == 0; - } + private boolean checkResponse(Map response) { + Integer responseStatus = (Integer) response.get("status"); + return responseStatus == 0; + } } diff --git a/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/ha/AbstractServiceCoordinator.java b/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/ha/AbstractServiceCoordinator.java new file mode 100644 index 00000000..0c2bccbf --- /dev/null +++ b/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/ha/AbstractServiceCoordinator.java @@ -0,0 +1,23 @@ +package com.webank.wedatasphere.qualitis.ha; + +/** + * @author howeye + */ +public abstract class AbstractServiceCoordinator { + + /** + * Do some init work + */ + public abstract void init(); + + /** + * coordinate multi service + */ + public abstract void coordinate(); + + /** + * Do some release work + */ + public abstract void release(); + +} diff --git a/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/ha/HaAbstractServiceCoordinator.java b/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/ha/HaAbstractServiceCoordinator.java new file mode 100644 index 00000000..b35ad4bb --- /dev/null +++ b/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/ha/HaAbstractServiceCoordinator.java @@ -0,0 +1,87 @@ +package com.webank.wedatasphere.qualitis.ha; + +import com.webank.wedatasphere.qualitis.config.ThreadPoolConfig; +import com.webank.wedatasphere.qualitis.config.ZkConfig; +import org.apache.curator.RetryPolicy; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.CuratorFrameworkFactory; +import org.apache.curator.framework.recipes.locks.InterProcessLock; +import org.apache.curator.framework.recipes.locks.InterProcessMutex; +import org.apache.curator.retry.ExponentialBackoffRetry; +import org.apache.curator.utils.CloseableUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; + +/** + * @author howeye + */ +@Component +@ConditionalOnProperty(name = "ha.enable", havingValue = "true") +public class HaAbstractServiceCoordinator extends AbstractServiceCoordinator { + + private static final Logger LOGGER = LoggerFactory.getLogger(HaAbstractServiceCoordinator.class); + + @Autowired + private ZkConfig zkConfig; + + @Autowired + private ThreadPoolConfig threadPoolConfig; + + private String lockPath; + private InterProcessLock lock; + private boolean lockFlag = false; + + @Override + public void init() { + LOGGER.info("Start to create zookeeper client"); + CuratorFramework client = createClient(); + lockPath = threadPoolConfig.getLockZkPath(); + lock = new InterProcessMutex(client, lockPath); + } + + @Override + public void coordinate() { + try { + LOGGER.info("Trying to acquire lock of zk, lock_path: {}, lock: {}", lockPath, lock.hashCode()); + lock.acquire(); + lockFlag = true; + LOGGER.info("Succeed to acquire lock of zk, lock_path: {}, lock: {}", lockPath, lock.hashCode()); + } catch (Exception e) { + LOGGER.error("Failed to get lock of zk, lock_path: {}, caused by: {}", lockPath, e.getMessage(), e); + } + } + + @Override + public void release() { + if (lockFlag) { + lockFlag = false; + try { + lock.release(); + } catch (Exception e) { + LOGGER.error("Failed to release lock of zookeeper", e); + } + } + } + + public CuratorFramework createClient() { + Integer baseSleepTimeMs = zkConfig.getBaseSleepTimeMs(); + Integer maxRetries = zkConfig.getMaxRetries(); + Integer sessionTimeOutMs = zkConfig.getSessionTimeOutMs(); + Integer connectionTimeOutMs = zkConfig.getConnectionTimeOutMs(); + + RetryPolicy retryPolicy = new ExponentialBackoffRetry(baseSleepTimeMs, maxRetries); + CuratorFramework client = CuratorFrameworkFactory.newClient(zkConfig.getZkAddress(), sessionTimeOutMs, connectionTimeOutMs, retryPolicy); + + LOGGER.info("Start to create zookeeper connection., url: {}", zkConfig.getZkAddress()); + client.start(); + LOGGER.info("Succeed to create zookeeper connection. url: {}", zkConfig.getZkAddress()); + return client; + } + + public void closeClient(CuratorFramework client) { + CloseableUtils.closeQuietly(client); + } +} diff --git a/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/ha/StandAloneAbstractServiceCoordinator.java b/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/ha/StandAloneAbstractServiceCoordinator.java new file mode 100644 index 00000000..1f6907b1 --- /dev/null +++ b/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/ha/StandAloneAbstractServiceCoordinator.java @@ -0,0 +1,27 @@ +package com.webank.wedatasphere.qualitis.ha; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; + +/** + * @author howeye + */ +@Component +@ConditionalOnProperty(name = "ha.enable", havingValue = "false") +public class StandAloneAbstractServiceCoordinator extends AbstractServiceCoordinator { + + @Override + public void init() { + // No need to init + } + + @Override + public void coordinate() { + // No need to coordinate with other service + } + + @Override + public void release() { + // No need to release + } +} diff --git a/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/timer/CheckerRunnable.java b/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/timer/CheckerRunnable.java index c80140c7..af57c235 100644 --- a/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/timer/CheckerRunnable.java +++ b/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/timer/CheckerRunnable.java @@ -19,19 +19,12 @@ import com.webank.wedatasphere.qualitis.bean.JobChecker; import com.webank.wedatasphere.qualitis.constant.ApplicationStatusEnum; import com.webank.wedatasphere.qualitis.constant.TaskStatusEnum; -import com.webank.wedatasphere.qualitis.zk.ZookeeperCuratorManager; import com.webank.wedatasphere.qualitis.dao.ApplicationDao; import com.webank.wedatasphere.qualitis.dao.TaskDao; import com.webank.wedatasphere.qualitis.entity.Application; import com.webank.wedatasphere.qualitis.entity.Task; -import com.webank.wedatasphere.qualitis.bean.JobChecker; -import com.webank.wedatasphere.qualitis.dao.ApplicationDao; -import com.webank.wedatasphere.qualitis.dao.TaskDao; -import com.webank.wedatasphere.qualitis.zk.ZookeeperCuratorManager; -import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.recipes.locks.InterProcessLock; -import org.apache.curator.framework.recipes.locks.InterProcessMutex; +import com.webank.wedatasphere.qualitis.ha.AbstractServiceCoordinator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,31 +40,25 @@ public class CheckerRunnable implements Runnable { private ApplicationDao applicationDao; private TaskDao taskDao; private IChecker iChecker; + private AbstractServiceCoordinator abstractServiceCoordinator; private static final Logger LOGGER = LoggerFactory.getLogger("monitor"); - private InterProcessLock lock; - private String lockPath; - private boolean lockFlag = false; - public CheckerRunnable(ApplicationDao applicationDao, TaskDao taskDao, ZookeeperCuratorManager zookeeperCuratorManager, - String monitorLockPath, IChecker iChecker) { + public CheckerRunnable(ApplicationDao applicationDao, TaskDao taskDao, IChecker iChecker, AbstractServiceCoordinator abstractServiceCoordinator) { this.applicationDao = applicationDao; this.taskDao = taskDao; - this.lockFlag = false; this.iChecker = iChecker; + this.abstractServiceCoordinator = abstractServiceCoordinator; - LOGGER.info("Start to create zookeeper client"); - CuratorFramework client = zookeeperCuratorManager.createClient(); - lockPath = monitorLockPath; - lock = new InterProcessMutex(client, lockPath); + abstractServiceCoordinator.init(); } @Override public void run() { try { LOGGER.info("Start to monitor application"); - acquireLock(); + abstractServiceCoordinator.coordinate(); // Get task that is not finished List jobs = null; @@ -95,28 +82,10 @@ public void run() { } catch (Exception e) { LOGGER.error("Failed to monitor application, caused by: {}", e.getMessage(), e); } finally { - if (lockFlag) { - lockFlag = false; - try { - lock.release(); - } catch (Exception e) { - LOGGER.error("Failed to release lock of zookeeper", e); - } - } + abstractServiceCoordinator.release(); } } - private void acquireLock() { - // Trying to acquire lock - try { - LOGGER.info("Trying to acquire lock of zk, lock_path: {}, lock: {}", lockPath, lock.hashCode()); - lock.acquire(); - lockFlag = true; - LOGGER.info("Succeed to acquire lock of zk, lock_path: {}, lock: {}", lockPath, lock.hashCode()); - } catch (Exception e) { - LOGGER.error("Failed to get lock of zk, lock_path: {}, caused by: {}", lockPath, e.getMessage(), e); - } - } private static final List END_APPLICATION_STATUS_LIST = Arrays.asList(ApplicationStatusEnum.FINISHED.getCode(), ApplicationStatusEnum.FAILED.getCode(), diff --git a/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/timer/JobCheckerTimer.java b/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/timer/JobCheckerTimer.java index 5560052d..8c134a9a 100644 --- a/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/timer/JobCheckerTimer.java +++ b/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/timer/JobCheckerTimer.java @@ -17,13 +17,10 @@ package com.webank.wedatasphere.qualitis.timer; import com.webank.wedatasphere.qualitis.config.ThreadPoolConfig; -import com.webank.wedatasphere.qualitis.zk.ZookeeperCuratorManager; import com.webank.wedatasphere.qualitis.dao.ApplicationDao; import com.webank.wedatasphere.qualitis.dao.TaskDao; -import com.webank.wedatasphere.qualitis.dao.ApplicationDao; -import com.webank.wedatasphere.qualitis.dao.TaskDao; -import com.webank.wedatasphere.qualitis.zk.ZookeeperCuratorManager; +import com.webank.wedatasphere.qualitis.ha.AbstractServiceCoordinator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -46,15 +43,14 @@ public class JobCheckerTimer { @Autowired private TaskDao taskDao; @Autowired - private ZookeeperCuratorManager zookeeperCuratorManager; - @Autowired private IChecker iChecker; + @Autowired + private AbstractServiceCoordinator abstractServiceCoordinator; @PostConstruct public void init() { ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(threadPoolConfig.getSize(), new MonitoryThreadFactory()); - executor.scheduleWithFixedDelay(new CheckerRunnable(applicationDao, taskDao, zookeeperCuratorManager, - threadPoolConfig.getLockZkPath(), iChecker), 0, threadPoolConfig.getPeriod(), TimeUnit.MILLISECONDS); + executor.scheduleWithFixedDelay(new CheckerRunnable(applicationDao, taskDao, iChecker, abstractServiceCoordinator), 0, threadPoolConfig.getPeriod(), TimeUnit.MILLISECONDS); } } diff --git a/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/timer/TaskChecker.java b/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/timer/TaskChecker.java index c3f71542..b4ab2614 100644 --- a/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/timer/TaskChecker.java +++ b/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/timer/TaskChecker.java @@ -158,7 +158,11 @@ private void modifyJobStatus(Task task, String newStatus) { } else if (newStatus.equals(TaskStatusEnum.PASS_CHECKOUT.getState())) { task.setStatus(TaskStatusEnum.PASS_CHECKOUT.getCode()); } else if (newStatus.equals(TaskStatusEnum.FAIL_CHECKOUT.getState())) { - task.setStatus(TaskStatusEnum.FAIL_CHECKOUT.getCode()); + if (task.isAbortOnFailure() != null && task.isAbortOnFailure()) { + task.setStatus(TaskStatusEnum.FAILED.getCode()); + } else { + task.setStatus(TaskStatusEnum.FAIL_CHECKOUT.getCode()); + } } else if (newStatus.equals(TaskStatusEnum.CANCELLED.getState())) { task.setStatus(TaskStatusEnum.CANCELLED.getCode()); } else if (newStatus.equals(TaskStatusEnum.TIMEOUT.getState())) { @@ -193,10 +197,10 @@ private Boolean checkTaskRuleSimplePass(String applicationId, TaskRuleSimple tas TaskResult taskResult = taskResultDao.findByApplicationIdAndRuleId(applicationId, taskRuleSimple.getRuleId()); for (TaskRuleAlarmConfig taskRuleAlarmConfig : taskRuleSimple.getTaskRuleAlarmConfigList()) { if (PassUtil.notSafe(applicationId, taskRuleSimple.getRuleId(), taskRuleAlarmConfig, taskResult, taskResultDao)) { + taskRuleAlarmConfig.setStatus(AlarmConfigStatusEnum.PASS.getCode()); + } else { passFlag = false; taskRuleAlarmConfig.setStatus(AlarmConfigStatusEnum.NOT_PASS.getCode()); - } else { - taskRuleAlarmConfig.setStatus(AlarmConfigStatusEnum.PASS.getCode()); } } return passFlag; diff --git a/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/util/PassUtil.java b/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/util/PassUtil.java index 4fc72997..ab589b8f 100644 --- a/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/util/PassUtil.java +++ b/core/monitor/src/main/java/com/webank/wedatasphere/qualitis/util/PassUtil.java @@ -98,7 +98,7 @@ private static Boolean moreThanThresholds(Double taskResult, Double compareValue Double maxValue = maxPercentage * compareValue; Double minValue = minPercentage * compareValue; - return taskResult > maxValue || taskResult < minValue; + return taskResult <= maxValue && taskResult >= minValue; } } else { return false; diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/project/entity/Project.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/project/entity/Project.java index c878d57c..bf3a0648 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/project/entity/Project.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/project/entity/Project.java @@ -16,8 +16,12 @@ package com.webank.wedatasphere.qualitis.project.entity; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import com.webank.wedatasphere.qualitis.rule.entity.Rule; +import java.util.ArrayList; +import java.util.List; import javax.persistence.*; import java.util.Set; @@ -25,6 +29,7 @@ * @author howeye */ @Entity +@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") @Table(name = "qualitis_project") public class Project { @@ -39,6 +44,9 @@ public class Project { @OneToMany(mappedBy = "project", cascade = {CascadeType.REMOVE, CascadeType.PERSIST}) private Set projectUsers; + @OneToMany(mappedBy = "project", cascade = {CascadeType.REMOVE, CascadeType.PERSIST}, fetch = FetchType.EAGER) + private Set projectLabels; + @OneToMany(mappedBy = "project", cascade = CascadeType.REMOVE, fetch = FetchType.EAGER) private Set rules; @@ -53,6 +61,15 @@ public class Project { @Column(name = "user_department", length = 50) private String userDepartment; + @Column(name = "create_time", length = 25) + private String createTime; + + @Column(name = "modify_user", length = 50) + private String modifyUser; + + @Column(name = "modify_time", length = 25) + private String modifyTime; + @Column(name = "project_type") private Integer projectType; @@ -67,6 +84,15 @@ public Project(String projectName, String description, String username, String c this.userDepartment = department; } + public Project(String projectName, String description, String username, String chineseName, String department, String createTime) { + this.name = projectName; + this.description = description; + this.createUser = username; + this.createUserFullName = username + "(" + chineseName + ")"; + this.userDepartment = department; + this.createTime = createTime; + } + public Long getId() { return id; } @@ -99,6 +125,14 @@ public void setProjectUsers(Set projectUsers) { this.projectUsers = projectUsers; } + public Set getProjectLabels() { + return projectLabels; + } + + public void setProjectLabels(Set projectLabels) { + this.projectLabels = projectLabels; + } + public Set getRules() { return rules; } @@ -139,15 +173,39 @@ public void setProjectType(Integer projectType) { this.projectType = projectType; } + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getModifyUser() { + return modifyUser; + } + + public void setModifyUser(String modifyUser) { + this.modifyUser = modifyUser; + } + + public String getModifyTime() { + return modifyTime; + } + + public void setModifyTime(String modifyTime) { + this.modifyTime = modifyTime; + } + @Override public String toString() { return "Project{" + - "id=" + id + - ", name='" + name + '\'' + - ", description='" + description + '\'' + - ", createUser='" + createUser + '\'' + - ", createUserFullName='" + createUserFullName + '\'' + - ", userDepartment='" + userDepartment + '\'' + - '}'; + "id=" + id + + ", name='" + name + '\'' + + ", description='" + description + '\'' + + ", createUser='" + createUser + '\'' + + ", createUserFullName='" + createUserFullName + '\'' + + ", userDepartment='" + userDepartment + '\'' + + '}'; } } diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/project/entity/ProjectLabel.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/project/entity/ProjectLabel.java new file mode 100644 index 00000000..a4be5323 --- /dev/null +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/project/entity/ProjectLabel.java @@ -0,0 +1,101 @@ +/* + * Copyright 2019 WeBank + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.webank.wedatasphere.qualitis.project.entity; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import java.util.Objects; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +/** + * @author allenzhou + */ +@Entity +@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") +@Table(name = "qualitis_project_label") +public class ProjectLabel { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + private Project project; + + @Column(name = "label_name", length = 20) + private String labelName; + + public ProjectLabel() { + } + + public ProjectLabel(Project project) { + this.project = project; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Project getProject() { + return project; + } + + public void setProject(Project project) { + this.project = project; + } + + public String getLabelName() { + return labelName; + } + + public void setLabelName(String labelName) { + this.labelName = labelName; + } + + @Override + public boolean equals(Object o) { + if (this == o) {return true;} + if (o == null || getClass() != o.getClass()) {return false;} + ProjectLabel that = (ProjectLabel) o; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + return "ProjectLabel{" + + "id=" + id + + ", project=" + project + + ", labelName='" + labelName + '\'' + + '}'; + } +} diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/project/entity/ProjectUser.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/project/entity/ProjectUser.java index f8d9a92a..f017789a 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/project/entity/ProjectUser.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/project/entity/ProjectUser.java @@ -16,6 +16,8 @@ package com.webank.wedatasphere.qualitis.project.entity; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import javax.persistence.*; import java.util.Objects; @@ -23,6 +25,7 @@ * @author howeye */ @Entity +@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") @Table(name = "qualitis_project_user") public class ProjectUser { @@ -32,6 +35,7 @@ public class ProjectUser { @ManyToOne private Project project; + private Integer permission; @Column(name = "user_name", length = 20) diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/constant/CheckTemplateEnum.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/constant/CheckTemplateEnum.java index 02f68a34..949af71a 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/constant/CheckTemplateEnum.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/constant/CheckTemplateEnum.java @@ -27,19 +27,21 @@ public enum CheckTemplateEnum { /** * Monthly, weekly, day and fixed name */ - MONTH_FLUCTUATION(1,"月波动", Arrays.asList(Number.class)), - WEEK_FLUCTUATION(2,"周波动", Arrays.asList(Number.class)), - DAY_FLUCTUATION(3,"日波动", Arrays.asList(Number.class)), - FIXED_VALUE(4,"固定值", Arrays.asList(Number.class)), + MONTH_FLUCTUATION(1,"月波动", "Month Fluctuation", Arrays.asList(Number.class)), + WEEK_FLUCTUATION(2,"周波动", "Week Fluctuation", Arrays.asList(Number.class)), + DAY_FLUCTUATION(3,"日波动", "Daily Fluctuation", Arrays.asList(Number.class)), + FIXED_VALUE(4,"固定值", "Fix Value", Arrays.asList(Number.class)), ; private Integer code; - private String message; + private String zhMessage; + private String enMessage; private List classes; - CheckTemplateEnum(Integer code, String message, List classes) { + CheckTemplateEnum(Integer code, String zhMessage, String enMessage, List classes) { this.code = code; - this.message = message; + this.zhMessage = zhMessage; + this.enMessage = enMessage; this.classes = classes; } @@ -47,8 +49,12 @@ public Integer getCode() { return code; } - public String getMessage() { - return message; + public String getZhMessage() { + return zhMessage; + } + + public String getEnMessage() { + return enMessage; } public List getClasses() { @@ -58,7 +64,7 @@ public List getClasses() { public static String getCheckTemplateName(Integer code) { for (CheckTemplateEnum c : CheckTemplateEnum.values()) { if (c.getCode().equals(code)) { - return c.getMessage(); + return c.getZhMessage(); } } return null; @@ -66,10 +72,38 @@ public static String getCheckTemplateName(Integer code) { public static Integer getCheckTemplateCode(String checkTemplateName) { for (CheckTemplateEnum c : CheckTemplateEnum.values()) { - if (c.getMessage().equals(checkTemplateName)) { + if (c.getZhMessage().equals(checkTemplateName)) { return c.getCode(); } } return null; } + + public static String getCheckTemplateName(Integer code, String local) { + for (CheckTemplateEnum c : CheckTemplateEnum.values()) { + if (c.getCode().equals(code)) { + if (local.equals("en_US")) { + return c.getEnMessage(); + } else { + return c.getZhMessage(); + } + } + } + return null; + } + + public static Integer getCheckTemplateCode(String checkTemplateName, String local) { + for (CheckTemplateEnum c : CheckTemplateEnum.values()) { + if (local.equals("en_US")) { + if (c.getEnMessage().equals(checkTemplateName)) { + return c.getCode(); + } + } else { + if (c.getZhMessage().equals(checkTemplateName)) { + return c.getCode(); + } + } + } + return null; + } } diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/RuleDao.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/RuleDao.java index b6b33365..d276c0bb 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/RuleDao.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/RuleDao.java @@ -20,6 +20,7 @@ import com.webank.wedatasphere.qualitis.rule.entity.Rule; import com.webank.wedatasphere.qualitis.rule.entity.RuleGroup; +import com.webank.wedatasphere.qualitis.rule.entity.Template; import java.util.List; /** @@ -34,6 +35,14 @@ public interface RuleDao { */ List findByProject(Project project); + /** + * Find rule by project + * @param project + * @param ruleName + * @return + */ + Rule findByProjectAndRuleName(Project project, String ruleName); + /** * Save rule * @param rule @@ -67,4 +76,11 @@ public interface RuleDao { * @return */ List findByRuleGroup(RuleGroup ruleGroup); + + /** + * Find rule by rule template + * @param templateInDb + * @return + */ + List findByTemplate(Template templateInDb); } diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/RuleDataSourceDao.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/RuleDataSourceDao.java index d9cefccc..00f65183 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/RuleDataSourceDao.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/RuleDataSourceDao.java @@ -46,7 +46,7 @@ public interface RuleDataSourceDao { * @param projectId * @return */ - List findByProjectId(Long projectId); + List findByProjectId(Long projectId); /** @@ -65,4 +65,46 @@ public interface RuleDataSourceDao { * @return */ List> findProjectDsByUser(String user); + + /** + * Paging query rule datasource + * @param user + * @param page + * @param size + * @return + */ + List> findProjectDsByUser(String user, int page, int size); + + /** + * Find rules related with cluster name, database name ,table name, column name. + * @param clusterName + * @param dbName + * @param tableName + * @param colName + * @param user + * @return + */ + List findRuleByDataSource(String clusterName, String dbName, String tableName, String colName, String user); + + /** + * Filter rule datasource + * @param user + * @param clusterName + * @param dbName + * @param tableName + * @return + */ + List> filterProjectDsByUser(String user, String clusterName, String dbName, String tableName); + + /** + * Filter rule datasource pageable. + * @param user + * @param clusterName + * @param dbName + * @param tableName + * @param page + * @param size + * @return + */ + List> filterProjectDsByUserPage(String user, String clusterName, String dbName, String tableName, int page, int size); } diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/TemplateMidTableInputMetaDao.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/TemplateMidTableInputMetaDao.java index 4bb82737..86e7f6f1 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/TemplateMidTableInputMetaDao.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/TemplateMidTableInputMetaDao.java @@ -20,6 +20,7 @@ import com.webank.wedatasphere.qualitis.rule.entity.TemplateMidTableInputMeta; import java.util.List; +import java.util.Set; /** * @author howeye @@ -40,4 +41,16 @@ public interface TemplateMidTableInputMetaDao { */ TemplateMidTableInputMeta findById(Long templateInputMetaId); + /** + * Save all template input meta. + * @param templateMidTableInputMetas + * @return + */ + Set saveAll(List templateMidTableInputMetas); + + /** + * Delete mid_table input meta by template + * @param templateInDb + */ + void deleteByTemplate(Template templateInDb); } diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/TemplateOutputMetaDao.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/TemplateOutputMetaDao.java index d137cf7f..47c18c32 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/TemplateOutputMetaDao.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/TemplateOutputMetaDao.java @@ -54,4 +54,9 @@ public interface TemplateOutputMetaDao { */ List findByTemplate(Template template); + /** + * Delete output meta by template + * @param templateInDb + */ + void deleteByTemplate(Template templateInDb); } diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/RuleDaoImpl.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/RuleDaoImpl.java index 0185603d..ef5ae5b5 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/RuleDaoImpl.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/RuleDaoImpl.java @@ -22,6 +22,7 @@ import com.webank.wedatasphere.qualitis.rule.entity.Rule; import com.webank.wedatasphere.qualitis.rule.entity.RuleGroup; import com.webank.wedatasphere.qualitis.rule.dao.RuleDao; +import com.webank.wedatasphere.qualitis.rule.entity.Template; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @@ -41,6 +42,17 @@ public List findByProject(Project project) { return ruleRepository.findByProject(project); } + @Override + public Rule findByProjectAndRuleName(Project project, String ruleName) { + List rules = findByProject(project); + for (Rule rule: rules) { + if (rule.getName().equals(ruleName)) { + return rule; + } + } + return null; + } + @Override public Rule saveRule(Rule rule) { return ruleRepository.save(rule); @@ -65,4 +77,9 @@ public List findByIds(List ruleIds) { public List findByRuleGroup(RuleGroup ruleGroup) { return ruleRepository.findByRuleGroup(ruleGroup); } + + @Override + public List findByTemplate(Template templateInDb) { + return ruleRepository.findByTemplate(templateInDb); + } } diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/RuleDataSourceDaoImpl.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/RuleDataSourceDaoImpl.java index de53f48b..0ee9cdea 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/RuleDataSourceDaoImpl.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/RuleDataSourceDaoImpl.java @@ -21,9 +21,11 @@ import com.webank.wedatasphere.qualitis.rule.entity.Rule; import com.webank.wedatasphere.qualitis.rule.entity.RuleDataSource; -import com.webank.wedatasphere.qualitis.rule.dao.RuleDataSourceDao; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Repository; import java.util.ArrayList; @@ -38,50 +40,76 @@ @Repository public class RuleDataSourceDaoImpl implements RuleDataSourceDao { - @Autowired - private RuleDataSourceRepository ruleDataSourceRepository; - - @Override - public List saveAllRuleDataSource(List ruleDataSources) { - return ruleDataSourceRepository.saveAll(ruleDataSources); - } - - @Override - public List findByRule(Rule rule) { - return ruleDataSourceRepository.findByRule(rule); - } - - @Override - public List findByProjectId(Long projectId) { - return ruleDataSourceRepository.findByProjectId(projectId); - } - - @Override - public List findByProjectUser(Long projectId, String cluster, String db, - String table) { - return ruleDataSourceRepository.findAll((root, query, cb) -> { - List predicates = new ArrayList<>(); - if (projectId != null) { - predicates.add(cb.equal(root.get("projectId"), projectId)); - } - if (StringUtils.isNotBlank(cluster)) { - predicates.add(cb.equal(root.get("clusterName"), cluster)); - } - if (StringUtils.isNotBlank(db)) { - predicates.add(cb.equal(root.get("dbName"), db)); - } - if (StringUtils.isNotBlank(table)) { - predicates.add(cb.equal(root.get("tableName"), table)); - } - Predicate[] p = new Predicate[predicates.size()]; - query.where(cb.and(predicates.toArray(p))); - - return query.getRestriction(); - }); - } - - @Override - public List> findProjectDsByUser(String user) { - return ruleDataSourceRepository.findProjectDsByUser(user); - } + @Autowired + private RuleDataSourceRepository ruleDataSourceRepository; + + @Override + public List saveAllRuleDataSource(List ruleDataSources) { + return ruleDataSourceRepository.saveAll(ruleDataSources); + } + + @Override + public List findByRule(Rule rule) { + return ruleDataSourceRepository.findByRule(rule); + } + + @Override + public List findByProjectId(Long projectId) { + return ruleDataSourceRepository.findByProjectId(projectId); + } + + @Override + public List findByProjectUser(Long projectId, String cluster, String db, + String table) { + return ruleDataSourceRepository.findAll((root, query, cb) -> { + List predicates = new ArrayList<>(); + if (projectId != null) { + predicates.add(cb.equal(root.get("projectId"), projectId)); + } + if (StringUtils.isNotBlank(cluster)) { + predicates.add(cb.equal(root.get("clusterName"), cluster)); + } + if (StringUtils.isNotBlank(db)) { + predicates.add(cb.equal(root.get("dbName"), db)); + } + if (StringUtils.isNotBlank(table)) { + predicates.add(cb.equal(root.get("tableName"), table)); + } + Predicate[] p = new Predicate[predicates.size()]; + query.where(cb.and(predicates.toArray(p))); + + return query.getRestriction(); + }); + } + + @Override + public List> findProjectDsByUser(String user) { + return ruleDataSourceRepository.findProjectDsByUser(user); + } + + @Override + public List> findProjectDsByUser(String user, int page, int size) { + Sort sort = new Sort(Sort.Direction.ASC, "clusterName", "dbName", "tableName"); + Pageable pageable = PageRequest.of(page, size, sort); + return ruleDataSourceRepository.findProjectDsByUser(user, pageable).getContent(); + } + + + @Override + public List findRuleByDataSource(String clusterName, String dbName, String tableName, String colName, String user) { + return ruleDataSourceRepository.findRuleByDataSource(clusterName, dbName, tableName, colName, user); + } + + @Override + public List> filterProjectDsByUser(String user, String clusterName, String dbName, String tableName) { + return ruleDataSourceRepository.filterProjectDsByUser(user, clusterName, dbName, tableName); + } + + @Override + public List> filterProjectDsByUserPage(String user, String clusterName, String dbName, String tableName, int page, int size) { + Sort sort = new Sort(Sort.Direction.ASC, "clusterName", "dbName", "tableName"); + Pageable pageable = PageRequest.of(page, size, sort); + return ruleDataSourceRepository.filterProjectDsByUser(user, clusterName, dbName, tableName, pageable).getContent(); + } + } diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/TemplateMidTableInputMetaDaoImpl.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/TemplateMidTableInputMetaDaoImpl.java index ac8814bd..95b90394 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/TemplateMidTableInputMetaDaoImpl.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/TemplateMidTableInputMetaDaoImpl.java @@ -20,8 +20,8 @@ import com.webank.wedatasphere.qualitis.rule.dao.repository.TemplateInputMetaRepository; import com.webank.wedatasphere.qualitis.rule.entity.Template; import com.webank.wedatasphere.qualitis.rule.entity.TemplateMidTableInputMeta; -import com.webank.wedatasphere.qualitis.rule.dao.TemplateMidTableInputMetaDao; -import com.webank.wedatasphere.qualitis.rule.dao.repository.TemplateInputMetaRepository; +import java.util.HashSet; +import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @@ -45,4 +45,16 @@ public List findByRuleTemplate(Template template) { public TemplateMidTableInputMeta findById(Long templateInputMetaId) { return templateInputMetaRepository.findById(templateInputMetaId).orElse(null); } + + @Override + public Set saveAll(List templateMidTableInputMetas) { + Set result = new HashSet<>(); + result.addAll(templateInputMetaRepository.saveAll(templateMidTableInputMetas)); + return result; + } + + @Override + public void deleteByTemplate(Template templateInDb) { + templateInputMetaRepository.deleteByTemplate(templateInDb); + } } diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/TemplateOutputMetaDaoImpl.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/TemplateOutputMetaDaoImpl.java index 8d14bf79..fab4f0e9 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/TemplateOutputMetaDaoImpl.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/impl/TemplateOutputMetaDaoImpl.java @@ -54,4 +54,11 @@ public TemplateOutputMeta saveTemplateOutputMeta(TemplateOutputMeta templateOutp public List findByTemplate(Template template) { return templateOutputMetaRepository.findByTemplate(template); } + + @Override + public void deleteByTemplate(Template templateInDb) { + templateOutputMetaRepository.deleteByTemplate(templateInDb); + } + + } diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/repository/RuleDataSourceRepository.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/repository/RuleDataSourceRepository.java index ac2f143e..d61b80e9 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/repository/RuleDataSourceRepository.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/repository/RuleDataSourceRepository.java @@ -19,6 +19,8 @@ import com.webank.wedatasphere.qualitis.rule.entity.Rule; import com.webank.wedatasphere.qualitis.rule.entity.RuleDataSource; import com.webank.wedatasphere.qualitis.rule.entity.RuleDataSource; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; @@ -37,11 +39,11 @@ public interface RuleDataSourceRepository extends JpaRepository findByRule(Rule rule); /** @@ -51,11 +53,55 @@ public interface RuleDataSourceRepository extends JpaRepository findByProjectId(Long projectId); - /** - * Find rule datasource by user - * @param user - * @return - */ - @Query(value = "select new map(ds.clusterName as cluster_name, ds.dbName as db_name, ds.tableName as table_name) from RuleDataSource ds, ProjectUser u where ds.projectId = u.project and u.userName = ?1 group by ds.clusterName, ds.dbName, ds.tableName") - List> findProjectDsByUser(String user); + /** + * Find rule datasource by user + * @param user + * @return + */ + @Query(value = "select new map(ds.clusterName as cluster_name, ds.dbName as db_name, ds.tableName as table_name) from RuleDataSource ds, ProjectUser u where ds.projectId = u.project and u.userName = ?1 group by ds.clusterName, ds.dbName, ds.tableName") + List> findProjectDsByUser(String user); + + /** + * Paging query rule data source + * @param user + * @param pageable + * @return + */ + @Query(value = "select new map(ds.clusterName as cluster_name, ds.dbName as db_name, ds.tableName as table_name) from RuleDataSource ds, ProjectUser u where ds.projectId = u.project and u.userName = ?1 group by ds.clusterName, ds.dbName, ds.tableName") + Page> findProjectDsByUser(String user, Pageable pageable); + + /** + * Find rules related with cluster name, database name ,table name, column name. + * @param clusterName + * @param dbName + * @param tableName + * @param colName + * @param user + * @return + */ + @Query(value = "select ds.rule from RuleDataSource ds, ProjectUser u where ds.clusterName = ?1 and ds.dbName = ?2 and ds.tableName = ?3 and ds.colName like ?4 and ds.projectId = u.project and u.userName = ?5") + List findRuleByDataSource(String clusterName, String dbName, String tableName, String colName, String user); + + /** + * Filter rule datasource + * @param user + * @param clusterName + * @param dbName + * @param tableName + * @return + */ + @Query(value = "select new map(ds.clusterName as cluster_name, ds.dbName as db_name, ds.tableName as table_name) from RuleDataSource ds, ProjectUser u where ds.projectId = u.project and u.userName = ?1 and ds.clusterName like ?2 and ds.dbName like ?3 and ds.tableName like ?4 group by ds.clusterName, ds.dbName, ds.tableName") + List> filterProjectDsByUser(String user, String clusterName, String dbName, String tableName); + + /** + * Filter rule datasource pageable. + * @param user + * @param clusterName + * @param dbName + * @param tableName + * @param pageable + * @return + */ + @Query(value = "select new map(ds.clusterName as cluster_name, ds.dbName as db_name, ds.tableName as table_name) from RuleDataSource ds, ProjectUser u where ds.projectId = u.project and u.userName = ?1 and ds.clusterName like ?2 and ds.dbName like ?3 and ds.tableName like ?4 group by ds.clusterName, ds.dbName, ds.tableName") + Page> filterProjectDsByUser(String user, String clusterName, String dbName, String tableName, Pageable pageable); } diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/repository/RuleRepository.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/repository/RuleRepository.java index 0f4a88fa..d699a63f 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/repository/RuleRepository.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/repository/RuleRepository.java @@ -20,6 +20,7 @@ import com.webank.wedatasphere.qualitis.rule.entity.Rule; import com.webank.wedatasphere.qualitis.rule.entity.RuleGroup; import com.webank.wedatasphere.qualitis.rule.entity.RuleGroup; +import com.webank.wedatasphere.qualitis.rule.entity.Template; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; @@ -42,4 +43,11 @@ public interface RuleRepository extends JpaRepository { * @return */ List findByRuleGroup(RuleGroup ruleGroup); + + /** + * Find rule by rule template + * @param templateInDb + * @return + */ + List findByTemplate(Template templateInDb); } diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/repository/TemplateInputMetaRepository.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/repository/TemplateInputMetaRepository.java index 295dd13d..30b1d81b 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/repository/TemplateInputMetaRepository.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/dao/repository/TemplateInputMetaRepository.java @@ -42,4 +42,9 @@ public interface TemplateInputMetaRepository extends JpaRepository { + + /** + * Delete statistics input meta by template. + * @param templateInDb + */ + void deleteByTemplate(Template templateInDb); } diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/AlarmConfig.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/AlarmConfig.java index d9d1345d..6120d81d 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/AlarmConfig.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/AlarmConfig.java @@ -16,6 +16,8 @@ package com.webank.wedatasphere.qualitis.rule.entity; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import javax.persistence.*; import java.util.Objects; @@ -23,6 +25,7 @@ * @author howeye */ @Entity +@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") @Table(name = "qualitis_rule_alarm_config") public class AlarmConfig { diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/Rule.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/Rule.java index cd6b1669..d22a4c3b 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/Rule.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/Rule.java @@ -16,17 +16,21 @@ package com.webank.wedatasphere.qualitis.rule.entity; -import com.webank.wedatasphere.qualitis.project.entity.Project; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import com.webank.wedatasphere.qualitis.project.entity.Project; import javax.persistence.*; import java.util.Objects; import java.util.Set; +import org.codehaus.jackson.annotate.JsonIgnore; /** * @author howeye */ @Entity +@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") @Table(name = "qualitis_rule", uniqueConstraints = @UniqueConstraint(columnNames = {"project_id", "name"})) public class Rule { @@ -35,14 +39,18 @@ public class Rule { private Long id; @ManyToOne + @JsonIgnore private Template template; + @Column(length = 170) private String name; @OneToMany(mappedBy = "rule", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) + @JsonIgnore private Set ruleDataSources; @OneToMany(mappedBy = "rule", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) + @JsonIgnore private Set ruleDataSourceMappings; @Column(name = "alarm") @@ -52,18 +60,23 @@ public class Rule { private Integer ruleType; @OneToMany(mappedBy = "rule", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) + @JsonIgnore private Set alarmConfigs; @OneToMany(mappedBy = "rule", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) + @JsonIgnore private Set ruleVariables; @OneToOne(mappedBy = "parentRule", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) + @JsonIgnore private Rule childRule; @OneToOne(fetch = FetchType.EAGER) + @JsonIgnore private Rule parentRule; @ManyToOne + @JsonIgnore private Project project; @Column(name = "rule_template_name", length = 180, updatable = false) @@ -80,7 +93,11 @@ public class Rule { @Column(name = "output_name", length = 170) private String outputName; + @Column(name = "abort_on_failure") + private Boolean abortOnFailure; + @ManyToOne + @JsonIgnore private RuleGroup ruleGroup; public Rule() { @@ -239,6 +256,14 @@ public void setRuleGroup(RuleGroup ruleGroup) { this.ruleGroup = ruleGroup; } + public Boolean getAbortOnFailure() { + return abortOnFailure; + } + + public void setAbortOnFailure(Boolean abortOnFailure) { + this.abortOnFailure = abortOnFailure; + } + @Override public boolean equals(Object o) { if (this == o) {return true;} diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleDataSource.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleDataSource.java index babdbbb8..bcd1e15e 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleDataSource.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleDataSource.java @@ -16,6 +16,8 @@ package com.webank.wedatasphere.qualitis.rule.entity; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import javax.persistence.*; import java.util.Objects; @@ -23,6 +25,7 @@ * @author howeye */ @Entity +@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") @Table(name = "qualitis_rule_datasource") public class RuleDataSource { diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleDataSourceMapping.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleDataSourceMapping.java index ac57019d..ee74f2ce 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleDataSourceMapping.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleDataSourceMapping.java @@ -16,6 +16,8 @@ package com.webank.wedatasphere.qualitis.rule.entity; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import javax.persistence.*; import java.util.Objects; @@ -23,6 +25,7 @@ * @author howeye */ @Entity +@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") @Table(name = "qualitis_rule_datasource_mapping") public class RuleDataSourceMapping { diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleGroup.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleGroup.java index b8e420b6..1cf3ac55 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleGroup.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleGroup.java @@ -16,6 +16,8 @@ package com.webank.wedatasphere.qualitis.rule.entity; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import javax.persistence.*; import java.util.List; @@ -23,6 +25,7 @@ * @author howeye */ @Entity +@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") @Table(name = "qualitis_rule_group") public class RuleGroup { diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleVariable.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleVariable.java index ca313627..02bec8c5 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleVariable.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/RuleVariable.java @@ -16,6 +16,8 @@ package com.webank.wedatasphere.qualitis.rule.entity; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import javax.persistence.*; import java.util.Map; import java.util.Objects; @@ -24,6 +26,7 @@ * @author howeye */ @Entity +@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") @Table(name = "qualitis_rule_variable") public class RuleVariable { diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/Template.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/Template.java index fb666f7f..6da71099 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/Template.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/Template.java @@ -16,13 +16,17 @@ package com.webank.wedatasphere.qualitis.rule.entity; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import javax.persistence.*; import java.util.Set; +import org.codehaus.jackson.annotate.JsonIgnore; /** * @author howeye */ @Entity +@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") @Table(name = "qualitis_template") public class Template { @@ -50,7 +54,9 @@ public class Template { private String midTableAction; @Column(name = "save_mid_table") private Boolean saveMidTable; + @OneToMany(mappedBy = "template", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) + @JsonIgnore private Set statisticAction; @Column(name = "show_sql", length = 5000) @@ -69,15 +75,19 @@ public class Template { private Integer actionType; @OneToMany(mappedBy = "template", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) + @JsonIgnore private Set templateMidTableInputMetas; @OneToMany(mappedBy = "template", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) + @JsonIgnore private Set templateOutputMetas; @OneToOne + @JsonIgnore private Template parentTemplate; @OneToOne(mappedBy = "parentTemplate", fetch = FetchType.EAGER) + @JsonIgnore private Template childTemplate; public Template() { diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/TemplateMidTableInputMeta.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/TemplateMidTableInputMeta.java index 723d82bc..aca5ed64 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/TemplateMidTableInputMeta.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/TemplateMidTableInputMeta.java @@ -16,6 +16,8 @@ package com.webank.wedatasphere.qualitis.rule.entity; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import javax.persistence.*; import java.util.Objects; import java.util.Set; @@ -24,6 +26,7 @@ * @author howeye */ @Table +@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") @Entity(name = "qualitis_template_mid_table_input_meta") public class TemplateMidTableInputMeta { diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/TemplateOutputMeta.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/TemplateOutputMeta.java index 401d5fab..fdaee794 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/TemplateOutputMeta.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/TemplateOutputMeta.java @@ -16,6 +16,9 @@ package com.webank.wedatasphere.qualitis.rule.entity; +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import javax.persistence.*; import java.util.Objects; @@ -23,6 +26,7 @@ * @author howeye */ @Entity +@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") @Table(name = "qualitis_template_output_meta") public class TemplateOutputMeta { @@ -31,6 +35,7 @@ public class TemplateOutputMeta { private Long id; @ManyToOne + @JsonBackReference private Template template; @Column(length = 150, name = "output_name", updatable = false) diff --git a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/TemplateStatisticsInputMeta.java b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/TemplateStatisticsInputMeta.java index 043a1707..86adfb4b 100644 --- a/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/TemplateStatisticsInputMeta.java +++ b/core/project/src/main/java/com/webank/wedatasphere/qualitis/rule/entity/TemplateStatisticsInputMeta.java @@ -16,6 +16,9 @@ package com.webank.wedatasphere.qualitis.rule.entity; +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import javax.persistence.*; import java.util.Objects; @@ -23,6 +26,7 @@ * @author howeye */ @Entity +@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") @Table(name = "qualitis_template_statistic_input_meta") public class TemplateStatisticsInputMeta { diff --git a/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/client/AbstractJobSubmitter.java b/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/client/AbstractJobSubmitter.java index 17aa0891..361f6aca 100644 --- a/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/client/AbstractJobSubmitter.java +++ b/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/client/AbstractJobSubmitter.java @@ -22,12 +22,6 @@ import com.webank.wedatasphere.qualitis.exception.TaskNotExistException; import com.webank.wedatasphere.qualitis.exception.JobSubmitException; import com.webank.wedatasphere.qualitis.exception.LogPartialException; -import com.webank.wedatasphere.qualitis.exception.ClusterInfoNotConfigException; -import com.webank.wedatasphere.qualitis.exception.LogPartialException; -import com.webank.wedatasphere.qualitis.bean.JobSubmitResult; -import com.webank.wedatasphere.qualitis.bean.LogResult; -import com.webank.wedatasphere.qualitis.exception.JobSubmitException; -import com.webank.wedatasphere.qualitis.exception.TaskNotExistException; /** * The function of submitter is to submit job, get task status and get task log diff --git a/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/client/LinkisJobSubmitter.java b/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/client/LinkisJobSubmitter.java index 15fbf6a0..57b1a067 100644 --- a/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/client/LinkisJobSubmitter.java +++ b/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/client/LinkisJobSubmitter.java @@ -27,11 +27,6 @@ import com.webank.wedatasphere.qualitis.exception.JobSubmitException; import com.webank.wedatasphere.qualitis.exception.LogPartialException; import com.webank.wedatasphere.qualitis.exception.TaskNotExistException; -import com.webank.wedatasphere.qualitis.bean.JobSubmitResult; -import com.webank.wedatasphere.qualitis.bean.LogResult; -import com.webank.wedatasphere.qualitis.config.LinkisConfig; -import com.webank.wedatasphere.qualitis.exception.JobSubmitException; -import com.webank.wedatasphere.qualitis.exception.TaskNotExistException; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -84,11 +79,11 @@ public JobSubmitResult submitJob(String code, String user, String remoteAddress, headers.add("Token-Code", getToken(clusterName)); Map map = new HashMap<>(4); - map.put("requestApplicationName", "qualitis"); + // TODO:recover qualitis + map.put("requestApplicationName", linkisConfig.getAppName()); map.put("executeApplicationName", "spark"); map.put("executionCode", code); map.put("runType", "scala"); - map.put("params", new Object()); Gson gson = new Gson(); HttpEntity entity = new HttpEntity<>(gson.toJson(map), headers); LOGGER.info("Start to submit job to linkis. url: {}, method: {}, body: {}", url, javax.ws.rs.HttpMethod.POST, entity); @@ -232,7 +227,8 @@ private Map getTaskDetail(Integer taskId, String user, String ujesAddress, Strin throw new TaskNotExistException("Can not get status of task, task_id : " + taskId); } - if (((Map)response.get("data")).get("task") == null) { + Object taskObj = ((Map)response.get("data")).get("task"); + if (taskObj == null) { throw new TaskNotExistException("Job id: " + taskId + " does not exist"); } diff --git a/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/config/LinkisConfig.java b/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/config/LinkisConfig.java index 50aadaf8..07cc75ac 100644 --- a/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/config/LinkisConfig.java +++ b/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/config/LinkisConfig.java @@ -48,9 +48,17 @@ public class LinkisConfig { @Value("${linkis.api.meta_data.table_path}") private String tablePath; + @Value("${linkis.api.meta_data.table_comment}") + private String tableComment; @Value("${linkis.api.meta_data.column_path}") private String columnPath; + @Value("${linkis.api.meta_data.column_info}") + private String columnInfo; + + @Value("${linkis.spark.application.name}") + private String appName; + public String getPrefix() { return prefix; @@ -116,6 +124,14 @@ public void setTablePath(String tablePath) { this.tablePath = tablePath; } + public String getTableComment() { + return tableComment; + } + + public void setTableComment(String tableComment) { + this.tableComment = tableComment; + } + public String getColumnPath() { return columnPath; } @@ -123,4 +139,21 @@ public String getColumnPath() { public void setColumnPath(String columnPath) { this.columnPath = columnPath; } + + public String getColumnInfo() { + return columnInfo; + } + + public void setColumnInfo(String columnInfo) { + this.columnInfo = columnInfo; + } + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + } + } diff --git a/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/config/ZkConfig.java b/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/config/ZkConfig.java index 7f6c3fef..e58ca52b 100644 --- a/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/config/ZkConfig.java +++ b/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/config/ZkConfig.java @@ -17,12 +17,14 @@ package com.webank.wedatasphere.qualitis.config; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Configuration; /** * @author howeye */ @Configuration +@ConditionalOnProperty(name = "ha.enable", havingValue = "true") public class ZkConfig { @Value("${zk.address}") diff --git a/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/submitter/impl/ExecutionManagerImpl.java b/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/submitter/impl/ExecutionManagerImpl.java index f660ca30..15e3bb2a 100644 --- a/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/submitter/impl/ExecutionManagerImpl.java +++ b/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/submitter/impl/ExecutionManagerImpl.java @@ -86,7 +86,6 @@ public class ExecutionManagerImpl implements ExecutionManager { @Override public List submitApplication(String applicationId, List rules, String createTime, String user, String database, String partition, Date date, Application application) throws ArgumentException, TaskTypeException, ConvertException, DataQualityTaskException, RuleVariableNotSupportException, RuleVariableNotFoundException, JobSubmitException, ClusterInfoNotConfigException, ExecutionException, InterruptedException { - // Check if cluster supported LOGGER.info("Start to collect rule to clusters"); Map> clusterNameMap = getRuleCluster(rules); @@ -149,6 +148,14 @@ private void saveDividedTask(List dataQualityTasks, ClusterInfo for (DataQualityTask dataQualityTask : dataQualityTasks) { List ruleList = getRule(rules, dataQualityTask); Task task = new Task(application, createTime, TaskStatusEnum.SUBMITTED.getCode(), clusterInfo.getClusterName(), clusterInfo.getLinkisAddress()); + Boolean abortOnFailure = false; + for (Rule rule : rules) { + if (rule.getAbortOnFailure()) { + abortOnFailure = true; + break; + } + } + task.setAbortOnFailure(abortOnFailure); Task taskInDb = taskDao.save(task); LOGGER.info("Succeed to save task. task_id: {}", taskInDb.getId()); saveJobRuleSimpleAndJobDataSource(ruleList, taskInDb); diff --git a/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/zk/ZookeeperCuratorManager.java b/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/zk/ZookeeperCuratorManager.java deleted file mode 100644 index 94f016bc..00000000 --- a/core/scheduler/src/main/java/com/webank/wedatasphere/qualitis/zk/ZookeeperCuratorManager.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2019 WeBank - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.webank.wedatasphere.qualitis.zk; - -import com.webank.wedatasphere.qualitis.config.ZkConfig; -import org.apache.curator.RetryPolicy; -import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.CuratorFrameworkFactory; -import org.apache.curator.retry.ExponentialBackoffRetry; -import org.apache.curator.utils.CloseableUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * @author howeye - */ -@Component -public class ZookeeperCuratorManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(ZookeeperCuratorManager.class); - - @Autowired - private ZkConfig zkConfig; - - public CuratorFramework createClient() { - Integer baseSleepTimeMs = zkConfig.getBaseSleepTimeMs(); - Integer maxRetries = zkConfig.getMaxRetries(); - Integer sessionTimeOutMs = zkConfig.getSessionTimeOutMs(); - Integer connectionTimeOutMs = zkConfig.getConnectionTimeOutMs(); - - RetryPolicy retryPolicy = new ExponentialBackoffRetry(baseSleepTimeMs, maxRetries); - CuratorFramework client = CuratorFrameworkFactory.newClient(zkConfig.getZkAddress(), sessionTimeOutMs, connectionTimeOutMs, retryPolicy); - - LOGGER.info("Start to create zookeeper connection., url: {}", zkConfig.getZkAddress()); - client.start(); - LOGGER.info("Succeed to create zookeeper connection. url: {}", zkConfig.getZkAddress()); - return client; - } - - public void closeClient(CuratorFramework client) { - CloseableUtils.closeQuietly(client); - } - -} diff --git a/core/task/src/main/java/com/webank/wedatasphere/qualitis/constant/AlarmConfigStatusEnum.java b/core/task/src/main/java/com/webank/wedatasphere/qualitis/constant/AlarmConfigStatusEnum.java index 5a8c0707..e9f03ea3 100644 --- a/core/task/src/main/java/com/webank/wedatasphere/qualitis/constant/AlarmConfigStatusEnum.java +++ b/core/task/src/main/java/com/webank/wedatasphere/qualitis/constant/AlarmConfigStatusEnum.java @@ -19,7 +19,7 @@ /** * @author howeye */ -public enum AlarmConfigStatusEnum { +public enum AlarmConfigStatusEnum { /** * 1 Pass verification,2 Not pass verification, 3 Not verified */ diff --git a/core/task/src/main/java/com/webank/wedatasphere/qualitis/entity/Task.java b/core/task/src/main/java/com/webank/wedatasphere/qualitis/entity/Task.java index 39ce24c6..a755f1f5 100644 --- a/core/task/src/main/java/com/webank/wedatasphere/qualitis/entity/Task.java +++ b/core/task/src/main/java/com/webank/wedatasphere/qualitis/entity/Task.java @@ -55,6 +55,9 @@ public class Task { @Column(name = "submit_address") private String submitAddress; + @Column(name = "abort_on_failure") + private Boolean abortOnFailure; + public Task() { } @@ -148,6 +151,14 @@ public void setSubmitAddress(String submitAddress) { this.submitAddress = submitAddress; } + public Boolean isAbortOnFailure() { + return abortOnFailure; + } + + public void setAbortOnFailure(Boolean abortOnFailure) { + this.abortOnFailure = abortOnFailure; + } + @Override public boolean equals(Object o) { if (this == o) {return true;} diff --git a/docs/en_US/ch1/QuickDeploy.md b/docs/en_US/ch1/QuickDeploy.md index d94eaebe..bf1f8887 100644 --- a/docs/en_US/ch1/QuickDeploy.md +++ b/docs/en_US/ch1/QuickDeploy.md @@ -8,7 +8,7 @@ Hadoop (2.7.2) Hive (1.2.1) Zookeeper (3.4.9) Linkis (0.9.1), Spark engine required.[How to install Linkis?](https://github.com/WeBankFinTech/Linkis) -DataSphereStudio (0.6.0) Optional. If you want to use workflow, it it required. [How to install DataSphereStudio?](https://github.com/WeBankFinTech/DataSphereStudio) +DataSphereStudio (0.6.0) Optional. If you want to use workflow, it it required. [How to install DataSphereStudio?](https://github.com/WeBankFinTech/DataSphereStudio) ## 2. Download [Download](https://github.com/WeBankFinTech/Qualitis/releases) diff --git a/docs/zh_CN/ch1/README.md b/docs/zh_CN/ch1/README.md index e9af5048..d34ca3e0 100644 --- a/docs/zh_CN/ch1/README.md +++ b/docs/zh_CN/ch1/README.md @@ -12,8 +12,8 @@ Qualitis基于Spring Boot,依赖于Linkis进行数据计算,提供数据质 支持以下数据模型定义: 1.单表校验数据模型。 2.跨表校验数据模型。 -3.自定义校验数据模型。 -
同时,系统预置了多个数据质量校验模版,包括空值校验,枚举校验等常用校验,并且支持自定义数据质量模版。 +3.自定义校验数据模型。 +
同时,系统预置了多个数据质量校验模版,包括空值校验,枚举校验等常用校验,并且支持自定义规则生成数据质量模版,单表数据质量模板以及跨表数据质量模板的定义。 - **数据质量模型调度** 支持数据质量模型调度。 @@ -32,15 +32,16 @@ Qualitis基于Spring Boot,依赖于Linkis进行数据计算,提供数据质 工作流必装[DataSphereStudio](https://github.com/WeBankFinTech/Linkis). - **管理员控制台** -提供管理员控制台界面,支持人员管理,权限管理,权限管理,元数据管理等管理功能。 +提供管理员控制台界面,支持人员管理,权限管理,元数据管理,系统参数配置等管理功能。 ## 与类似系统对比 ![](../../../images/zh_CN/ch1/相似系统对比图.png) ## 文档列表 +[架构设计文档](架构设计文档.md) [快速搭建手册](快速搭建手册.md) [用户手册](用户手册.md) -[架构设计文档](架构设计文档.md) +
## Architecture diff --git "a/docs/zh_CN/ch1/\345\215\207\347\272\247\346\214\207\345\215\227.md" "b/docs/zh_CN/ch1/\345\215\207\347\272\247\346\214\207\345\215\227.md" index d0b31997..cdbad2a6 100644 --- "a/docs/zh_CN/ch1/\345\215\207\347\272\247\346\214\207\345\215\227.md" +++ "b/docs/zh_CN/ch1/\345\215\207\347\272\247\346\214\207\345\215\227.md" @@ -10,10 +10,19 @@ source conf/database/update/update_0.5.0-0.6.0.sql ``` ## 0.6.0 升级 0.7.0 -下载0.6.0版本代码,并解压。 +下载0.7.0版本代码,并解压。 执行以下数据库脚本: ``` mysql -u {USERNAME} -p {PASSWORD} -h {IP} --default-character-set=utf8 source conf/database/update/update_0.6.0-0.7.0.sql +``` + +## 0.7.0 升级 0.8.0 +下载0.8.0版本代码,并解压。 + +执行以下数据库脚本: +``` +mysql -u {USERNAME} -p {PASSWORD} -h {IP} --default-character-set=utf8 +source conf/database/update/update_0.7.0-0.8.0.sql ``` \ No newline at end of file diff --git "a/docs/zh_CN/ch1/\345\277\253\351\200\237\346\220\255\345\273\272\346\211\213\345\206\214.md" "b/docs/zh_CN/ch1/\345\277\253\351\200\237\346\220\255\345\273\272\346\211\213\345\206\214\342\200\224\342\200\224HA\347\211\210.md" similarity index 93% rename from "docs/zh_CN/ch1/\345\277\253\351\200\237\346\220\255\345\273\272\346\211\213\345\206\214.md" rename to "docs/zh_CN/ch1/\345\277\253\351\200\237\346\220\255\345\273\272\346\211\213\345\206\214\342\200\224\342\200\224HA\347\211\210.md" index 0a38b3a1..b119438f 100644 --- "a/docs/zh_CN/ch1/\345\277\253\351\200\237\346\220\255\345\273\272\346\211\213\345\206\214.md" +++ "b/docs/zh_CN/ch1/\345\277\253\351\200\237\346\220\255\345\273\272\346\211\213\345\206\214\342\200\224\342\200\224HA\347\211\210.md" @@ -3,10 +3,8 @@ ## 一、基础软件安装 Gradle (4.9) MySQL (5.5+) -JDK (1.8.0_141) -Hadoop (2.7.2) -Hive (1.2.1) -Zookeeper (3.4.9) +JDK (1.8.0_141) +Zookeeper (3.4.9) Linkis(0.9.1), 必装Spark引擎。[如何安装Linkis](https://github.com/WeBankFinTech/Linkis) DataSphereStudio (0.6.0) 可选. 如果你想使用工作流,必装DataSphereStudio [如何安装DataSphereStudio?](https://github.com/WeBankFinTech/DataSphereStudio) @@ -52,9 +50,17 @@ task.persistence.username= task.persistence.password= task.persistence.address= -## Zookeeper地址 +## zk配置 zk.address= ``` +并打开HA开关 +``` +vim conf/application.yml +``` +开启HA: +``` +ha.enable=true +``` ### 4.4 启动系统 ``` @@ -76,7 +82,7 @@ sh bin/start.sh 填入以下配置信息: 集群名称(Hadoop集群名称) 集群类型 -Linkis地址(linkis gateway的ip和端口) +Linkis地址 Linkis Token(Linkis Token配置方式请查看文档:[接入Linkis文档](接入Linkis文档.md)) 可参考以下例子: @@ -107,4 +113,4 @@ Debug模式已默认开启,默认端口是8091。 ``` -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8091 ``` -如果是在编译好的代码中,可以通过编辑'bin/qualitis'文件,来关闭Debug模式。 +如果是在编译好的代码中,可以通过编辑'bin/qualitis'文件,来关闭Debug模式。 \ No newline at end of file diff --git "a/docs/zh_CN/ch1/\345\277\253\351\200\237\346\220\255\345\273\272\346\211\213\345\206\214\342\200\224\342\200\224\345\215\225\346\234\272\347\211\210.md" "b/docs/zh_CN/ch1/\345\277\253\351\200\237\346\220\255\345\273\272\346\211\213\345\206\214\342\200\224\342\200\224\345\215\225\346\234\272\347\211\210.md" new file mode 100644 index 00000000..b86b8e7f --- /dev/null +++ "b/docs/zh_CN/ch1/\345\277\253\351\200\237\346\220\255\345\273\272\346\211\213\345\206\214\342\200\224\342\200\224\345\215\225\346\234\272\347\211\210.md" @@ -0,0 +1,104 @@ +# 快速搭建手册 + +## 一、基础软件安装 +Gradle (4.9) +MySQL (5.5+) +JDK (1.8.0_141) +Linkis(0.9.1), 必装Spark引擎。[如何安装Linkis](https://github.com/WeBankFinTech/Linkis) +DataSphereStudio (0.7.0) 可选. 如果你想使用工作流,必装DataSphereStudio [如何安装DataSphereStudio?](https://github.com/WeBankFinTech/DataSphereStudio) + +## 二、安装包下载 +[下载](https://github.com/WeBankFinTech/Qualitis/releases) + +## 三、编译(二进制包跳过) +``` +gradle clean distZip +``` + +## 四、部署 +### 4.1 解压安装包 +##### zip包 +``` +unzip qualitis-{version}.zip +``` + +##### tar包 +``` +tar -zxvf qualitis-{VERSION}.tar.gz +``` + +### 4.2 连接MySQL,插入初始数据。 +``` +mysql -u {USERNAME} -p {PASSWORD} -h {IP} --default-character-set=utf8 +source conf/database/init.sql +``` + +### 4.3 修改配置文件 +``` +vim conf/application-dev.yml +``` +修改以下配置: +``` +## 数据库配置 +spring.datasource.username= +spring.datasource.password= +spring.datasource.url= + +## 数据库配置,和以上一致 +task.persistence.username= +task.persistence.password= +task.persistence.address= +``` + +### 4.4 启动系统 +``` +dos2unix bin/* +sh bin/start.sh +``` + +## 五、登录 +### 5.1 登录验证 +浏览器中输入localhost:8090, 出现一下页面说明启动成功 +![登录验证图片](../../../images/zh_CN/ch1/登录.png) +输入 +用户名: admin +密码: admin + +### 5.2 系统配置填写 +点击系统配置 -> 参数配置,并新增集群 +![系统配置](../../../images/zh_CN/ch1/系统配置.png) +填入以下配置信息: +集群名称(Hadoop集群名称) +集群类型 +Linkis地址 +Linkis Token(Linkis Token配置方式请查看文档:[接入Linkis文档](接入Linkis文档.md)) + +可参考以下例子: +![](../../../images/zh_CN/ch1/规则配置样例.png) + +--- + +Tips: + +Qualitis会将异常数据保存在数据库当中,保存的数据库名称可以在系统设置中配置,如下图所示: +![](../../../images/zh_CN/ch1/异常数据数据库配置.png) +如图所示,Qualitis提供${USERNAME}来作为用户名替换的表达式,不同的用户跑出来的异常数据,保存在各自的数据库中。 + +--- + +工作流已默认开启,工作流需要安装[DataSphereStudio](https://github.com/WeBankFinTech/DataSphereStudio)。 +开启工作流不影响Qualitis正常使用。 +如需关闭,可修改配置文件 +``` +vim conf/application.yml +``` +并修改workflow.enable=false + +--- + +Debug模式已默认开启,默认端口是8091。 +在源码中,你可以通过在'build.gradle'文件中删除以下代码,关闭Debug模式。 +``` +-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8091 +``` +如果是在编译好的代码中,可以通过编辑'bin/qualitis'文件,来关闭Debug模式。 \ No newline at end of file diff --git "a/docs/zh_CN/ch1/\347\224\250\346\210\267\346\211\213\345\206\214.md" "b/docs/zh_CN/ch1/\347\224\250\346\210\267\346\211\213\345\206\214.md" index c9e89639..75c29083 100644 --- "a/docs/zh_CN/ch1/\347\224\250\346\210\267\346\211\213\345\206\214.md" +++ "b/docs/zh_CN/ch1/\347\224\250\346\210\267\346\211\213\345\206\214.md" @@ -13,11 +13,14 @@ Qualitis是一个数据质量管理系统,用于监控数据质量。其功能 点击页面左上方的新增项目,弹出新增项目界面。 ![新增项目图片](../../../images/zh_CN/ch1/新增项目图片.png) 填入 + ##### 1)项目名称 项目的名称,不能重复。 ##### 2)项目介绍 对该项目的简单介绍。 -点击保存,即可创建一个新项目。 +##### 3)项目标签 +可以指定项目的标签,非必选。 +点击确定,即可创建一个新项目。 ## 四、创建规则 保存项目之后,左下角可以创建规则。可以新建单表规则,自定义规则以及跨表规则。 @@ -42,10 +45,10 @@ Qualitis是一个数据质量管理系统,用于监控数据质量。其功能 |${yyyyMMddHH}[-N(可选)]|2018年12月17号15点|2018121715(前N天)只减天数| |${yyyy/MM/dd}[-N(可选)]|2018年12月17号|2018/12/17(前N天)| -##### 4)是否告警 -如果不进行告警,不会监控任务的输出结果。 +##### 4)是否校验 +如果不进行校验,不会监控任务的输出结果。 -如果选择告警,并在其中选择监控的输出结果,并设定监控的阈值,当结果超出告警阈值的时候,任务就是不通过校验的状态。 +如果选择校验,并在其中选择监控的输出结果,并设定校验的阈值,当结果超出校验阈值的时候,任务就是不通过校验的状态。 比较运行结果和阈值的方式有以下四种:(假设设定的阈值为x,本次任务的运行结果为r) @@ -63,6 +66,7 @@ Qualitis是一个数据质量管理系统,用于监控数据质量。其功能 ![](../../../images/zh_CN/ch1/新增自定义技术规则.png) 点击新增自定义技术规则,进入新增自定义技术规则页面。 填入 + ##### 1)规则名称 技术规则的名称,不可重复。 ##### 2)输出的校验规则 @@ -72,9 +76,11 @@ Qualitis是一个数据质量管理系统,用于监控数据质量。其功能 ##### 4)集群 选择提交任务的集群 ##### 5)保存不符合数据校验的结果 -如果勾选,则会将没通过校验的数据提取出来并保存,否则不会保存 +如果勾选,则会将没通过校验的数据提取出来并保存,否则不会保存; + +将要执行的SQL语句会在预览中显示; -将要执行的SQL语句会在预览中显示。 +自定义技术规则会生成自定义的规则模板。 ### 4.3 跨表规则创建示例 ![](../../../images/zh_CN/ch1/新增跨表技术规则.png) @@ -82,7 +88,7 @@ Qualitis是一个数据质量管理系统,用于监控数据质量。其功能 跨表技术规则能选择同一个集群中两张表,并对两张表进行数据校验。 -跨表技术规则目前提供以下两种模版: +跨表技术规则目前提供以下两种默认模版,: - 准确性校验 准确性校验可以比较两个表之间,所选字段的数据记录的准确性差异性。 - 通用校验 @@ -127,7 +133,277 @@ B表 规则纬度则是挑选规则进行任务执行。执行方式如下图所示: ![规则纬度执行任务](../../../images/zh_CN/ch1/规则纬度执行任务.png) -## 六、任务查看 +## 六、规则查询介绍 +在“规则查询”界面,提供了以数据源为索引,查看与之关联规则的功能。首先会分页展示所有关联了现有规则的数据源,信息如下: +![规则查询首页](../../../images/zh_CN/ch1/规则查询首页.png) + +上方是对数据源的精确筛选和对表名的模糊筛选,分页显示满足筛选条件的数据源: +![规则查询筛选](../../../images/zh_CN/ch1/规则查询筛选.png) + +点击具体的表名,则进入表详情界面,可以看到具体的列信息: +![表列详情](../../../images/zh_CN/ch1/表列详情.png) +点击关联规则管理,右侧弹出关联规则页面,会展示该列进行校验的规则列表,同样在这里有规则的执行,导出和批量删除操作: +![列关联规则详情](../../../images/zh_CN/ch1/列关联规则详情.png) + +## 七、规则模板配置介绍 +以下例子均以Cluster0002集群,allenzhou_ind库,test_table表为例。假设该表结构如下: + +|字段名称|字段类型| +| ------------ | ------------ | +|key|int| +|value|string| +|ds|string(一级分区)| +|day|string| + + ### 7.1 空值检测 + 语义: + 指定一个表中的某一个字段,检测出该字段为空的记录条数。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,value字段为空的记录条数。 + + 配置: + 首先选择空值检测模版。 + 选择希望检测的集群,库名,表名,字段,并填入分区过滤条件,如下图所示: + + ![空值检测模板](../../../images/zh_CN/ch1/空值检测模板.png) + + 可以在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.2 主键检测 + 语义: + 指定一个表中的多个字段,检测这些字段的组合在该表中是否具有唯一性。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,key字段是否具有唯一性。 + + 配置: + 首先选择主键检测模版。 + 选择希望检测的集群,库名,表名,字段,并填入分区过滤条件,如下图所示: + + ![主键检测模板](../../../images/zh_CN/ch1/主键检测模板.png) + + 可以在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.3 表行数检测 + 语义: + 指定一个表,检测该表的行数是否达到预期。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,记录条数为多少。 + + 配置: + 首先选择表行数检测模版。 + 选择希望检测的集群,库名,表名,字段,并填入分区过滤条件,如下图所示: + + ![表行数检测模板](../../../images/zh_CN/ch1/表行数检测模板.png) + + 可以在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.4 平均值检测 + 语义: + 指定一个表中一个字段,检测该字段的平均值是否达到预期。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,key字段的平均值为多少。 + + 配置: + 首先选择平均值检测模版。 + 选择希望检测的集群,库名,表名,字段,并填入分区过滤条件,如下图所示: + + ![平均值检测模板](../../../images/zh_CN/ch1/平均值检测模板.png) + + 可以在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.5 总和检测 + 语义: + 指定一个表中一个字段,检测该字段的总和是否达到预期。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,key字段的总和值为多少。 + + 配置: + 首先选择总和检测模版。 + 选择希望检测的集群,库名,表名,字段,并填入分区过滤条件,如下图所示: + + ![总和检测模板](../../../images/zh_CN/ch1/总和检测模板.png) + + 可以在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.6 最大值检测 + 语义: + 指定一个表中一个字段,检测该字段的最大值是否达到预期。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,key字段的最大值为多少。 + + 配置: + 首先选择最大值检测模版。 + 选择希望检测的集群,库名,表名,字段,并填入分区过滤条件,如下图所示: + + ![最大值检测模板](../../../images/zh_CN/ch1/最大值检测模板.png) + + 可以在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.7 最小值检测 + 语义: + 指定一个表中一个字段,检测该字段的最小值是否达到预期。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,key字段的最小值为多少。 + + 配置: + 首先选择最小值检测模版。 + 选择希望检测的集群,库名,表名,字段,并填入分区过滤条件,如下图所示: + + ![最小值检测模板](../../../images/zh_CN/ch1/最小值检测模板.png) + + 可以在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.8 正则表达式检测 + 语义: + 指定一个表中一个字段,找出该字段不满足给定正则表达式的记录条数。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,value字段不满足正则表达式'[0-9][a-z][A-Z]'的记录数。 + + 配置: + 首先选择正则表达式检测模版。 + 选择希望检测的集群,库名,表名,字段,并填入分区过滤条件和正则表达式。如下图所示: + + ![正则表达式检测模板](../../../images/zh_CN/ch1/正则表达式检测模板.png) + + 可以在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.9 日期格式检测 + 语义: + 指定一个表中一个字段,找出该字段不满足选中日期格式的字段。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,day字段不满足日期格式yyyyMMdd的记录数。 + + 配置: + 首先选择日期格式检测模版。 + 选择希望检测的集群,库名,表名,字段,并填入分区过滤条件,选中日期格式。如下图所示: + + ![日期检测模板](../../../images/zh_CN/ch1/日期检测模板.png) + + 可以在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.10 字段数值类型检测 + 语义: + 指定一个表中一个字段,找出该字段不满足数值类型的字段(是不是都是数字)。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,value字段不满足数值类型的记录数。 + + 配置: + 首先选择字段数值类型检测模版。 + 选择希望检测的集群,库名,表名,字段,并填入分区过滤条件。如下图所示: + + ![字段数值类型检测模板](../../../images/zh_CN/ch1/字段数值类型检测模板.png) + + 可以在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.11 枚举值检测 + 语义: + 指定一个表中一个字段,找出该字段不在所给枚举值中的记录条数。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,value字段不在“1,2,3,4”中的记录数。 + + 配置: + 首先选择枚举值检测模版。 + 选择希望检测的集群,库名,表名,字段,并填入分区过滤条件和枚举值(逗号分隔)。如下图所示: + + ![枚举检测模板](../../../images/zh_CN/ch1/枚举值检测模板.png) + + 可以在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.12 数值范围检测 + 语义: + 指定一个表中一个字段,找出该字段不在所给数值范围中的记录条数。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,key字段不在[0-5]的记录数。 + + 配置: + 首先选择数值范围检测模版。 + 选择希望检测的集群,库名,表名,并填入分区过滤条件和数值范围。如下图所示: + + ![数值范围检测模板](../../../images/zh_CN/ch1/数值范围检测模板.png) + + 可以在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.13 身份证校验 + 语义: + 指定一个表中一个字段,找出该字段不符合身份证格式的记录条数(不能查询是否是真正的身份证,只能校验格式)。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,value字段不符合身份证格式记录数。 + + 配置: + 首先选择身份证检测模版。 + 选择希望检测的集群,库名,表名,字段,并填入分区过滤条件。如下图所示: + + ![身份证检测模板](../../../images/zh_CN/ch1/身份证检测模板.png) + + 可以在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.14 逻辑类校验 + 语义: + 指定一个表,前置条件和后置条件,找到该表中满足该前置条件,但不满足后置条件的记录条数。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,若key<10(前置条件), 找到不满足value>100(后置条件)的记录条数。 + + 配置: + 首先选择逻辑类检测模版。 + 选择希望检测的集群,库名,表名,字段,并填入分区过滤条件,前置条件和后置条件。如下图所示: + + ![逻辑类检测模板](../../../images/zh_CN/ch1/逻辑类检测模板.png) + + 可以在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.15 空字符串检测 + 语义: + 指定一个表中一个字段,找出该字段为空字符串的记录条数。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,value字段为空字符串的记录数。 + + 配置: + 首先选择空字符串检测模版。 + 选择希望检测的集群,库名,表名,字段,并填入分区过滤条件。如下图所示: + + ![空字符串检测模板](../../../images/zh_CN/ch1/空字符串检测模板.png) + + 可以在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.16 空值或空字符串检测 + 语义: + 指定一个表中一个字段,找出该字段为空值或空字符串的记录条数。 + + 举例: + 需求:希望找出Cluster0002集群中,allenzhou_ind库中,test_table表,在ds='20190314'分区下,value字段为空值或空字符串的记录数。 + + 配置: + 首先选择空值或空字符串检测模版。 + 选择希望检测的集群,库名,表名,字段,并填入分区过滤条件。如下图所示: + + ![空值或空字符串检测模板](../../../images/zh_CN/ch1/空值或空字符串检测模板.png) + + 最后在SQL预览中查看执行的SQL是否和预期一致。 + + ### 7.17 规则模板的新增和修改 + 在该版本中,新增管理员管理规则模板的功能,管理员身份登录系统,点击规则模板,左上方又规则模板添加按钮: + ![添加规则模板](../../../images/zh_CN/ch1/添加规则模板.png) + + 填写好模板信息,保存即可在创建规则的时候使用。 +编辑已有规则模板,则可点击“编辑”操作: +![编辑规则模板](../../../images/zh_CN/ch1/编辑规则模板.png) + + ## 八、任务查看 点击左侧菜单栏中任务查询,即可进入任务界面。 ![任务界面](../../../images/zh_CN/ch1/任务查询.png) @@ -135,4 +411,4 @@ B表 ![任务详情界面](../../../images/zh_CN/ch1/任务详情界面.png) 任务的校验结果可以点击任务的状态进行查看。 -![任务校验结果界面](../../../images/zh_CN/ch1/任务校验结果界面.png) \ No newline at end of file +![任务校验结果界面](../../../images/zh_CN/ch1/任务校验结果界面.png) \ No newline at end of file diff --git "a/docs/zh_CN/ch1/\350\247\246\345\217\221\346\225\260\346\215\256\350\264\250\351\207\217\344\273\273\345\212\241.md" "b/docs/zh_CN/ch1/\350\247\246\345\217\221\346\225\260\346\215\256\350\264\250\351\207\217\344\273\273\345\212\241.md" index 99a9458f..17c7c116 100644 --- "a/docs/zh_CN/ch1/\350\247\246\345\217\221\346\225\260\346\215\256\350\264\250\351\207\217\344\273\273\345\212\241.md" +++ "b/docs/zh_CN/ch1/\350\247\246\345\217\221\346\225\260\346\215\256\350\264\250\351\207\217\344\273\273\345\212\241.md" @@ -23,7 +23,7 @@ **Query参数:** |参数名 |必选 | 类型 | 说明| -| -- | -- |-- |-- | +|:---- |:---|:----- |----- | |app_id |是 | string |系统分配的授权应用APP_ID.| |timestamp | 是 | string | 时间戳。毫秒级的时间戳,时效性:7天| |nonce | 是 | string | 随机数,长度为5| @@ -51,8 +51,8 @@ curl -X POST \ -H 'Cache-Control: no-cache' \ -H 'Content-Type: application/json' \ -d '{ - "project_id":1, - "execution_user":"admin", - "create_user":"admin" + "project_id":1, + "execution_user":"admin", + "create_user":"admin" }' -``` +``` \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index c4b66f88..21a32bb3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,4 +15,4 @@ # group=com.webank.wedatasphere.qualitis -version=0.7.0 \ No newline at end of file +version=0.8.0 \ No newline at end of file diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index b5a5864e..6b0c6e51 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -24,18 +24,34 @@ versions += [ "springBoot": "2.0.4.RELEASE", "commonsLang":"2.6", "commonsLang3":"3.3.1", - "guava": "18.0", - "slf4j":"1.7.25", - "spring":"5.0.8.RELEASE", + "guava": "29.0-jre", + "slf4j":"1.7.30", + "spring":"5.1.15.RELEASE", "gson":"2.8.5", + "jackson":"2.11.0", "hive":"1.2.1", + "hadoop":"2.7.2", "zkCurator":"2.12.0", "jersey":"2.26", "easyExcel":"1.1.2-beat1", "springRetry":"1.2.2.RELEASE", "aspectJ":"1.8.13", "quartz":"2.2.1", - "dss":"0.6.0" + "dss":"0.9.0.WEBANK", + "fastJson":"1.2.70", + "log4j":"1.1.3", + "dom4j":"2.1.1", + "apiUtil":"1.0.2", + "nettyAll":"4.1.50.Final", + "nettyTransport":"4.1.51.Final", + "derby":"10.14.2.0", + "thrift":"0.13.0", + "zookeeper":"3.5.6", + "mysqlConnector":"8.0.11", + "c3p0":"0.9.5.4", + "javaxWebsocket":"9.4.16.v20190411", + "jetty":"6.1.3", + "log4jCore":"2.13.2", ] libs += [ @@ -52,8 +68,37 @@ libs += [ "commonsLang3":"org.apache.commons:commons-lang3:$versions.commonsLang3", "guava":"com.google.guava:guava:$versions.guava", "slf4j":"org.slf4j:slf4j-api:$versions.slf4j", + "log4j":"log4j:log4j:$versions.log4j", + "dom4j":"org.dom4j:dom4j:$versions.dom4j", + "apiUtil":"org.apache.directory.api:api-util:$versions.apiUtil", + "nettyAll":"io.netty:netty-all:$versions.nettyAll", + "nettyTransport":"io.netty:netty-transport:$versions.nettyTransport", + "derby":"org.apache.derby:derby:$versions.derby", + "thrift":"org.apache.thrift:thrift:$versions.thrift", + "zookeeper":"org.apache.zookeeper:zookeeper:$versions.zookeeper", + "mysqlConnector":"mysql:mysql-connector-java:$versions.mysqlConnector", + "c3p0":"c3p0:c3p0:$versions.c3p0", + "javaxWebsocket":"org.eclipse.jetty.websocket:javax-websocket-server-impl:$versions.javaxWebsocket", + "jetty":"org.mortbay.jetty:jetty:$versions.jetty", + "log4jCore":"org.apache.logging.log4j:log4j-core:$versions.log4jCore", + "springAop":"org.springframework:spring-aop:$versions.spring", + "springAspects":"org.springframework:spring-aspects:$versions.spring", + "springBeans":"org.springframework:spring-beans:$versions.spring", + "springContext":"org.springframework:spring-context:$versions.spring", + "springCore":"org.springframework:spring-core:$versions.spring", + "springExpressions":"org.springframework:spring-expressions:$versions.spring", + "springJcl":"org.springframework:spring-jcl:$versions.spring", + "springJdbc":"org.springframework:spring-jdbc:$versions.spring", + "springOrm":"org.springframework:spring-orm:$versions.spring", + "springTest":"org.springframework:spring-test:$versions.spring", + "springTx":"org.springframework:spring-tx:$versions.spring", "springWeb":"org.springframework:spring-web:$versions.spring", + "springWebMvc":"org.springframework:spring-webmvc:$versions.spring", "gson":"com.google.code.gson:gson:$versions.gson", + "jacksonCore":"com.fasterxml.jackson.core:jackson-core:$versions.jackson", + "jacksonDatabind":"com.fasterxml.jackson.core:jackson-databind:$versions.jackson", + "jacksonAnnotations":"com.fasterxml.jackson.core:jackson-annotations:$versions.jackson", + "hadoopClient":"org.apache.hadoop:hadoop-client:$versions.hadoop", "hiveExec":"org.apache.hive:hive-exec:$versions.hive", "curatorRecipes":"org.apache.curator:curator-recipes:$versions.zkCurator", "curatorFramework":"org.apache.curator:curator-framework:$versions.zkCurator", @@ -64,5 +109,6 @@ libs += [ "aspectJ":"org.aspectj:aspectjweaver:$versions.aspectJ", "quartz":"org.quartz-scheduler:quartz:$versions.quartz", "quartzJobs":"org.quartz-scheduler:quartz-jobs:$versions.quartz", - "dssAppJointAuth":"com.webank.wedatasphere.dss:dss-appjoint-auth:$versions.dss" -] + "dssAppJointAuth":"com.webank.wedatasphere.dss:dss-appjoint-auth:$versions.dss", + "fastJson":"com.alibaba:fastjson:$versions.fastJson" +] \ No newline at end of file diff --git "a/images/zh_CN/ch1/\344\270\273\351\224\256\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\344\270\273\351\224\256\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..ce012fc4 Binary files /dev/null and "b/images/zh_CN/ch1/\344\270\273\351\224\256\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\344\273\273\345\212\241\346\237\245\350\257\242-v0.png" "b/images/zh_CN/ch1/\344\273\273\345\212\241\346\237\245\350\257\242-v0.png" new file mode 100644 index 00000000..e7e5de48 Binary files /dev/null and "b/images/zh_CN/ch1/\344\273\273\345\212\241\346\237\245\350\257\242-v0.png" differ diff --git "a/images/zh_CN/ch1/\344\273\273\345\212\241\346\237\245\350\257\242.png" "b/images/zh_CN/ch1/\344\273\273\345\212\241\346\237\245\350\257\242.png" index e7e5de48..4f5b840e 100644 Binary files "a/images/zh_CN/ch1/\344\273\273\345\212\241\346\237\245\350\257\242.png" and "b/images/zh_CN/ch1/\344\273\273\345\212\241\346\237\245\350\257\242.png" differ diff --git "a/images/zh_CN/ch1/\344\273\273\345\212\241\346\240\241\351\252\214\347\273\223\346\236\234\347\225\214\351\235\242-v0.png" "b/images/zh_CN/ch1/\344\273\273\345\212\241\346\240\241\351\252\214\347\273\223\346\236\234\347\225\214\351\235\242-v0.png" new file mode 100644 index 00000000..f67051f9 Binary files /dev/null and "b/images/zh_CN/ch1/\344\273\273\345\212\241\346\240\241\351\252\214\347\273\223\346\236\234\347\225\214\351\235\242-v0.png" differ diff --git "a/images/zh_CN/ch1/\344\273\273\345\212\241\346\240\241\351\252\214\347\273\223\346\236\234\347\225\214\351\235\242.png" "b/images/zh_CN/ch1/\344\273\273\345\212\241\346\240\241\351\252\214\347\273\223\346\236\234\347\225\214\351\235\242.png" index f67051f9..615d1148 100644 Binary files "a/images/zh_CN/ch1/\344\273\273\345\212\241\346\240\241\351\252\214\347\273\223\346\236\234\347\225\214\351\235\242.png" and "b/images/zh_CN/ch1/\344\273\273\345\212\241\346\240\241\351\252\214\347\273\223\346\236\234\347\225\214\351\235\242.png" differ diff --git "a/images/zh_CN/ch1/\344\273\273\345\212\241\350\257\246\346\203\205\347\225\214\351\235\242-v0.png" "b/images/zh_CN/ch1/\344\273\273\345\212\241\350\257\246\346\203\205\347\225\214\351\235\242-v0.png" new file mode 100644 index 00000000..6e24bd32 Binary files /dev/null and "b/images/zh_CN/ch1/\344\273\273\345\212\241\350\257\246\346\203\205\347\225\214\351\235\242-v0.png" differ diff --git "a/images/zh_CN/ch1/\344\273\273\345\212\241\350\257\246\346\203\205\347\225\214\351\235\242.png" "b/images/zh_CN/ch1/\344\273\273\345\212\241\350\257\246\346\203\205\347\225\214\351\235\242.png" index 6e24bd32..35817785 100644 Binary files "a/images/zh_CN/ch1/\344\273\273\345\212\241\350\257\246\346\203\205\347\225\214\351\235\242.png" and "b/images/zh_CN/ch1/\344\273\273\345\212\241\350\257\246\346\203\205\347\225\214\351\235\242.png" differ diff --git "a/images/zh_CN/ch1/\345\210\227\345\205\263\350\201\224\350\247\204\345\210\231\350\257\246\346\203\205.png" "b/images/zh_CN/ch1/\345\210\227\345\205\263\350\201\224\350\247\204\345\210\231\350\257\246\346\203\205.png" new file mode 100644 index 00000000..d21e918f Binary files /dev/null and "b/images/zh_CN/ch1/\345\210\227\345\205\263\350\201\224\350\247\204\345\210\231\350\257\246\346\203\205.png" differ diff --git "a/images/zh_CN/ch1/\345\255\227\346\256\265\346\225\260\345\200\274\347\261\273\345\236\213\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\345\255\227\346\256\265\346\225\260\345\200\274\347\261\273\345\236\213\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..c8b2efa6 Binary files /dev/null and "b/images/zh_CN/ch1/\345\255\227\346\256\265\346\225\260\345\200\274\347\261\273\345\236\213\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\345\271\263\345\235\207\345\200\274\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\345\271\263\345\235\207\345\200\274\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..d4fc8851 Binary files /dev/null and "b/images/zh_CN/ch1/\345\271\263\345\235\207\345\200\274\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\346\200\273\345\222\214\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\346\200\273\345\222\214\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..19df609a Binary files /dev/null and "b/images/zh_CN/ch1/\346\200\273\345\222\214\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\346\225\260\345\200\274\350\214\203\345\233\264\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\346\225\260\345\200\274\350\214\203\345\233\264\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..e0d20fab Binary files /dev/null and "b/images/zh_CN/ch1/\346\225\260\345\200\274\350\214\203\345\233\264\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\346\226\260\345\242\236\345\215\225\350\241\250\346\212\200\346\234\257\350\247\204\345\210\231-v0.png" "b/images/zh_CN/ch1/\346\226\260\345\242\236\345\215\225\350\241\250\346\212\200\346\234\257\350\247\204\345\210\231-v0.png" new file mode 100644 index 00000000..ba113c26 Binary files /dev/null and "b/images/zh_CN/ch1/\346\226\260\345\242\236\345\215\225\350\241\250\346\212\200\346\234\257\350\247\204\345\210\231-v0.png" differ diff --git "a/images/zh_CN/ch1/\346\226\260\345\242\236\345\215\225\350\241\250\346\212\200\346\234\257\350\247\204\345\210\231.png" "b/images/zh_CN/ch1/\346\226\260\345\242\236\345\215\225\350\241\250\346\212\200\346\234\257\350\247\204\345\210\231.png" index ba113c26..b7110176 100644 Binary files "a/images/zh_CN/ch1/\346\226\260\345\242\236\345\215\225\350\241\250\346\212\200\346\234\257\350\247\204\345\210\231.png" and "b/images/zh_CN/ch1/\346\226\260\345\242\236\345\215\225\350\241\250\346\212\200\346\234\257\350\247\204\345\210\231.png" differ diff --git "a/images/zh_CN/ch1/\346\226\260\345\242\236\350\207\252\345\256\232\344\271\211\346\212\200\346\234\257\350\247\204\345\210\231-v0.png" "b/images/zh_CN/ch1/\346\226\260\345\242\236\350\207\252\345\256\232\344\271\211\346\212\200\346\234\257\350\247\204\345\210\231-v0.png" new file mode 100644 index 00000000..8215a8e9 Binary files /dev/null and "b/images/zh_CN/ch1/\346\226\260\345\242\236\350\207\252\345\256\232\344\271\211\346\212\200\346\234\257\350\247\204\345\210\231-v0.png" differ diff --git "a/images/zh_CN/ch1/\346\226\260\345\242\236\350\207\252\345\256\232\344\271\211\346\212\200\346\234\257\350\247\204\345\210\231.png" "b/images/zh_CN/ch1/\346\226\260\345\242\236\350\207\252\345\256\232\344\271\211\346\212\200\346\234\257\350\247\204\345\210\231.png" index 8215a8e9..46e7b028 100644 Binary files "a/images/zh_CN/ch1/\346\226\260\345\242\236\350\207\252\345\256\232\344\271\211\346\212\200\346\234\257\350\247\204\345\210\231.png" and "b/images/zh_CN/ch1/\346\226\260\345\242\236\350\207\252\345\256\232\344\271\211\346\212\200\346\234\257\350\247\204\345\210\231.png" differ diff --git "a/images/zh_CN/ch1/\346\226\260\345\242\236\350\267\250\350\241\250\346\212\200\346\234\257\350\247\204\345\210\231-v0.png" "b/images/zh_CN/ch1/\346\226\260\345\242\236\350\267\250\350\241\250\346\212\200\346\234\257\350\247\204\345\210\231-v0.png" new file mode 100644 index 00000000..c223c49a Binary files /dev/null and "b/images/zh_CN/ch1/\346\226\260\345\242\236\350\267\250\350\241\250\346\212\200\346\234\257\350\247\204\345\210\231-v0.png" differ diff --git "a/images/zh_CN/ch1/\346\226\260\345\242\236\350\267\250\350\241\250\346\212\200\346\234\257\350\247\204\345\210\231.png" "b/images/zh_CN/ch1/\346\226\260\345\242\236\350\267\250\350\241\250\346\212\200\346\234\257\350\247\204\345\210\231.png" index c223c49a..63eec252 100644 Binary files "a/images/zh_CN/ch1/\346\226\260\345\242\236\350\267\250\350\241\250\346\212\200\346\234\257\350\247\204\345\210\231.png" and "b/images/zh_CN/ch1/\346\226\260\345\242\236\350\267\250\350\241\250\346\212\200\346\234\257\350\247\204\345\210\231.png" differ diff --git "a/images/zh_CN/ch1/\346\226\260\345\242\236\351\241\271\347\233\256\345\233\276\347\211\207-v0.png" "b/images/zh_CN/ch1/\346\226\260\345\242\236\351\241\271\347\233\256\345\233\276\347\211\207-v0.png" new file mode 100644 index 00000000..f4f1ebed Binary files /dev/null and "b/images/zh_CN/ch1/\346\226\260\345\242\236\351\241\271\347\233\256\345\233\276\347\211\207-v0.png" differ diff --git "a/images/zh_CN/ch1/\346\226\260\345\242\236\351\241\271\347\233\256\345\233\276\347\211\207.png" "b/images/zh_CN/ch1/\346\226\260\345\242\236\351\241\271\347\233\256\345\233\276\347\211\207.png" index f4f1ebed..efec965f 100644 Binary files "a/images/zh_CN/ch1/\346\226\260\345\242\236\351\241\271\347\233\256\345\233\276\347\211\207.png" and "b/images/zh_CN/ch1/\346\226\260\345\242\236\351\241\271\347\233\256\345\233\276\347\211\207.png" differ diff --git "a/images/zh_CN/ch1/\346\227\245\346\234\237\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\346\227\245\346\234\237\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..d6eb97cc Binary files /dev/null and "b/images/zh_CN/ch1/\346\227\245\346\234\237\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\346\234\200\345\244\247\345\200\274\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\346\234\200\345\244\247\345\200\274\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..9562b1af Binary files /dev/null and "b/images/zh_CN/ch1/\346\234\200\345\244\247\345\200\274\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\346\234\200\345\260\217\345\200\274\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\346\234\200\345\260\217\345\200\274\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..43d82b39 Binary files /dev/null and "b/images/zh_CN/ch1/\346\234\200\345\260\217\345\200\274\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\346\236\232\344\270\276\345\200\274\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\346\236\232\344\270\276\345\200\274\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..23da9505 Binary files /dev/null and "b/images/zh_CN/ch1/\346\236\232\344\270\276\345\200\274\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..0b9fb2a9 Binary files /dev/null and "b/images/zh_CN/ch1/\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\346\267\273\345\212\240\350\247\204\345\210\231\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\346\267\273\345\212\240\350\247\204\345\210\231\346\250\241\346\235\277.png" new file mode 100644 index 00000000..2b3fc6d2 Binary files /dev/null and "b/images/zh_CN/ch1/\346\267\273\345\212\240\350\247\204\345\210\231\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\347\233\270\344\274\274\347\263\273\347\273\237\345\257\271\346\257\224\345\233\276-v0.png" "b/images/zh_CN/ch1/\347\233\270\344\274\274\347\263\273\347\273\237\345\257\271\346\257\224\345\233\276-v0.png" new file mode 100644 index 00000000..90ae58fe Binary files /dev/null and "b/images/zh_CN/ch1/\347\233\270\344\274\274\347\263\273\347\273\237\345\257\271\346\257\224\345\233\276-v0.png" differ diff --git "a/images/zh_CN/ch1/\347\233\270\344\274\274\347\263\273\347\273\237\345\257\271\346\257\224\345\233\276.png" "b/images/zh_CN/ch1/\347\233\270\344\274\274\347\263\273\347\273\237\345\257\271\346\257\224\345\233\276.png" index 90ae58fe..dedb2221 100644 Binary files "a/images/zh_CN/ch1/\347\233\270\344\274\274\347\263\273\347\273\237\345\257\271\346\257\224\345\233\276.png" and "b/images/zh_CN/ch1/\347\233\270\344\274\274\347\263\273\347\273\237\345\257\271\346\257\224\345\233\276.png" differ diff --git "a/images/zh_CN/ch1/\347\251\272\345\200\274\346\210\226\347\251\272\345\255\227\347\254\246\344\270\262\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\347\251\272\345\200\274\346\210\226\347\251\272\345\255\227\347\254\246\344\270\262\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..4e3f98b5 Binary files /dev/null and "b/images/zh_CN/ch1/\347\251\272\345\200\274\346\210\226\347\251\272\345\255\227\347\254\246\344\270\262\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\347\251\272\345\200\274\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\347\251\272\345\200\274\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..2b3987db Binary files /dev/null and "b/images/zh_CN/ch1/\347\251\272\345\200\274\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\347\251\272\345\255\227\347\254\246\344\270\262\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\347\251\272\345\255\227\347\254\246\344\270\262\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..dfe9ad96 Binary files /dev/null and "b/images/zh_CN/ch1/\347\251\272\345\255\227\347\254\246\344\270\262\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\347\263\273\347\273\237\351\205\215\347\275\256-v0.png" "b/images/zh_CN/ch1/\347\263\273\347\273\237\351\205\215\347\275\256-v0.png" new file mode 100644 index 00000000..d379c551 Binary files /dev/null and "b/images/zh_CN/ch1/\347\263\273\347\273\237\351\205\215\347\275\256-v0.png" differ diff --git "a/images/zh_CN/ch1/\347\263\273\347\273\237\351\205\215\347\275\256.png" "b/images/zh_CN/ch1/\347\263\273\347\273\237\351\205\215\347\275\256.png" index d379c551..4cabb650 100644 Binary files "a/images/zh_CN/ch1/\347\263\273\347\273\237\351\205\215\347\275\256.png" and "b/images/zh_CN/ch1/\347\263\273\347\273\237\351\205\215\347\275\256.png" differ diff --git "a/images/zh_CN/ch1/\347\274\226\350\276\221\350\247\204\345\210\231\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\347\274\226\350\276\221\350\247\204\345\210\231\346\250\241\346\235\277.png" new file mode 100644 index 00000000..b450ab10 Binary files /dev/null and "b/images/zh_CN/ch1/\347\274\226\350\276\221\350\247\204\345\210\231\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\350\241\250\345\210\227\350\257\246\346\203\205.png" "b/images/zh_CN/ch1/\350\241\250\345\210\227\350\257\246\346\203\205.png" new file mode 100644 index 00000000..d0752871 Binary files /dev/null and "b/images/zh_CN/ch1/\350\241\250\345\210\227\350\257\246\346\203\205.png" differ diff --git "a/images/zh_CN/ch1/\350\241\250\350\241\214\346\225\260\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\350\241\250\350\241\214\346\225\260\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..5b3d42cf Binary files /dev/null and "b/images/zh_CN/ch1/\350\241\250\350\241\214\346\225\260\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\350\247\204\345\210\231\346\237\245\350\257\242\347\255\233\351\200\211.png" "b/images/zh_CN/ch1/\350\247\204\345\210\231\346\237\245\350\257\242\347\255\233\351\200\211.png" new file mode 100644 index 00000000..14371a28 Binary files /dev/null and "b/images/zh_CN/ch1/\350\247\204\345\210\231\346\237\245\350\257\242\347\255\233\351\200\211.png" differ diff --git "a/images/zh_CN/ch1/\350\247\204\345\210\231\346\237\245\350\257\242\351\246\226\351\241\265.png" "b/images/zh_CN/ch1/\350\247\204\345\210\231\346\237\245\350\257\242\351\246\226\351\241\265.png" new file mode 100644 index 00000000..5bb33f69 Binary files /dev/null and "b/images/zh_CN/ch1/\350\247\204\345\210\231\346\237\245\350\257\242\351\246\226\351\241\265.png" differ diff --git "a/images/zh_CN/ch1/\350\247\204\345\210\231\347\272\254\345\272\246\346\211\247\350\241\214\344\273\273\345\212\241-v0.png" "b/images/zh_CN/ch1/\350\247\204\345\210\231\347\272\254\345\272\246\346\211\247\350\241\214\344\273\273\345\212\241-v0.png" new file mode 100644 index 00000000..4132d75e Binary files /dev/null and "b/images/zh_CN/ch1/\350\247\204\345\210\231\347\272\254\345\272\246\346\211\247\350\241\214\344\273\273\345\212\241-v0.png" differ diff --git "a/images/zh_CN/ch1/\350\247\204\345\210\231\347\272\254\345\272\246\346\211\247\350\241\214\344\273\273\345\212\241.png" "b/images/zh_CN/ch1/\350\247\204\345\210\231\347\272\254\345\272\246\346\211\247\350\241\214\344\273\273\345\212\241.png" index 4132d75e..af48584f 100644 Binary files "a/images/zh_CN/ch1/\350\247\204\345\210\231\347\272\254\345\272\246\346\211\247\350\241\214\344\273\273\345\212\241.png" and "b/images/zh_CN/ch1/\350\247\204\345\210\231\347\272\254\345\272\246\346\211\247\350\241\214\344\273\273\345\212\241.png" differ diff --git "a/images/zh_CN/ch1/\350\272\253\344\273\275\350\257\201\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\350\272\253\344\273\275\350\257\201\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..f63e62cc Binary files /dev/null and "b/images/zh_CN/ch1/\350\272\253\344\273\275\350\257\201\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\351\200\273\350\276\221\347\261\273\346\243\200\346\265\213\346\250\241\346\235\277.png" "b/images/zh_CN/ch1/\351\200\273\350\276\221\347\261\273\346\243\200\346\265\213\346\250\241\346\235\277.png" new file mode 100644 index 00000000..79791ae3 Binary files /dev/null and "b/images/zh_CN/ch1/\351\200\273\350\276\221\347\261\273\346\243\200\346\265\213\346\250\241\346\235\277.png" differ diff --git "a/images/zh_CN/ch1/\351\241\271\347\233\256\345\233\276\347\211\207-v0.png" "b/images/zh_CN/ch1/\351\241\271\347\233\256\345\233\276\347\211\207-v0.png" new file mode 100644 index 00000000..023cdd23 Binary files /dev/null and "b/images/zh_CN/ch1/\351\241\271\347\233\256\345\233\276\347\211\207-v0.png" differ diff --git "a/images/zh_CN/ch1/\351\241\271\347\233\256\345\233\276\347\211\207.png" "b/images/zh_CN/ch1/\351\241\271\347\233\256\345\233\276\347\211\207.png" index 023cdd23..9d11ed81 100644 Binary files "a/images/zh_CN/ch1/\351\241\271\347\233\256\345\233\276\347\211\207.png" and "b/images/zh_CN/ch1/\351\241\271\347\233\256\345\233\276\347\211\207.png" differ diff --git "a/images/zh_CN/ch1/\351\241\271\347\233\256\347\272\254\345\272\246\346\211\247\350\241\214\344\273\273\345\212\241-v0.png" "b/images/zh_CN/ch1/\351\241\271\347\233\256\347\272\254\345\272\246\346\211\247\350\241\214\344\273\273\345\212\241-v0.png" new file mode 100644 index 00000000..a8ccf3cc Binary files /dev/null and "b/images/zh_CN/ch1/\351\241\271\347\233\256\347\272\254\345\272\246\346\211\247\350\241\214\344\273\273\345\212\241-v0.png" differ diff --git "a/images/zh_CN/ch1/\351\241\271\347\233\256\347\272\254\345\272\246\346\211\247\350\241\214\344\273\273\345\212\241.png" "b/images/zh_CN/ch1/\351\241\271\347\233\256\347\272\254\345\272\246\346\211\247\350\241\214\344\273\273\345\212\241.png" index a8ccf3cc..d2aa690b 100644 Binary files "a/images/zh_CN/ch1/\351\241\271\347\233\256\347\272\254\345\272\246\346\211\247\350\241\214\344\273\273\345\212\241.png" and "b/images/zh_CN/ch1/\351\241\271\347\233\256\347\272\254\345\272\246\346\211\247\350\241\214\344\273\273\345\212\241.png" differ diff --git a/profile.gradle b/profile.gradle index eebe49af..b2a28325 100644 --- a/profile.gradle +++ b/profile.gradle @@ -43,6 +43,33 @@ project(':web/app') { compile libs.springBootStarterTest compile libs.springBootStarterAop compile libs.dssAppJointAuth +// compile (libs.springAop) { +// force = true +// } + compile libs.springAop + compile libs.springAspects + compile libs.springBeans + compile libs.springContext + compile libs.springCore + compile libs.springJcl + compile libs.springJdbc + compile libs.springOrm + compile libs.springTest + compile libs.springTx + compile libs.springWeb + compile libs.springWebMvc + compile libs.jacksonCore + compile libs.jacksonDatabind + compile libs.jacksonAnnotations + compile libs.fastJson + compile libs.log4j + compile libs.dom4j + compile libs.apiUtil + compile libs.nettyAll + compile libs.nettyTransport + compile libs.derby + compile libs.zookeeper + compile libs.log4jCore compile project(':web/user') compile project(':web/sys_config') compile project(':web/meta_data') @@ -192,6 +219,13 @@ project(':core/common') { compile libs.springBootStarterJersey compile libs.commonsLang + compile (libs.hadoopClient) { + exclude group: 'javax.servlet' + exclude group: 'javax.servlet.jsp' + exclude group: 'com.sun.jersey' + exclude group: 'com.sun.jersey.contribs' + exclude group: 'javax.xml.bind' + } compile (libs.hiveExec) { exclude group: 'org.apache.commons' exclude group: 'commons-lang' @@ -306,7 +340,6 @@ project(':core/user') { dependencies{ compile libs.springBootStarterDataJpa compile libs.mysqlConnectorJava - } } diff --git a/ui/.editorconfig b/ui/.editorconfig new file mode 100644 index 00000000..8786e6e2 --- /dev/null +++ b/ui/.editorconfig @@ -0,0 +1,15 @@ +# http://editorconfig.org + +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/ui/.eslintrc.json b/ui/.eslintrc.json new file mode 100644 index 00000000..b0f2b686 --- /dev/null +++ b/ui/.eslintrc.json @@ -0,0 +1,37 @@ +{ + "root": true, + "env": { + "browser": true, + "commonjs": true, + "es6": true + }, + "extends": ["eslint:recommended", "plugin:vue/recommended"], + "parserOptions": { + "sourceType": "module" + }, + "plugins": ["vue"], + "rules": { + "no-console": ["error", { + "allow": ["warn", "error"] + }], + "vue/html-indent": [2, 4, { + "attribute": 1, + "closeBracket": 0, + "alignAttributesVertically": false + }], + "vue/html-closing-bracket-newline": 0, + "vue/html-closing-bracket-spacing": ["error", { + "startTag": "never", + "endTag": "never", + "selfClosingTag": "always" + }], + "vue/comment-directive": 0, + "vue/component-name-in-template-casing": 0, + "vue/max-attributes-per-line": 0, + "vue/multiline-html-element-content-newline": 0, + "vue/singleline-html-element-content-newline": 0 + }, + "globals": { + "_": true + } +} diff --git a/ui/.gitattributes b/ui/.gitattributes new file mode 100644 index 00000000..988cdb9d --- /dev/null +++ b/ui/.gitattributes @@ -0,0 +1,4 @@ +* text=auto +* text eol=lf +*.png binary +*.gif binary diff --git a/ui/.gitignore b/ui/.gitignore new file mode 100644 index 00000000..386f4cbb --- /dev/null +++ b/ui/.gitignore @@ -0,0 +1,6 @@ +dist/ +node_modules/ +.cache/ +.idea/ +.DS_Store +dist.zip diff --git a/ui/.vscode/settings.json b/ui/.vscode/settings.json new file mode 100644 index 00000000..981d6c46 --- /dev/null +++ b/ui/.vscode/settings.json @@ -0,0 +1,37 @@ +{ + "files.autoSave": "afterDelay", + "window.zoomLevel": 1, + "git.autofetch": true, + "files.associations": { + "*.fes": "vue" + }, + "beautify.language": { + "html": [ + "htm", + "html", + "vue", + "fes" + ] + }, + "editor.detectIndentation": false, + "vetur.format.scriptInitialIndent": true, + "vetur.format.styleInitialIndent": true, + "vetur.format.defaultFormatter.html": "prettyhtml", + "vetur.format.defaultFormatter.js": "vscode-typescript", + "diffEditor.renderSideBySide": true, + "eslint.autoFixOnSave": true, + "eslint.run": "onSave", + "eslint.alwaysShowStatus": true, + "eslint.validate": [ + "javascript", + { + "language": "vue", + "autoFix": true + }, + "html", + "vue" + ], + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + } +} diff --git a/ui/README.md b/ui/README.md new file mode 100644 index 00000000..2b23f5a6 --- /dev/null +++ b/ui/README.md @@ -0,0 +1,105 @@ +### BDP-DQM数据质量服务前端 + +项目依赖FES2 + +### 项目目录结构 + +``` tree -C -L 3 -I "node_modules" +. +├── README.md +├── dist # fes2 build 之后资源目录 +│   ├── assets +│   │   ├── iconfont.0dd8.svg +│   │   ├── iconfont.126d.eot +│   │   ├── iconfont.18b9.ttf +│   │   └── iconfont.c976.woff +│   ├── index.html +│   ├── js +│   │   ├── app.e923.js +│   │   ├── chunk.b48c.js +│   │   ├── common.e923.js +│   │   └── vendor.dll.f3b5.js +│   └── styles +│   └── common.e923.css +├── fes-jenkins.config.js #fes-jenkins 配置文件 +├── fes.config.js # fes 配置文件 +├── mock.js +├── package-lock.json +├── package.json +└── src + ├── app.js + ├── assets + │   ├── images + │   ├── js + │   └── styles + ├── components + │   ├── fesLeft.fes + │   └── goBack.fes + └── pages + ├── HelpDocument + ├── addTechniqueRule + ├── configureParameter + ├── customTechnicalRule + ├── dashboard + ├── home + ├── metadataManagement + ├── myDatasheet + ├── optionManage + ├── personnelManage + ├── projects + ├── route.fes + ├── ruleTemplateList + ├── taskDetail + ├── taskQuery + └── verifyFailData +``` + +### 开发 + +``` +fes2 dev +``` + +### 代码检查 + +配置了eslint,规则详见.eslintrc.json + +同时添加了提交代码时pre-commit hook,请按规范修改错误信息后提交代码 + +``` +npm run lint +npm run fix +``` + +### 构建 +``` +wnpm install -g @webank/fes-jenkins +``` + +``` +fes2 build +fes2 build --env $env +``` + +### 构建发布 + +dev分支push代码会自动发布到开发环境 http://test-dqm.webank.com/dqm-ui-dev/ +以下本地命令需全局安装fes-jenkins,不同环境自动发布命令: + +``` +fj build dev +fj build sit +fj build uat +``` + +### 其它 + +编辑器推荐vscode +建议安装eslint,stylelint,editorconfig插件 + +eslint-plugin-vue 只能检查出来.vue 格式的,暂时不使用template格式部分规则 +``` +"vue/max-attributes-per-line": 0, +"vue/multiline-html-element-content-newline": 0, +"vue/singleline-html-element-content-newline" +``` diff --git a/ui/fes-jenkins.config.js b/ui/fes-jenkins.config.js new file mode 100644 index 00000000..cb5ed88c --- /dev/null +++ b/ui/fes-jenkins.config.js @@ -0,0 +1,20 @@ +module.exports = { + job: 'web-bdp-dqm', // Jenkins项目名 + env : { + uat: { // uat http://test-dqm.webank.com/dqm-ui/ + ENV: 'uat', + TPL: '29520', + DEPLOY_SERVER: 'origin/uat' + }, + sit: { // sit http://test-dqm.webank.com/dqm-ui-dev/ + ENV: 'sit', + TPL: '29878', + DEPLOY_SERVER: 'origin/dev' + }, + dev: { // 开发 http://test-dqm.webank.com/dqm-ui-dev/ + ENV: 'dev', + TPL: '29878', + DEPLOY_SERVER: 'origin/dev' + } + } +} diff --git a/ui/fes.config.js b/ui/fes.config.js new file mode 100644 index 00000000..ee3664cb --- /dev/null +++ b/ui/fes.config.js @@ -0,0 +1,53 @@ +import i18nConfig from './i18n-config.json' +export default { + mode: 'vertical', // 可选有vertical、horizontal,默认vertical + theme: 'dark', // 可选有blue、dark,默认blue + fesName: 'Qualitis', // 项目名称 + FesHeader: true, + favicon: 'static/icon-title.ico', // 图标 + // 环境变量配置 + env: { + // 本地开发环境 fes dev默认使用local环境 + local: { + // api: 'http://127.0.0.1:8090/qualitis' //行内 + api: 'http://127.0.0.1:8090/qualitis' //开源 + + }, + // 开发环境机器 + dev: { + api: 'qualitis', + + }, + // 测试环境 fes build --env=sit 触发使用 + sit: { + api: '', + }, + // 测试环境 fes build --env=uat 触发使用 + uat: { + api: '', + }, + // 生产环境 fes build默认使用prod环境 fes dev --env=prod 触发使用 + prod: { + } + }, + // 配置角色-路由访问权限,使用FesApp.setRole('unLogin')来修改当前用户的角色,控制路由访问权限 + roles: { + unLogin: ['/home','/dashboard', '/'], + noauth: ['/dashboard','/home','/taskQuery','/addTechniqueRule','/ruleQuery','/ruleQuery/*','/taskDetail', + '/ruleTemplateList','/ruleTemplateList/*','/myProject','/projects/*','/myProject/*','/HelpDocument','/customTechnicalRule', + '/crossTableCheck','/verifyFailData', '/addGroupTechniqueRule', '/'], + admin: ['/dashboard','*'] + }, + // map + map: { + status: [ + ['1', '成功'], + ['2', '失败'] + ] + }, + i18n: { + locale: 'zh-cn', // default zh-cn + messages: i18nConfig + }, + menu: [] +} diff --git a/ui/find.js b/ui/find.js new file mode 100644 index 00000000..bf0e139a --- /dev/null +++ b/ui/find.js @@ -0,0 +1,52 @@ +var fs = require('fs'); +var path = require('path'); +var reg = /[\u4e00-\u9fa5]+:?/g; +var json = {}; +function fileDisplay(filePath) { + fs.readdir(filePath, function (err, files) { + if (err) { + console.warn(err) + } else { + files.forEach(function (filename) { + var filedir = path.join(filePath, filename); + fs.stat(filedir, function (eror, stats) { + if (eror) { + console.warn('获取文件stats失败'); + } else { + var isFile = stats.isFile(); + var isDir = stats.isDirectory(); + if (isFile) { + // console.log(filedir); + var content = fs.readFileSync(filedir, 'utf-8'); + var arrs = content.match(reg) || []; + arrs.forEach(item => { + json[item] = item; + }); + + fs.writeFile('./cn.json', JSON.stringify(json), function(err) { + if (err) { + throw err; + } + console.log('done.'); + }) + } + if (isDir) { + fileDisplay(filedir); + } + } + }) + }); + } + }); +} +var filePath = path.resolve('./src/pages/verifyFailData'); +fileDisplay(filePath); + + +// 1.首先修改filePath,指定要处理的目录 +// 2.然后执行node find.js, 找出所有需要替换的中文形成json +// 3.然后执行node translate.js 调用API批量翻译,翻译结束结果输出cn.json ,对接口翻译结果检查及修改 +// 3.接着修改cn.json文件里面的key值,key值建议按如下格式:`模块文件名.文字内容英文简写`,key中英文部分保持一致 +// 4.生成的json文件每个key值修改完成后,修改replace.js filePath 值为1中指定的目录 ,执行node replace.js, 会把所指定目录下的中文全部按第三步的key值替换为$t('key') +// 5.把json文件内容复制到国际配置里 + diff --git a/ui/i18n-config.json b/ui/i18n-config.json new file mode 100644 index 00000000..2df02d5b --- /dev/null +++ b/ui/i18n-config.json @@ -0,0 +1,1023 @@ +{ + "zh-cn": { + "languageSwitching": "语言切换", + "common": { + "status": "状态", + "noData": "暂无数据", + "projectName": "项目名称", + "projectId": "项目Id", + "operate": "操作", + "ok": "确定", + "cancel": "取消", + "newProject": "新增项目", + "edit": "编辑", + "save": "保存", + "SQL": "SQL预览", + "monthlyFluctuation": "月波动", + "weeklyFluctuation": "周波动", + "daillyFluctuation": "日波动", + "fixedValue": "固定值", + "equal": "等于", + "greaterThan": "大于", + "lessThan": "小于", + "greatThanOrEqualTo": "大于等于", + "lessThanOrEqualTo": "小于等于", + "unequalTo": "不等于", + "beforeDays": "前N天(表示程序运行时的实际日期前N天,需手动改变N值)", + "delete":"删除", + "successfulOperate": "操作成功", + "back":"返回", + "fail": "登录失败,请检查密码或帐号", + "notFound":"请求未找到", + "contentLanguage": "zh_CN", + "refresh": "刷新", + "notEmpty": "不能为空", + "runUser": "执行用户", + "condition": "过滤条件", + "ruleName": "规则名称", + "ruleTemplate": "校验规则", + "dataSource": "数据源", + "database": "库名", + "table": "表名", + "column": "字段", + "template": "模板", + "cluster": "集群", + "linkis":"Linkis地址", + "pleaseEnter": "请输入", + "view": "查看", + "executeTask": "执行任务", + "ruleType": "规则类型", + "config": "配置", + "templateParameter": "模板参数", + "templateType": "模板类型", + "customType": "自定义类型", + "crossTableType":"跨表类型", + "databaseList":"数据库", + "tableList":"数据表", + "detail": "详情", + "clustetrConfig": "集群配置", + "failCheck": "未通过校验", + "byCheck": "通过校验", + "checkDataSource": "校验数据源", + "technicalRegulation": "技术规则", + "parityField": "校验字段", + "thresholdValue": "阈值", + "qualityCheck": "质量校验", + "search": "搜索", + "project": "项目", + "number": "任务编号", + "yes":"是", + "no":"否", + "user": "用户", + "add": "新增", + "submit": "提交", + "openUpstream": "开启上游表查询", + "closeUpstream": "关闭上游表查询", + "openTask": "开启任务阻断", + "closeTask": "关闭任务阻断", + "addRule": "添加技术规则", + "description": "描述", + "operations": "操作已选项", + "selectOne": "请至少选择一项", + "founder": "创建人", + "createTime": "创建时间", + "modifier": "修改人", + "changeTheTime": "修改时间", + "addTo": "添加", + "addTag": "添加标签", + "itemTag": "项目标签", + "pageinfo": "共{total}条数据,共{pageTotal} 页", + "prompt": "提示", + "errorPage": "抱歉,您访问的页面不存在", + "open": "开", + "close": "关", + "homePage": "返回首页", + "previousPage": "返回上一页", + "editCurrentRules": "编辑当前规则" + }, + "modal": { + "deleteRule": "删除规则" + }, + "label": { + "projectIntro": "项目介绍", + "projectId": "项目ID", + "alarm": "是否校验", + "comparisonMethod": "比较方式", + "validationRules": "输出的校验规则", + "statisticalFunction":"统计函数值" + }, + "toastSuccess": { + "successImport": "项目导入成功", + "deleteSuccess": "删除成功", + "executeSuccess": "任务执行成功", + "addSuccess": "添加成功", + "technicalSuccess": "技术规则导入成功", + "editSuccess": "修改成功", + "search": "查询成功", + "refreshSuccessfully":"刷新成功", + "authorizedSuccess":"授权成功 ", + "simulatedOut":"模拟用户账号退出成功", + "simulatedUser":"模拟用户成功" + }, + "toastWarn": { + "importFile": "所导入文件不能大于5M", + "validationRule": "请选择校验规则", + "conformValidationRules": "不符合校验规则的字段", + "atMost": "最多可以选择", + "fields": "个字段", + "oneField": "最少选择一个字段", + "cluster": "集群名称不能为空", + "selectCluster":"请选择集群", + "oneType":"类型至少选择一个", + "userEmpty":"用户不能为空", + "oneMapping":"至少添加一条映射关系!", + "cannotBeEmpty":"数据库,表不可以为空!", + "selectRelation":"请选择运算关系", + "expressionEmpty":"表达式不可为空" + }, + "toastError": { + "selectFile": "请选择需要导出的项目", + "importFail": "文件导出失败", + "selectRule": "请选择需要导出的规则", + "runRule": "请选择需要执行的规则" + }, + "message": { + "delete": "请确认是否删除?", + "thresholdTitle": "超出阈值范围", + "thresholdText": "日波动,月波动,周波动的阈值最大值为10000%", + "title": "标题", + "password": "密码是", + "user": "请确认是否退出当前模拟用户账号" + }, + "tableThead": { + "ruleId": "规则ID", + "templateName": "规则模板名称", + "databaseAndTable": "数据库、表" + }, + "home": { + "login": "登录", + "username": "用户名", + "password": "密码", + "system":"系统", + "enterUsername":"请输入用户名" + }, + "dashboard": { + "dashboard": "工作概览", + "todayPass": "今日通过校验", + "todayFail": "失败", + "last7Days": "最近7天", + "last30Days": "最近30天", + "totalNumberOfApplication": "任务总数", + "failedNumberOfAppliaction": "任务失败数", + "passNumberOfApplication": "任务通过校验数", + "notPassNumberOfApplication": "任务未通过校验数" + }, + "alarmsList": { + "applicationId": "编号", + "executionTime": "执行时间", + "task": "子任务:通过校验/失败/未通过校验", + "passVerification": "通过校验/失败/未通过校验", + "statusList": "{0:'', 1:'已提交', 2:'', 3:'运行中', 4:'通过校验', 5:'', 6:'', 7:'失败',8:'未通过校验',9:'任务初始化失败', 10:'任务初始化成功',11:'参数错误'}" + }, + "projects": { + "projects": "规则管理", + "delete": "是否要删除", + "rule": "规则", + "groupName": "组名", + "deleteRule": "请确认是否删除当前【{name}】技术规则?", + "projectHint": "Tip: 普通项目主要是Qualitis UI创建和管理的项目。是构建校验任务的基础。\n工作流项目主要是Qualitis内嵌DSS,联动创建和管理的项目,是工作流的校验任务的基础。", + "lableRepeat": "标签名已存在" + }, + "myProject": { + "myProject": "我的项目", + "importProject": "导入项目", + "downloadProject": "导出项目", + "newSingleTableRule": "新增技术规则", + "newCustomRule": "自定义技术规则", + "newMultiTableRule": "新增跨表规则", + "importRules": "导入技术规则", + "DownloadRules": "导出技术规则", + "run": "任务执行", + "ordinaryProject": "普通项目", + "workflowProject": "工作流项目", + "addOrdinaryProject": "新增普通项目", + "label": "标签", + "deleteProject": "确认删除【{name}】项目?", + "projectEdit": "项目编辑" + }, + "ruleQuery": { + "ruleQuery": "规则查询", + "tableRuleInformation": "表规则信息" + }, + "ruleTemplate": { + "ruleTemplate": "规则模板", + "templateDetails": "模板详情" + }, + "configureParameter": { + "configureParameter": "系统设置" + }, + "personnelManage": { + "personnelManage": "人员配置" + }, + "optionManage": { + "optionManage": "权限管理" + }, + "metadataManagement": { + "metadataManagement": "元数据管理" + }, + "addTechniqueRule": { + "replace": "替换SQL模版中的占位符${filter}", + "notConformRules":"不符合规则的字段", + "fields":"个字段", + "limitRule": "已含有规则", + "notSupportUpstream": "不支持上游环境", + "selectDataFirst": "请先选择数据表" + }, + "verifyFailData": { + "notPassBase": "未通过校验的数据存储数据库", + "notCheck": "未校验", + "singleTableCheck": "单表校验", + "database": "数据库:", + "dataTable": "数据表:", + "actualResult": "实际结果", + "notPassTable": "未通过校验数据的存储表", + "acrossCheck": "跨表校验", + "table": "表", + "resultOrder": "实际结果排序", + "restoreData": "还原数据结构", + "checkDetails": "校验详情" + }, + "crossTableCheck": { + "Database": "数据库", + "sheets": "数据表", + "mapSheets": "数据表", + "search0": "请输入关键字进行搜索", + "signOfOperation": "运算符号", + "function": "函数", + "keyWords": "关键字", + "expression": "系统表达式", + "inTheDay": "当天", + "actualDate": "表示程序运行时的实际日期", + "before": "前", + "day": "天", + "beforeDay": "表示程序运行时的实际日期前", + "manuallyChange": "需手动改变", + "value": "值", + "mappingRelationship": "映射关系", + "add": "添加", + "leftSide": "左侧表达式", + "relationshipBetween": "关系", + "rightSide": "右侧表达式", + "preview": "预览", + "alarm": "是否告警", + "template": "template", + "compareTheWay": "比较方式", + "addFilterConditions": "添加过滤条件", + "addTheMappingRelationship": "添加映射关系", + "confirmToAdd": "确认添加", + "confirmTheChange": "确认修改", + "operatetheOperator": "操作运算符", + "thecustomValue": "自定义值", + "enterValue": "请输入自定义值", + "dataTable": "数据表", + "addWhere": "添加where添加", + "serviceMenuEditing": "自主菜单编辑", + "customEdit": "自定义编辑" + }, + "taskQuery": { + "taskQuery": "任务查询", + "searchCriteria0": "搜索条件", + "status": "任务状态", + "search": "查询", + "ruleNumber": "技术规则数目", + "submissionTime": "任务提交时间", + "endTime": "任务结束时间", + "subTasks": "子任务", + "failure": "失败", + "scheduling": "调度方式", + "selectSearchCriteria": "请选择搜索条件进行查询", + "all": "所有", + "submitted": "已提交", + "inTheOperation": "运行中", + "tasksFailed": "任务初始化失败", + "tasksSuccessfully": "任务初始化成功", + "parameterError": "参数错误", + "selectProject0": "请选择项目", + "searchCriteria": "请选择搜索条件", + "inputNumber": "请输入任务编号", + "selectProject": "选择项目", + "dataSource": "选择数据源", + "interfaceScheduling": "接口调度", + "timeSchedule": "定时调度", + "taskCheck": "子任务:通过校验/失败/未通过校验" + }, + "taskDetail": { + "taskRule": "任务规则", + "startTime": "开始时间", + "endTime": "结束时间", + "collapse": "收起", + "moreErrors": "更多错误", + "moreLogs": "更多日志", + "statusList": "{0:'', 1:'已提交', 2:'初始化', 3: '运行中', 4: '', 5:'通过校验', 6:'未通过校验', 7:'失败', 8:'任务不存在', 9:'取消', 10:'超时', 11:''}" + }, + "ruleTemplatelist": { + "baseTemplate": "基础模板", + "templateId": "模板Id", + "templateName": "模板名称", + "multiTableTemplate":"跨表校验模板", + "basicInformation": "基础信息", + "dataSourceType": "数据源类型", + "templateType": "模板类型", + "saveData": "是否保存不符合校验的数据", + "inputLimit": "输入限制", + "numberOfClusters": "集群数量限制", + "numberOfDatabases": "数据库数量限制", + "numberOfDataTables": "数据表数量限制", + "fieldLimit": "字段限制", + "templateOutput": "模板输出", + "typeMap": [" ","固定值","枚举值","数据表","字段","数据库","字段拼接","正则","数组","条件"], + "notLimited": "不限制", + "notSelectable": "不可选择", + "one": "1个", + "createIntermediateTable": "创建中间表", + "saveTable": "是否保存中间表", + "previewTemplateSql": "预览模板sql", + "templateStatisticsName": "模板统计名称", + "templateStatisticalFunctions": "模板统计函数", + "templateOutputName": "模板输出名称", + "parseFormat": "解析格式", + "tableHint": "请输入生成中间表的sql语句,注意使用占位符。\n 例如:select * from ${db}.${table} where (${filter}) and (${field} is null)", + "functionValue": "函数值", + "replaceName": "占位符名称", + "replaceContent": "替换内容", + "numberType": "统计数值类型", + "deleteTemplate": "请确认是否删除当前【{name}】规则模板?", + "fieldSplice": "字段拼接", + "regular": "正则", + "array": "数组", + "condition": "条件", + "placeholder": "占位符", + "replaceType": "占位符类型", + "placeholderDescription": "Placeholder description", + "clusterNum": "集群数量", + "dbNum": "数据库数量", + "tableNum": "数据表数量", + "fleldNum": "字段数量", + "notDeleteTemplate": "不可删除内置规则模板", + "checkPlaceholderContent": "请检查占位符内容是否完整", + "ANDStitching": "AND拼接", + "sourceDatabase": "来源数据库", + "sourceTable": "来源表", + "targetDatabase": "目标数据库", + "targetTable": "目标表", + "joinLeftExpression": "Join左表达式", + "joinOperator": "join操作符", + "joinRightExpression": "Join右表达式", + "joinLeftField": "Join左字段", + "joinRightField": "Join右字段", + "precondition": "前置条件", + "postcondition": "后置条件" + }, + "ruleQueryPage": { + "dataTableName": "数据表名", + "search": "查询", + "technicalRules": "技术规则数量", + "founder": "创建人", + "technicalRuleName": "技术规则名称", + "verificationRuleTemplate": "校验规则模板", + "allowedEmpty": "是否允许为空", + "partition": "是否分区", + "primaryKey": "是否主键", + "negativeLength": "字段定长", + "default": "默认值", + "associationRuleManagement": "关联规则管理", + "ruleName": "规则名", + "carriedOut": "执行", + "export": "导出", + "filterTable": "模糊查询表名", + "deleteRule": "请确认是否删除当前【{name}】规则名?" + }, + "personnelManagePage": { + "userManagement": "用户管理", + "newUsers":"新增用户", + "userId":"用户ID", + "userName": "用户名", + "chineseName": "中文名", + "department": "部门", + "userGroupManagement": "用户组管理", + "proxyUser": "新增代理用户", + "proxyUserId":"代理用户ID", + "proxyUserName":"代理用户名", + "memberManagement":"成员管理", + "userGroup":"用户组", + "userGroupName":"用户组名称", + "addUser": "添加用户", + "addMembers": "添加成员", + "deleteCurrentUser": "确认删除当前用户名为【{name}】的数据?", + "deleteProxyUser": "确认删除当前代理用户名为【{name}】的数据?", + "proxyUserDetail": "代理用户" + }, + "optionManagePage": { + "authorityManagement": "权限管理", + "authorizationId":"权限ID", + "URLAddress": "URL地址", + "requestMethod": "请求方式", + "editPermissionManagement": "编辑权限管理", + "roleRightsManagement": "角色权限管理", + "rolePermissionID": "角色权限ID", + "roleID": "角色ID", + "roleManagement":"角色管理", + "characterName": "角色名", + "editRoleManagement": "编辑角色管理", + "userRoleManagement": "用户角色管理", + "userRoleID":"用户角色ID", + "userID":"用户ID", + "userSpecialPermission":"用户特殊权限", + "userPrivilegeID": "用户权限ID", + "privilegeID":"权限ID", + "userPermissionSpecialPermission":"用户权限特殊权限", + "modifyRoleId": "修改角色ID", + "confirmModifyRoleId": "确认修改角色ID?", + "modifyPermissionId": "修改权限ID", + "confirmPermissionId": "确认修改权限ID?", + "modifyRoleName": "修改角色名", + "confirmRoleName": "确认修改角色名?", + "modifyUserID": "修改用户ID", + "confirmUserID": "确认修改用户ID?", + "deleteCurrentRole": "确认删除当前角色名为【{name}】的数据?", + "deleteAuthorityID": "确认删除当前角色权限ID为【{name}】的数据?", + "deleteLimitID": "确认删除当前权限ID为【{name}】的数据?", + "deleteRoleID": "确认删除当前角色ID为【{name}】的数据?", + "deleteUserID": "确认删除当前用户ID为【{name}】的数据?" + }, + "metadataManagementPage": { + "addAuthorization": "新增授权", + "authorization": "授权", + "authorizationManagementList":"授权管理列表", + "type":"类型", + "permissionType":"权限类型", + "authorizationTime": "授权时间", + "authorizationInformation":"授权信息", + "confirmAuthorization": "确认授权", + "clusterPermissions":"集群权限", + "databasePermissions":"数据库权限", + "dataTablePermissions":"数据表权限", + "authorizedUser":"授权用户" + }, + "configureParameterPage": { + "clusterParameterId":"集群参数id", + "clusterName": "集群名称", + "clusterType":"集群类型", + "parameterConfiguration":"数据源参数配置", + "errorData":"异常数据存储数据库名称", + "executor": "可以使用${USERNAME}去替换实际执行的用户", + "dataMapValueRule": "只支持字母、$、{}或下划线", + "deleteCurrentCluster": "确认删除当前集群名为【{name}】的数据?" + }, + "filterDescription": { + "tips": "过滤条件说明:可在过滤条件中添加分区表达式,用于指定运行时的分区。", + "example":"例子", + "actualDate":" 1. ds=${yyyyMMdd},表示程序运行时的实际日期。", + "brforeDay": "2. ds=${yyyyMMdd}-N,表示程序运行时的实际日期前N天 若今天是20181217,填写了ds=${yyyyMMdd}-1,运行时替换为ds=20181216。", + "support":"当前支持通用的日期格式,如yyyyMMdd,yyyy-MM-dd等。" + }, + "customTechnicalRule": { + "save": "保存不符合数据校验的结果", + "text": "如果勾选,就会将不满足sql语句的结果保存到中间表中" + + }, + "fesHeader":{ + "simulatedUser":"模拟用户", + "exit": "退出", + "current":"当前模拟用户为", + "language":"语言切换", + "select": "请选择要模拟登录的用户", + "exitUser": "退出模拟用户", + "selectUser": "请选择用户", + "signOut": "退出登录", + "changePassword": "修改密码", + "oldPassword": "旧密码", + "newPassword": "新密码", + "confirmPassword": "确认新密码", + "checkPassword": "新密码输入不一致" + }, + "addGroupTechniqueRule": { + "newCustomRule": "自定义技术规则", + "newMultiTableRule": "新增跨表规则", + "projectDetails": "项目详情", + "technicalRulesDetails": "技术规则详情", + "deleteNode": "请直接删除节点" + } + }, + "en": { + "languageSwitching": "Language switching", + "common": { + "status": "Status", + "noData": "No Data", + "projectName": "Project Name", + "projectId": "Project Id", + "operate": "Operation", + "ok": "Ok", + "cancel": "Cancel", + "newProject": "New Project", + "edit": "Edit", + "save": "Save", + "SQL": "SQL", + "monthlyFluctuation": "Monthly Fluctuation", + "weeklyFluctuation": "Weekly Fluctuation", + "daillyFluctuation": "Daily Fluctuation", + "fixedValue": "Fixed Value", + "equal": "Equal", + "greaterThan": "Greater Than", + "lessThan": "Less Than", + "greatThanOrEqualTo": "Great Than Or Equal To", + "lessThanOrEqualTo": "Less Than Or Equal To", + "unequalTo": "Not Equal To", + "beforeDays": "N days before (means N days before the actual date when the program is running, N values need to be changed manually)", + "delete":"Delete", + "successfulOperate": "Success", + "back":"Back", + "fail": "Login failed, please check your password or account", + "notFound":"Request not found", + "contentLanguage": "en_US", + "refresh": "Refresh", + "notEmpty": "Can not be empty", + "runUser": "Administrator", + "condition": "Filter", + "ruleName": "Rule Name", + "ruleTemplate": "Template", + "dataSource": "DataSource", + "database": "Database", + "table": "Table", + "column": "Column", + "fields": "Fields", + "template": "Template", + "cluster": "Cluster", + "linkis":"Linkis Address", + "pleaseEnter": "Please Enter", + "view": "View", + "executeTask": "Run", + "ruleType": "Template Type", + "config": " Configuration", + "templateParameter": "templateParameter", + "templateType": "Template Type", + "customType": "Custom Template Type", + "crossTableType":"Multi-table Template Type", + "databaseList":"Database", + "tableList":"Table", + "detail": "Details", + "clustetrConfig": "Cluster", + "failCheck": "Not Pass", + "byCheck": "Pass", + "checkDataSource": "DataSource", + "technicalRegulation": "Rule", + "parityField": "Check Column", + "thresholdValue": "Threshold", + "qualityCheck": "Verification Configuration", + "search": "Search", + "project": "Project", + "number": "ApplicationId", + "yes":"Yes", + "no":"No", + "user": "User", + "add": "Add", + "submit": "Submit", + "openUpstream": "Open upstream table query", + "closeUpstream": "Close upstream table query", + "openTask": "Enable task blocking", + "closeTask": "Turn off task blocking", + "addRule": "New Rule", + "description": "Description", + "operations": "Operate Selected", + "selectOne": "Please select at lest one", + "founder": "Creator", + "createTime": "Create Time", + "modifier": "Modifier", + "changeTheTime": "Change The Time", + "addTo": "Add", + "addTag": "Add Tag", + "itemTag": "Project Tag", + "pageinfo": "Total {total} data, {pageTotal} pages", + "prompt": "Prompt", + "errorPage": "Sorry, the page you visited does not exist", + "open": "Open", + "close": "Close", + "homePage": "Back to homepage", + "previousPage": "Return to previous page", + "editCurrentRules": "edit Current Rule" + }, + "modal": { + "deleteRule": "Delete Rule" + }, + "label": { + "projectIntro": "Project Introduction", + "projectId": "Project Id", + "alarm": "Verification", + "comparisonMethod": "Compare Type", + "validationRules": "Check Column", + "statisticalFunction":"Statistical function value" + }, + "toastSuccess": { + "successImport": "Project import successful", + "deleteSuccess": "Successfully delete", + "executeSuccess": "Mission executed successfully", + "addSuccess": "Successfully added", + "technicalSuccess": "Successfully import of technical rules", + "editSuccess": "Successfully modify", + "search": "Successful search", + "refreshSuccessfully":"Successfully refresh", + "authorizedSuccess":"Successfully authorized", + "simulatedOut":"Simulated user account logged out successfully", + "simulatedUser":"Simulated user successful" + }, + "toastWarn": { + "importFile": "The size of file can not be greater than 5M", + "validationRule": "Please select a template", + "conformValidationRules": "A field that does not conform to the validation rules", + "atMost": "At most", + "fields": "fields", + "oneField": "Please select at least one field", + "cluster": "The cluster name can not be empty", + "selectCluster":"Please select cluster", + "oneType":"Please select cluster", + "userEmpty":"The user can not be empty", + "oneMapping":"Add at least one mapping", + "cannotBeEmpty":"Database, table can not be empty", + "selectRelation":"Please select the operation relation", + "expressionEmpty":"The expression can not be empty" + }, + "toastError": { + "selectFile": "Please select project first", + "importFail": "File export Failed", + "selectRule": "Please select template first", + "runRule": "Please select the template to be executed" + }, + "message": { + "delete": "Please confirm whether to delete it", + "thresholdTitle": "Beyond the threshold", + "thresholdText":"The maximum threshold of daily fluctuation, monthly fluctuation and weekly fluctuation is 10000%", + "title": "title", + "password": "password is", + "user": "Please confirm whether to exit the current simulated user account" + }, + "tableThead": { + "ruleId": "RuleId", + "templateName": "TemplateName", + "databaseAndTable": "Datasource" + }, + "home": { + "login": "Sign in", + "username": "Username", + "password": "Password", + "system":"system", + "enterUsername":"please enter user name" + }, + "dashboard": { + "dashboard": "OverView", + "todayPass": "Pass", + "todayFail": "Failed", + "last7Days": "Last 7 Days", + "last30Days": "last 30 Days", + "totalNumberOfApplication": "Total Number Of Application", + "failedNumberOfAppliaction": "Failed Number Of Appliaction", + "passNumberOfApplication": "Pass Number Of Application", + "notPassNumberOfApplication": "Not Pass Number Of Application" + }, + "alarmsList": { + "applicationId": "ApplicationId", + "executionTime": "ExecutionTime", + "task": "Task: Pass/Failed/Not Pass", + "passVerification": "Pass/Failed/Not Pass", + "statusList": "{0:'', 1:'submitted', 2:'', 3:'running', 4:'pass', 5:'', 6:'', 7:'failed',8:'not pass',9:'initialization failed', 10:'initialization successful',11:'argument error'}" + }, + "projects": { + "projects": "Rule Configuration", + "delete": "Whether to delete or not", + "rule": "Template", + "groupName": "Group Name", + "deleteRule": "Please confirm whether to delete the current【{name}】technical rules?", + "projectHint": "Tip: Common projects are mainly projects created and managed by Qualitis UI. It is the basis for building verification tasks. \nWorkflow projects are mainly Qualitis embedded DSS projects, which are created and managed by linkage, and are the basis of workflow verification tasks.", + "lableRepeat": "Label name already exists" + }, + "myProject": { + "myProject": "Rule management", + "importProject": "Import Project", + "downloadProject": "Download Project", + "newSingleTableRule": "New Single Table Rule", + "newCustomRule": "New Custom Rule", + "newMultiTableRule": "New Multi-table Rule", + "importRules": "Import Rules", + "DownloadRules": "Download Rules", + "run": "Run", + "ordinaryProject": "Normal Project", + "workflowProject": "Workflow Project", + "addOrdinaryProject": "New Normal Project", + "label": "Label", + "deleteProject": "Confirm to delete project 【{name}】?", + "projectEdit": " Project Editor" + }, + "ruleQuery": { + "ruleQuery": "Query", + "tableRuleInformation": "Table Rule Information" + }, + "ruleTemplate": { + "ruleTemplate": "Template", + "templateDetails": "Template Details" + }, + "configureParameter": { + "configureParameter": "Settings" + }, + "personnelManage": { + "personnelManage": "User Management" + }, + "optionManage": { + "optionManage": "Authority" + }, + "metadataManagement": { + "metadataManagement": "Metadata Management" + }, + "addTechniqueRule": { + "replace": "Replace the placeholder ${filter} in the SQL template", + "notConformRules":"Field that does not conform to the rules", + "fields":"Column", + "limitRule":"Contained rule", + "notSupportUpstream": "Don Not Support Upstream Environment", + "selectDataFirst": "Please Select Ddata Sheet First" + }, + "verifyFailData": { + "notPassBase": "Database to save the not pass verification data", + "notCheck": "Not Verified", + "singleTableCheck": "Single Table Verification", + "database": "Database:", + "dataTable": "Table:", + "actualResult": "Result", + "notPassTable": "Table to save data that not pass verification", + "acrossCheck": "Multi-table", + "table": "Table:", + "resultOrder": "Actual result ordering", + "restoreData": "Restore data structure", + "checkDetails": "Check Details" + }, + "crossTableCheck": { + "Database": "Database", + "sheets": "Table", + "mapSheets": "Table1", + "search0": "Please enter the keywords to search", + "signOfOperation": "Operation", + "function": "Function:", + "keyWords": "Key words", + "expression": "System expression", + "inTheDa": "In the day", + "actualDate": "The actual date when the program is running", + "before": "Before", + "day": "day", + "beforeDay": "Before the actual date of said the program is running", + "manuallyChange": "Need to manually change", + "value": "value", + "mappingRelationship": "The mapping relationship", + "add": "add", + "leftSide": "On the left side of the expression", + "relationshipBetween": "Relationship between", + "rightSide": "On the right side of the expression", + "preview": "preview", + "alarm": "Whether the alarm", + "template": "The template", + "compareTheWay": "Compare Type", + "addFilterConditions": "Add filter conditions", + "addTheMappingRelationship": "Add the mapping relationship", + "confirmToAdd": "Confirm to add", + "confirmTheChange": "Confirm the change", + "operatetheOperator": "Operator", + "thecustomValue": "Custom Value", + "enterValue": "Please enter a custom value, and then click on 'Enter'", + "dataTable": "Table2", + "addWhere": "add one or more conditions to a where", + "Self-serviceMenuEditing": "Self-service Menu Editing", + "customEdit": "Custom Edit" + }, + "taskQuery": { + "taskQuery": "Application", + "searchCriteria0": "Search Criteria", + "status": "Status", + "search": "Search", + "ruleNumber": "Rule Size", + "submissionTime": "Submit Time", + "endTime": "End Time:", + "subTasks": "The subtasks", + "failure": "Failed", + "scheduling": "Invoke Type", + "selectSearchCriteria": "Please select a search criteria", + "all": "All", + "submitted": "Submitted", + "inTheOperation": "Running", + "tasksFailed": "Init Failed", + "tasksSuccessfully": "Init Succeed", + "parameterError": "Argument Error", + "selectProject0": "Please select a project", + "searchCriteria": "Please select a search criteria", + "inputNumber": "Please input number", + "selectProject": "Select the project", + "dataSource": "Select DataSource", + "interfaceScheduling": "API", + "timeSchedule": "Timing schedule", + "taskCheck": "Task: pass/failed/not pass" + }, + "taskDetail": { + "taskRule": "Task Rule", + "startTime": "Start Time:", + "endTime": "End Time:", + "collapse": "Collapse", + "moreErrors": "More Errors", + "moreLogs": "More Logs", + "statusList": "{0:'', 1:'submitted', 2:'initialization', 3: 'running', 4: '', 5:'pass', 6:'not pass', 7:'failed', 8:'task does not exist', 9:'cancel', 10:'time out', 11:''}" + }, + "ruleTemplatelist": { + "baseTemplate": "Single Table Template", + "templateId": "TemplateId", + "templateName": "Template Name", + "multiTableTemplate":"Multi-table Template:", + "basicInformation": "Basic Information", + "dataSourceType": "DataSource Type", + "templateType": "Template Type", + "saveData": "Save Data", + "inputLimit": "Input Limitation", + "numberOfClusters": "Number Of Clusters", + "numberOfDatabases": "Number Of Databases", + "numberOfDataTables": "Number Of Data Tables", + "fieldLimit": "Field Limitation", + "templateOutput": "Template Output", + "typeMap": [" ","Fixed Value","Enum value","Table","Field","Database","Field Concat","Regexp","Array","Condition"], + "notLimited": "Not Limited", + "notSelectable": "Not Selectable", + "one": "one", + "createIntermediateTable": "Create Intermediate Table", + "saveTable": "Whether to save the intermediate table", + "previewTemplateSql": "Preview Template Sql", + "templateStatisticsName": "Template Statistics Name", + "templateStatisticalFunctions": "template Statistical Functions", + "templateOutputName": "Template Output Name", + "parseFormat": "Parse Format", + "tableHint": "Please enter the SQL statement to generate the intermediate table, pay attention to the use of placeholders.Example\nselect * from ${db}.${table} where (${filter}) and (${field} is null)", + "functionValue": "Function Value", + "replace": "Replace Name", + "replaceContent": "Replace Content", + "numberType": "Numeric Type", + "deleteTemplate": "Please confirm whether to delete the current【 {name}】rule template?", + "fieldSplice": "Field Splice", + "regular": "Regular", + "array": "Array", + "condition": "Condition", + "placeholder": "Placeholder", + "replaceType": "Placeholder type", + "placeholderDescription": "Placeholder description", + "clusterNum": "Number of clusters", + "dbNum": "Number of databases", + "tableNum": "Number of data sheets", + "fleldNum": "Number of fields", + "notDeleteTemplate": "Cannot delete built-in rule templates", + "checkPlaceholderContent": "Please check if the placeholder content is complete", + "ANDStitching": "AND Stitching", + "sourceDatabase": "Source Database", + "sourceTable": "Source Table", + "targetDatabase": "Target Database", + "targetTable": "Target Table", + "joinLeftExpression": "Join Left Expression", + "joinOperator": "Join Operator", + "joinRightExpression": "Join Right Expression", + "joinLeftField": "Join Left Field", + "joinRightField": "Join Right Field", + "precondition": "Precondition", + "postcondition": "Postcondition" + }, + "ruleQueryPage": { + "dataTableName": "Table", + "search": "Search", + "technicalRules": "Rule Size", + "founder": "Creator", + "technicalRuleName": "Rule", + "verificationRuleTemplate": "Rule Template", + "verifyDataSource": "Verify data source", + "allowedEmpty": "Whether it is allowed to be empty", + "partition": "Whether to partition", + "primaryKey": "Primary Key", + "negativeLength": "Column Length", + "default": "Defaults", + "associationRuleNumber": "Association Rule Management", + "ruleName": "Rule Name", + "carriedOut": "Carry Out", + "export": "Export", + "filterTable": "Fuzzy lookup table name", + "deleteRule": "Please confirm whether to delete the current 【{name}】 rule name?" + }, + "personnelManagePage": { + "userManagement": "User Management", + "newUsers":"New", + "userId":"UserId", + "userName": "Username", + "chineseName": "Chinese Name", + "department": "Department", + "userGroupManagement": "Proxy User Management", + "proxyUser": "Add Proxy User", + "proxyUserId":"Proxy User ID", + "proxyUserName":"Proxy Username", + "memberManagement":"Member Management", + "userGroup":"Proxy User", + "userGroupName":"Proxy User Name", + "addUser": "Add Users", + "addMembers": "Add Members", + "deleteCurrentUser": "Are you sure to delete the data of the current user named 【{name}】?", + "deleteProxyUser": "Confirm to delete the data of the current proxy user name 【{name}】?", + "proxyUserDetail": "Proxy User" + }, + "optionManagePage": { + "authorityManagement": "Permission Management", + "authorizationId": "Permission ID", + "URLAddress": "URL", + "requestMethod": "Method", + "editPermissionManagement":"Edit Permission Management", + "roleRightsManagement": "Role Permission Management", + "rolePermissionID": "Role And Permission ID", + "roleID": "Role ID", + "roleManagement":"Role Management", + "characterName": "Role Name", + "editRoleManagement": "Role Management", + "userRoleManagement": "User Role Management", + "userRoleID":"User Role ID", + "userID":"UserId", + "userSpecialPermission":"User Permission Management", + "userPrivilegeID": "User And Permission ID", + "privilegeID":"PermissionId", + "userPermissionSpecialPermission":"User Permission Management", + "modifyRoleId": "Modify Role ID", + "confirmModifyRoleId": "Confirm To Modify The Role ID?", + "modifyPermissionId": "Modify Permission ID", + "confirmPermissionId": "Confirm To Modify The Permission ID?", + "modifyRoleName": "Modify Role Name", + "confirmRoleName": "Confirm To Modify Role Name?", + "modifyUserID": "Modify User ID", + "confirmUserID": "Confirm To Modify User ID?", + "deleteCurrentRole": "Are you sure to delete the data of the current role named 【{name}】?", + "deleteAuthorityID": "Are you sure to delete the data whose current role authority ID is 【{name}】?", + "deleteLimitID": "Are you sure to delete the data whose current permission ID is 【{name}】?", + "deleteRoleID": "Are you sure to delete the data with the current role ID 【{name}】?", + "deleteUserID": "Are you sure to delete the data whose current user ID is 【{name}】?" + }, + "metadataManagementPage": { + "addAuthorization": "Add Authorization", + "authorization": "Grant", + "authorizationManagementList":"Authorization Management", + "type":"Authorization Type", + "permissionType":"Authorization Type", + "authorizationTime": "Grant Time", + "authorizationInformation":"Authorization Information", + "confirmAuthorization": "Confirm", + "clusterPermissions":"Cluster Authorization Type", + "databasePermissions":"Database Authorization Type", + "dataTablePermissions":"Table Authorization Type", + "authorizedUser":"Grantor" + }, + "configureParameterPage": { + "clusterParameterId":"Cluster Parameter Id", + "clusterName": "Cluster Name", + "clusterType":"Cluster Type", + "parameterConfiguration":"Data Source Parameter Configuration", + "errorData":"Database To Save Error Data", + "executor": "Use ${USERNAME} to replace the executor", + "dataMapValueRule": "Only letters, $, {}, or underscores are supported", + "deleteCurrentCluster": "Are you sure to delete the data 【{name}】 in the current cluster?" + }, + "filterDescription": { + "tips": "Tips: System expressions are provided in filter", + "example":"Example", + "actualDate":" 1. ds=${yyyyMMdd} means the actual date that running this rule", + "brforeDay": "2.ds=${yyyyMMdd}-N means the N day before date that running this rule.For example, when ds=${yyyyMMdd}-1 was typed in, if today is 20181217, it will be replace by ds=20181216", + "support": "'yyyyMMdd','yyyy-MM-dd' are supported." + }, + "customTechnicalRule": { + "save": "Save results that do not conform to data validation", + "text": "If checked, results that do not satisfy the SQL statement are saved to the intermediate table" + }, + "fesHeader":{ + "simulatedUser":"Simulated User", + "exit": "Exit", + "current":"The current simulated user is ", + "language": "Language switching", + "select": "Please select the user to simulate", + "exitUser": "Exit Simulated User", + "selectUser": "Please select user", + "signOut": "Sign out", + "changePassword": "Change Password", + "oldPassword": "old Password", + "newPassword": "new Password", + "confirmPassword": "Confirm new password", + "checkPassword": "The new password input is inconsistent" + }, + "addGroupTechniqueRule": { + "newCustomRule": "New Custom Rule", + "newMultiTableRule": "New Multi-table Rule", + "projectDetails": "Project Details", + "technicalRulesDetails": "Technical Rules Details", + "deleteNode": "Please delete the node directly" + } + } +} \ No newline at end of file diff --git a/ui/mock.js b/ui/mock.js new file mode 100644 index 00000000..6661c1ff --- /dev/null +++ b/ui/mock.js @@ -0,0 +1,115 @@ +module.exports = function (cgiMock, Mock) { + var Random = Mock.Random; + + //前缀,全局(可选) + //cgiMock.prefix = ''; + + // 登录 + cgiMock({ + url: 'api/v1/login/local', + method: 'POST', + result: { + "code": "200", + "success": false + } + }); + + //利用mock.js 产生随机文本 + cgiMock('/text', Random.cparagraph()); + + // 返回一个字符串 利用mock.js 产生随机字符 + cgiMock('/string', Mock.mock({ + "string|1-10": "★" + })); + + + // 正则匹配url, 返回一个字符串 + // cgiMock(/\/abc|\/xyz/, 'regexp test!'); + + // option.result 参数如果是一个函数, 可以实现自定义返回内容, 接收的参数是是经过 express 封装的 req 和 res 对象. + // cgiMock(/\/function$/, function (req, res) { + // res.send('function test'); + // }); + + // 返回文本 fs.readFileSync + // cgiMock('/file', cgiMock.file('./test.json')); + + // 更复杂的规则配置 + cgiMock({ + url: /\/who/, + method: 'GET', + result: function (req, res) { + if (req.query.name === 'kwan') { + res.json({ + 'kwan': '孤独患者' + }); + } else { + res.send('Nooooooooooo'); + } + }, + headers: { + 'Content-Type': 'text/plain', + 'Content-Length': '123', + 'ETag': '12345' + }, + cookies: [{ + name: 'myname', + value: 'kwan', + maxAge: 900000, + httpOnly: true + }], + //接口随机延迟 + timeout: Mock.mock({ + "number|1000-5000": 1000 + }).number + }); + //登录 + cgiMock('/login', function (req, res) { + res.send(JSON.stringify({ + code: "0", + msg: "", + result: { + username: "万纯(harrywan)", + roleName: "管理员" + } + })) + }); + + cgiMock('/getTestList', function (req, res) { + var list = []; + for (var i = 0; i < req.body.pageSize; i++) { + list.push({ + a: i + }) + } + res.send(JSON.stringify({ + code: "0", + msg: "this is message", + result: { + list: list, + page: { + pageSize: req.body.pageSize, + currentPage: req.body.currentPage, + totalPage: 1000 + } + } + + })) + }); + + cgiMock('/getNumber', function (req, res) { + res.send(JSON.stringify({ + code: "0", + msg: "this is message", + result: 4 + })) + }); + + cgiMock('/getRoleName', function (req, res) { + res.send(JSON.stringify({ + code: "0", + msg: "this is message", + result: 'admin' + })) + }); +} diff --git a/ui/package-lock.json b/ui/package-lock.json new file mode 100644 index 00000000..898dd743 --- /dev/null +++ b/ui/package-lock.json @@ -0,0 +1,4347 @@ +{ + "name": "Exchangis", + "version": "0.5.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@antv/adjust": { + "version": "0.2.3", + "resolved": "http://127.0.0.1:8001/@antv/adjust/download/@antv/adjust-0.2.3.tgz", + "integrity": "sha1-w4hKaAwyZMwSXX8qtTmOihwLlAE=", + "requires": { + "@antv/util": "~2.0.0", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "http://127.0.0.1:8001/tslib/download/tslib-1.14.1.tgz", + "integrity": "sha1-zy04vcNKE0vK8QkcQfZhni9nLQA=" + } + } + }, + "@antv/attr": { + "version": "0.3.2", + "resolved": "http://127.0.0.1:8001/@antv/attr/download/@antv/attr-0.3.2.tgz", + "integrity": "sha1-5YZrZIcMYvOpwluKYfZUuiv9oFE=", + "requires": { + "@antv/color-util": "^2.0.1", + "@antv/util": "~2.0.0", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "http://127.0.0.1:8001/tslib/download/tslib-1.14.1.tgz", + "integrity": "sha1-zy04vcNKE0vK8QkcQfZhni9nLQA=" + } + } + }, + "@antv/color-util": { + "version": "2.0.5", + "resolved": "http://127.0.0.1:8001/@antv/color-util/download/@antv/color-util-2.0.5.tgz", + "integrity": "sha1-bGwUrShzUmvLpyOAt4GiskNgrG4=", + "requires": { + "@antv/util": "^2.0.9", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "http://127.0.0.1:8001/tslib/download/tslib-1.14.1.tgz", + "integrity": "sha1-zy04vcNKE0vK8QkcQfZhni9nLQA=" + } + } + }, + "@antv/component": { + "version": "0.6.3", + "resolved": "http://127.0.0.1:8001/@antv/component/download/@antv/component-0.6.3.tgz", + "integrity": "sha1-O7TO2+mF6DG/s3ip5nKkbAQipac=", + "requires": { + "@antv/dom-util": "~2.0.1", + "@antv/g-base": "~0.4.0", + "@antv/matrix-util": "^3.1.0-beta.1", + "@antv/path-util": "~2.0.7", + "@antv/scale": "~0.3.1", + "@antv/util": "~2.0.0", + "fecha": "~4.2.0", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "http://127.0.0.1:8001/tslib/download/tslib-1.14.1.tgz", + "integrity": "sha1-zy04vcNKE0vK8QkcQfZhni9nLQA=" + } + } + }, + "@antv/coord": { + "version": "0.3.0", + "resolved": "http://127.0.0.1:8001/@antv/coord/download/@antv/coord-0.3.0.tgz", + "integrity": "sha1-RyOc/TVF+Ht6Z6m+2S0SpSnVqZY=", + "requires": { + "@antv/matrix-util": "^3.1.0-beta.2", + "@antv/util": "~2.0.3", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "http://127.0.0.1:8001/tslib/download/tslib-1.14.1.tgz", + "integrity": "sha1-zy04vcNKE0vK8QkcQfZhni9nLQA=" + } + } + }, + "@antv/data-set": { + "version": "0.11.7", + "resolved": "http://127.0.0.1:8001/@antv/data-set/download/@antv/data-set-0.11.7.tgz", + "integrity": "sha1-oO/7z4pR3Ir0wDzB0Z+bxtuuBXo=", + "requires": { + "@antv/hierarchy": "^0.6.0", + "@antv/util": "^2.0.0", + "d3-composite-projections": "^1.2.0", + "d3-dsv": "^1.0.5", + "d3-geo": "~1.6.4", + "d3-geo-projection": "~2.1.2", + "d3-hexjson": "^1.0.1", + "d3-hierarchy": "^1.1.5", + "d3-sankey": "^0.9.1", + "d3-voronoi": "^1.1.2", + "dagre": "^0.8.2", + "point-at-length": "^1.0.2", + "regression": "^2.0.0", + "simple-statistics": "^6.1.0", + "topojson-client": "^3.0.0", + "wolfy87-eventemitter": "^5.1.0" + } + }, + "@antv/dom-util": { + "version": "2.0.2", + "resolved": "http://127.0.0.1:8001/@antv/dom-util/download/@antv/dom-util-2.0.2.tgz", + "integrity": "sha1-THsKGV4CflVXBDWmglzsVt+wtZA=", + "requires": { + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "http://127.0.0.1:8001/tslib/download/tslib-1.14.1.tgz", + "integrity": "sha1-zy04vcNKE0vK8QkcQfZhni9nLQA=" + } + } + }, + "@antv/event-emitter": { + "version": "0.1.2", + "resolved": "http://127.0.0.1:8001/@antv/event-emitter/download/@antv/event-emitter-0.1.2.tgz", + "integrity": "sha1-oXt8uG5tBxiA3Gv7IydW+IYk7Lw=" + }, + "@antv/g-base": { + "version": "0.4.7", + "resolved": "http://127.0.0.1:8001/@antv/g-base/download/@antv/g-base-0.4.7.tgz", + "integrity": "sha1-dpj8TIyzgfK3iaMPvrJrHojEgZY=", + "requires": { + "@antv/event-emitter": "^0.1.1", + "@antv/g-math": "^0.1.3", + "@antv/matrix-util": "^3.1.0-beta.1", + "@antv/path-util": "~2.0.5", + "@antv/util": "~2.0.0", + "@types/d3-timer": "^1.0.9", + "d3-ease": "^1.0.5", + "d3-interpolate": "^1.3.2", + "d3-timer": "^1.0.9", + "detect-browser": "^5.1.0" + } + }, + "@antv/g-canvas": { + "version": "0.4.15", + "resolved": "http://127.0.0.1:8001/@antv/g-canvas/download/@antv/g-canvas-0.4.15.tgz", + "integrity": "sha1-gawb4mnZYoAgL/76AqOfBgsajAc=", + "requires": { + "@antv/g-base": "^0.4.7", + "@antv/g-math": "^0.1.3", + "@antv/path-util": "~2.0.5", + "@antv/util": "~2.0.0", + "gl-matrix": "^3.0.0" + } + }, + "@antv/g-math": { + "version": "0.1.5", + "resolved": "http://127.0.0.1:8001/@antv/g-math/download/@antv/g-math-0.1.5.tgz", + "integrity": "sha1-jkSYp7wCsRPBG1A3OpsVJzE5ze8=", + "requires": { + "@antv/util": "~2.0.0", + "gl-matrix": "^3.0.0" + } + }, + "@antv/g-svg": { + "version": "0.4.7", + "resolved": "http://127.0.0.1:8001/@antv/g-svg/download/@antv/g-svg-0.4.7.tgz", + "integrity": "sha1-DWXh2zTm3+YJqts+3fR0jbAvCwE=", + "requires": { + "@antv/g-base": "^0.4.7", + "@antv/g-math": "^0.1.3", + "@antv/util": "~2.0.0", + "detect-browser": "^4.6.0" + }, + "dependencies": { + "detect-browser": { + "version": "4.8.0", + "resolved": "http://127.0.0.1:8001/detect-browser/download/detect-browser-4.8.0.tgz", + "integrity": "sha1-HXO9iMF76GaQGVDOCqrh7QYJAsY=" + } + } + }, + "@antv/g2": { + "version": "4.0.15", + "resolved": "http://127.0.0.1:8001/@antv/g2/download/@antv/g2-4.0.15.tgz", + "integrity": "sha1-aO7uW+/Z8uZU92VfjT0pNc3VJrg=", + "requires": { + "@antv/adjust": "^0.2.1", + "@antv/attr": "^0.3.1", + "@antv/color-util": "^2.0.2", + "@antv/component": "^0.6.0", + "@antv/coord": "^0.3.0", + "@antv/event-emitter": "~0.1.0", + "@antv/g-base": "^0.4.3", + "@antv/g-canvas": "^0.4.0", + "@antv/g-svg": "^0.4.0", + "@antv/matrix-util": "^3.1.0-beta.1", + "@antv/path-util": "^2.0.3", + "@antv/scale": "^0.3.1", + "@antv/util": "~2.0.5", + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.3", + "resolved": "http://127.0.0.1:8001/tslib/download/tslib-2.0.3.tgz", + "integrity": "sha1-jgdBrEX8DCJuWKF7/D5kubxsphw=" + } + } + }, + "@antv/hierarchy": { + "version": "0.6.6", + "resolved": "http://127.0.0.1:8001/@antv/hierarchy/download/@antv/hierarchy-0.6.6.tgz", + "integrity": "sha1-WEWbCO8ZuzTY3wqW1SlUWAeDrr4=", + "requires": { + "@antv/util": "^2.0.7" + } + }, + "@antv/matrix-util": { + "version": "3.1.0-beta.2", + "resolved": "http://127.0.0.1:8001/@antv/matrix-util/download/@antv/matrix-util-3.1.0-beta.2.tgz", + "integrity": "sha1-tK+vtw299Sr/yjCNNUbIoJD9I8o=", + "requires": { + "@antv/util": "^2.0.9", + "gl-matrix": "^3.3.0", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "http://127.0.0.1:8001/tslib/download/tslib-1.14.1.tgz", + "integrity": "sha1-zy04vcNKE0vK8QkcQfZhni9nLQA=" + } + } + }, + "@antv/path-util": { + "version": "2.0.8", + "resolved": "http://127.0.0.1:8001/@antv/path-util/download/@antv/path-util-2.0.8.tgz", + "integrity": "sha1-m8VNK3GYqtmIqcxKbekFTyaRm4Q=", + "requires": { + "@antv/util": "^2.0.9", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "http://127.0.0.1:8001/tslib/download/tslib-1.14.1.tgz", + "integrity": "sha1-zy04vcNKE0vK8QkcQfZhni9nLQA=" + } + } + }, + "@antv/scale": { + "version": "0.3.4", + "resolved": "http://127.0.0.1:8001/@antv/scale/download/@antv/scale-0.3.4.tgz", + "integrity": "sha1-/t/a7f0+RaD0O/eG6ElnN12J364=", + "requires": { + "@antv/util": "~2.0.3", + "fecha": "~4.2.0", + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.3", + "resolved": "http://127.0.0.1:8001/tslib/download/tslib-2.0.3.tgz", + "integrity": "sha1-jgdBrEX8DCJuWKF7/D5kubxsphw=" + } + } + }, + "@antv/util": { + "version": "2.0.9", + "resolved": "http://127.0.0.1:8001/@antv/util/download/@antv/util-2.0.9.tgz", + "integrity": "sha1-vT4pajkuEfvieB/eOdjnC6HFPtA=", + "requires": { + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "http://127.0.0.1:8001/tslib/download/tslib-1.14.1.tgz", + "integrity": "sha1-zy04vcNKE0vK8QkcQfZhni9nLQA=" + } + } + }, + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "http://127.0.0.1:8001/@babel/code-frame/download/@babel/code-frame-7.0.0.tgz", + "integrity": "sha1-BuKrGb21NThVWaq7W6WXKUgoAPg=", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.12.1", + "resolved": "http://127.0.0.1:8001/@babel/generator/download/@babel/generator-7.12.1.tgz", + "integrity": "sha1-DXC+Mr2qA9fFHIWX3aduDfHxVGg=", + "dev": true, + "requires": { + "@babel/types": "^7.12.1", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "http://127.0.0.1:8001/@babel/helper-function-name/download/@babel/helper-function-name-7.10.4.tgz", + "integrity": "sha1-0tOyDFmtjEcRL6fSqUvAnV74Lxo=", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "http://127.0.0.1:8001/@babel/helper-get-function-arity/download/@babel/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha1-mMHL6g4jMvM/mkZhuM4VBbLBm6I=", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "http://127.0.0.1:8001/@babel/helper-split-export-declaration/download/@babel/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha1-+KSRJErPamdhWKxCBykRuoOtCZ8=", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "http://127.0.0.1:8001/@babel/helper-validator-identifier/download/@babel/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha1-p4x6clHgH2FlEtMbEK3PUq2l4NI=", + "dev": true + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "http://127.0.0.1:8001/@babel/highlight/download/@babel/highlight-7.0.0.tgz", + "integrity": "sha1-9xDDjI1Fjm3ZogGvtjf8t4HOmeQ=", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.12.3", + "resolved": "http://127.0.0.1:8001/@babel/parser/download/@babel/parser-7.12.3.tgz", + "integrity": "sha1-owVBXr56bHAjtAtRIqBmLZKDNM0=", + "dev": true + }, + "@babel/runtime-corejs3": { + "version": "7.12.1", + "resolved": "http://127.0.0.1:8001/@babel/runtime-corejs3/download/@babel/runtime-corejs3-7.12.1.tgz", + "integrity": "sha1-UbkJK+++7tk4M1oQnb4N9RRR6dw=", + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "http://127.0.0.1:8001/@babel/template/download/@babel/template-7.10.4.tgz", + "integrity": "sha1-MlGZbEIA68cdGo/EBfupQPNrong=", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "http://127.0.0.1:8001/@babel/code-frame/download/@babel/code-frame-7.10.4.tgz", + "integrity": "sha1-Fo2ho26Q2miujUnA8bSMfGJJITo=", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "http://127.0.0.1:8001/@babel/highlight/download/@babel/highlight-7.10.4.tgz", + "integrity": "sha1-fRvf1ldTU4+r5sOFls23bZrGAUM=", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + } + } + }, + "@babel/traverse": { + "version": "7.12.1", + "resolved": "http://127.0.0.1:8001/@babel/traverse/download/@babel/traverse-7.12.1.tgz", + "integrity": "sha1-lBOV4MXMhtXT51yqCV05JFJvDB4=", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.1", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.12.1", + "@babel/types": "^7.12.1", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "http://127.0.0.1:8001/@babel/code-frame/download/@babel/code-frame-7.10.4.tgz", + "integrity": "sha1-Fo2ho26Q2miujUnA8bSMfGJJITo=", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "http://127.0.0.1:8001/@babel/highlight/download/@babel/highlight-7.10.4.tgz", + "integrity": "sha1-fRvf1ldTU4+r5sOFls23bZrGAUM=", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "http://127.0.0.1:8001/lodash/download/lodash-4.17.20.tgz", + "integrity": "sha1-tEqbYpe8tpjxxRo1RaKzs2jVnFI=", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.12.1", + "resolved": "http://127.0.0.1:8001/@babel/types/download/@babel/types-7.12.1.tgz", + "integrity": "sha1-4QnZq5mo3nNb4ofuPWqZR6GQxK4=", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.20", + "resolved": "http://127.0.0.1:8001/lodash/download/lodash-4.17.20.tgz", + "integrity": "sha1-tEqbYpe8tpjxxRo1RaKzs2jVnFI=", + "dev": true + } + } + }, + "@types/chart.js": { + "version": "2.9.27", + "resolved": "http://127.0.0.1:8001/@types/chart.js/download/@types/chart.js-2.9.27.tgz", + "integrity": "sha1-cW/Ve0zHkdxZLNQkpE35XyrvuRg=", + "dev": true, + "requires": { + "moment": "^2.10.2" + } + }, + "@types/d3-timer": { + "version": "1.0.10", + "resolved": "http://127.0.0.1:8001/@types/d3-timer/download/@types/d3-timer-1.0.10.tgz", + "integrity": "sha1-MpxRwskx9E7QrP94uMhFcazw7SE=" + }, + "@types/json-schema": { + "version": "7.0.6", + "resolved": "http://127.0.0.1:8001/@types/json-schema/download/@types/json-schema-7.0.6.tgz", + "integrity": "sha1-9MfsQ+gbMZqYFRFQMXCfJph4kfA=", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "http://127.0.0.1:8001/@types/json5/download/@types/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/node": { + "version": "14.14.2", + "resolved": "http://127.0.0.1:8001/@types/node/download/@types/node-14.14.2.tgz", + "integrity": "sha1-0lKV+eTKWYmixhB1TcAqlyEjXus=", + "dev": true + }, + "@webank/eslint-config-webank": { + "version": "0.1.6", + "resolved": "http://127.0.0.1:8001/@webank/eslint-config-webank/download/@webank/eslint-config-webank-0.1.6.tgz", + "integrity": "sha1-WvNH3KUIlzhomX2bKujJOLSyiQw=", + "dev": true, + "requires": { + "babel-eslint": "^10.0.2", + "eslint": "^5.3.0", + "eslint-config-airbnb-base": "^13.2.0", + "eslint-plugin-import": "^2.18.2", + "eslint-plugin-vue": "^5.2.3", + "vue-eslint-parser": "^6.0.4" + }, + "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "http://127.0.0.1:8001/acorn/download/acorn-6.4.2.tgz", + "integrity": "sha1-NYZv1xBSjpLeEM8GAWSY5H454eY=", + "dev": true + }, + "eslint-plugin-vue": { + "version": "5.2.3", + "resolved": "http://127.0.0.1:8001/eslint-plugin-vue/download/eslint-plugin-vue-5.2.3.tgz", + "integrity": "sha1-PudZfYI7VHiASy/rqYY7G3QnOWE=", + "dev": true, + "requires": { + "vue-eslint-parser": "^5.0.0" + }, + "dependencies": { + "vue-eslint-parser": { + "version": "5.0.0", + "resolved": "http://127.0.0.1:8001/vue-eslint-parser/download/vue-eslint-parser-5.0.0.tgz", + "integrity": "sha1-APTk2pTsl0uCGib/DtD3p4QCuKE=", + "dev": true, + "requires": { + "debug": "^4.1.0", + "eslint-scope": "^4.0.0", + "eslint-visitor-keys": "^1.0.0", + "espree": "^4.1.0", + "esquery": "^1.0.1", + "lodash": "^4.17.11" + } + } + } + }, + "ms": { + "version": "2.1.2", + "resolved": "http://127.0.0.1:8001/ms/download/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", + "dev": true + }, + "vue-eslint-parser": { + "version": "6.0.5", + "resolved": "http://127.0.0.1:8001/vue-eslint-parser/download/vue-eslint-parser-6.0.5.tgz", + "integrity": "sha1-wcBnwnVXSOKPOHLNQujBxMGoBZ8=", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-scope": "^4.0.0", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.0", + "esquery": "^1.0.1", + "lodash": "^4.17.11" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "http://127.0.0.1:8001/debug/download/debug-4.2.0.tgz", + "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "espree": { + "version": "5.0.1", + "resolved": "http://127.0.0.1:8001/espree/download/espree-5.0.1.tgz", + "integrity": "sha1-XWUm+k/H8HiKXPdbFfMDI+L4H3o=", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + } + } + } + } + }, + "@webank/fes-core": { + "version": "0.0.11", + "resolved": "http://127.0.0.1:8001/@webank/fes-core/download/@webank/fes-core-0.0.11.tgz", + "integrity": "sha1-XMrWh9NDR/xKmXriF+Mnr7lH6ok=", + "requires": { + "@webank/wa-sdk": "1.x", + "axios": "^0.16.2", + "lodash": "^4.17.4", + "vue": "^2.6.10", + "vue-i18n": "^8.4.0", + "vue-router": "^2.6.0", + "vue-template-compiler": "^2.6.10" + } + }, + "@webank/ui-webank": { + "version": "2.3.43", + "resolved": "http://127.0.0.1:8001/@webank/ui-webank/download/@webank/ui-webank-2.3.43.tgz", + "integrity": "sha1-o3zBhQuSDrEBFrtXlcnwEmVBiCc=", + "requires": { + "async-validator": "^1.8.2", + "xss": "^1.0.7" + } + }, + "@webank/wa-sdk": { + "version": "1.10.11", + "resolved": "http://127.0.0.1:8001/@webank/wa-sdk/download/@webank/wa-sdk-1.10.11.tgz", + "integrity": "sha1-NY3Kcv05rsfjiSDTvyYx18HBH3I=" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "http://127.0.0.1:8001/abbrev/download/abbrev-1.1.1.tgz", + "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg=", + "dev": true + }, + "abs-svg-path": { + "version": "0.1.1", + "resolved": "http://127.0.0.1:8001/abs-svg-path/download/abs-svg-path-0.1.1.tgz", + "integrity": "sha1-32Acjo0roQ1KdtYl4japo5wnI78=" + }, + "acorn": { + "version": "6.0.4", + "resolved": "http://127.0.0.1:8001/acorn/download/acorn-6.0.4.tgz", + "integrity": "sha1-dzd+c1O3LsUQRVCqLSCXov1At1Q=", + "dev": true + }, + "acorn-jsx": { + "version": "5.0.0", + "resolved": "http://127.0.0.1:8001/acorn-jsx/download/acorn-jsx-5.0.0.tgz", + "integrity": "sha1-lYWE3bYJkMAsl8G9nVIfzkM7sQE=", + "dev": true + }, + "ajv": { + "version": "6.5.5", + "resolved": "http://127.0.0.1:8001/ajv/download/ajv-6.5.5.tgz", + "integrity": "sha1-z5fNreccY5mpLG1sQXc4EpG3gaE=", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "http://127.0.0.1:8001/ajv-keywords/download/ajv-keywords-3.5.2.tgz", + "integrity": "sha1-MfKdpatuANHC0yms97WSlhTVAU0=", + "dev": true + }, + "amdefine": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/amdefine/download/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-escapes": { + "version": "3.1.0", + "resolved": "http://127.0.0.1:8001/ansi-escapes/download/ansi-escapes-3.1.0.tgz", + "integrity": "sha1-9zIHu4EgfXX9bIPxJa8m7qN4yjA=", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "http://127.0.0.1:8001/ansi-regex/download/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "http://127.0.0.1:8001/ansi-styles/download/ansi-styles-3.2.1.tgz", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "http://127.0.0.1:8001/aproba/download/aproba-1.2.0.tgz", + "integrity": "sha1-aALmJk79GMeQobDVF/DyYnvyyUo=", + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "http://127.0.0.1:8001/are-we-there-yet/download/are-we-there-yet-1.1.5.tgz", + "integrity": "sha1-SzXClE8GKov82mZBB2A1D+nd/CE=", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "http://127.0.0.1:8001/readable-stream/download/readable-stream-2.3.7.tgz", + "integrity": "sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "http://127.0.0.1:8001/safe-buffer/download/safe-buffer-5.1.2.tgz", + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "http://127.0.0.1:8001/string_decoder/download/string_decoder-1.1.1.tgz", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "http://127.0.0.1:8001/argparse/download/argparse-1.0.10.tgz", + "integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/array-find-index/download/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-includes": { + "version": "3.1.1", + "resolved": "http://127.0.0.1:8001/array-includes/download/array-includes-3.1.1.tgz", + "integrity": "sha1-zdZ+aFK9+cEhVGB4ZzIlXtJFk0g=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/array-union/download/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "http://127.0.0.1:8001/array-uniq/download/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "http://127.0.0.1:8001/array.prototype.flat/download/array.prototype.flat-1.2.3.tgz", + "integrity": "sha1-DegrQmsDGNv9uUAInjiwQ9N/bHs=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/arrify/download/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "http://127.0.0.1:8001/asn1/download/asn1-0.2.4.tgz", + "integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/assert-plus/download/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "async-foreach": { + "version": "0.1.3", + "resolved": "http://127.0.0.1:8001/async-foreach/download/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "dev": true + }, + "async-validator": { + "version": "1.12.2", + "resolved": "http://127.0.0.1:8001/async-validator/download/async-validator-1.12.2.tgz", + "integrity": "sha1-vq5nHnF00pOLe0tp0vt+cit/1yw=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "http://127.0.0.1:8001/asynckit/download/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "http://127.0.0.1:8001/aws-sign2/download/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "http://127.0.0.1:8001/aws4/download/aws4-1.11.0.tgz", + "integrity": "sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk=", + "dev": true + }, + "axios": { + "version": "0.16.2", + "resolved": "http://127.0.0.1:8001/axios/download/axios-0.16.2.tgz", + "integrity": "sha1-uk+S8XFn37q0CYN4VFS5rBScPG0=", + "requires": { + "follow-redirects": "^1.2.3", + "is-buffer": "^1.1.5" + } + }, + "babel-eslint": { + "version": "10.1.0", + "resolved": "http://127.0.0.1:8001/babel-eslint/download/babel-eslint-10.1.0.tgz", + "integrity": "sha1-aWjlaKkQt4+zd5zdi2rC9HmUMjI=", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/balanced-match/download/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/bcrypt-pbkdf/download/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "big.js": { + "version": "5.2.2", + "resolved": "http://127.0.0.1:8001/big.js/download/big.js-5.2.2.tgz", + "integrity": "sha1-ZfCvOC9Xi83HQr2cKB6cstd2gyg=", + "dev": true + }, + "block-stream": { + "version": "0.0.9", + "resolved": "http://127.0.0.1:8001/block-stream/download/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true, + "requires": { + "inherits": "~2.0.0" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/boolbase/download/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "http://127.0.0.1:8001/brace-expansion/download/brace-expansion-1.1.11.tgz", + "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "http://127.0.0.1:8001/builtin-modules/download/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "call-bind": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/call-bind/download/call-bind-1.0.0.tgz", + "integrity": "sha1-JBJwVLs/m9y0sfuCQYGGBy93uM4=", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.0" + } + }, + "caller-path": { + "version": "0.1.0", + "resolved": "http://127.0.0.1:8001/caller-path/download/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "^0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "http://127.0.0.1:8001/callsites/download/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "camelcase": { + "version": "2.1.1", + "resolved": "http://127.0.0.1:8001/camelcase/download/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "http://127.0.0.1:8001/camelcase-keys/download/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "http://127.0.0.1:8001/caseless/download/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "2.4.1", + "resolved": "http://127.0.0.1:8001/chalk/download/chalk-2.4.1.tgz", + "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "http://127.0.0.1:8001/chardet/download/chardet-0.7.0.tgz", + "integrity": "sha1-kAlISfCTfy7twkJdDSip5fDLrZ4=", + "dev": true + }, + "chart.js": { + "version": "2.9.4", + "resolved": "http://127.0.0.1:8001/chart.js/download/chart.js-2.9.4.tgz", + "integrity": "sha1-CCf5Vj+v+y3FwGVi+OsQM31bloQ=", + "dev": true, + "requires": { + "chartjs-color": "^2.1.0", + "moment": "^2.10.2" + } + }, + "chartjs-color": { + "version": "2.4.1", + "resolved": "http://127.0.0.1:8001/chartjs-color/download/chartjs-color-2.4.1.tgz", + "integrity": "sha1-YRi7ogL+Hqed1/fA+dqTRnKWw7A=", + "dev": true, + "requires": { + "chartjs-color-string": "^0.6.0", + "color-convert": "^1.9.3" + } + }, + "chartjs-color-string": { + "version": "0.6.0", + "resolved": "http://127.0.0.1:8001/chartjs-color-string/download/chartjs-color-string-0.6.0.tgz", + "integrity": "sha1-HfCWYhwOcHIKZPQTXqFx0FFAL3E=", + "dev": true, + "requires": { + "color-name": "^1.0.0" + } + }, + "cheerio": { + "version": "1.0.0-rc.3", + "resolved": "http://127.0.0.1:8001/cheerio/download/cheerio-1.0.0-rc.3.tgz", + "integrity": "sha1-CUY21CWy6cD065GkbAVjDJoai/Y=", + "dev": true, + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.1", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash": "^4.15.0", + "parse5": "^3.0.1" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "http://127.0.0.1:8001/circular-json/download/circular-json-0.3.3.tgz", + "integrity": "sha1-gVyZ6oT2gJUp0vRXkb34JxE1LWY=", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "http://127.0.0.1:8001/cli-cursor/download/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "http://127.0.0.1:8001/cli-width/download/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "http://127.0.0.1:8001/cliui/download/cliui-5.0.0.tgz", + "integrity": "sha1-3u/P2y6AB4SqNPRvoI4GhRx7u8U=", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "http://127.0.0.1:8001/ansi-regex/download/ansi-regex-4.1.0.tgz", + "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "http://127.0.0.1:8001/string-width/download/string-width-3.1.0.tgz", + "integrity": "sha1-InZ74htirxCBV0MG9prFG2IgOWE=", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "http://127.0.0.1:8001/strip-ansi/download/strip-ansi-5.2.0.tgz", + "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "http://127.0.0.1:8001/wrap-ansi/download/wrap-ansi-5.1.0.tgz", + "integrity": "sha1-H9H2cjXVttD+54EFYAG/tpTAOwk=", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "http://127.0.0.1:8001/code-point-at/download/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "http://127.0.0.1:8001/color-convert/download/color-convert-1.9.3.tgz", + "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "http://127.0.0.1:8001/color-name/download/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "http://127.0.0.1:8001/combined-stream/download/combined-stream-1.0.8.tgz", + "integrity": "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.19.0", + "resolved": "http://127.0.0.1:8001/commander/download/commander-2.19.0.tgz", + "integrity": "sha1-9hmKqE5bg8RgVLlN3tv+1e6f8So=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "http://127.0.0.1:8001/concat-map/download/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "confusing-browser-globals": { + "version": "1.0.10", + "resolved": "http://127.0.0.1:8001/confusing-browser-globals/download/confusing-browser-globals-1.0.10.tgz", + "integrity": "sha1-MNHn89G4grJexJM9HRraw1PSClk=", + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "http://127.0.0.1:8001/console-control-strings/download/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "contains-path": { + "version": "0.1.0", + "resolved": "http://127.0.0.1:8001/contains-path/download/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "core-js-pure": { + "version": "3.6.5", + "resolved": "http://127.0.0.1:8001/core-js-pure/download/core-js-pure-3.6.5.tgz", + "integrity": "sha1-x5519eONvIWmYtke6lK4JW1TuBM=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/core-util-is/download/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "http://127.0.0.1:8001/cross-spawn/download/cross-spawn-6.0.5.tgz", + "integrity": "sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q=", + "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" + } + }, + "csp-html-webpack-plugin": { + "version": "4.0.0", + "resolved": "http://127.0.0.1:8001/csp-html-webpack-plugin/download/csp-html-webpack-plugin-4.0.0.tgz", + "integrity": "sha1-HtLNDe4jGGWH+WQghHFbFjNFtZs=", + "dev": true, + "requires": { + "cheerio": "^1.0.0-rc.3", + "lodash": "^4.17.15", + "memory-fs": "^0.5.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.20", + "resolved": "http://127.0.0.1:8001/lodash/download/lodash-4.17.20.tgz", + "integrity": "sha1-tEqbYpe8tpjxxRo1RaKzs2jVnFI=", + "dev": true + } + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "http://127.0.0.1:8001/css-select/download/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "dev": true, + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "http://127.0.0.1:8001/css-what/download/css-what-2.1.3.tgz", + "integrity": "sha1-ptdgRXM2X+dGhsPzEcVlE9iChfI=", + "dev": true + }, + "cssfilter": { + "version": "0.0.10", + "resolved": "http://127.0.0.1:8001/cssfilter/download/cssfilter-0.0.10.tgz", + "integrity": "sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4=" + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "http://127.0.0.1:8001/currently-unhandled/download/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "d3-array": { + "version": "2.8.0", + "resolved": "http://127.0.0.1:8001/d3-array/download/d3-array-2.8.0.tgz", + "integrity": "sha1-924QrUfx9PdfM9tfwyLrn/3l7yM=" + }, + "d3-collection": { + "version": "1.0.7", + "resolved": "http://127.0.0.1:8001/d3-collection/download/d3-collection-1.0.7.tgz", + "integrity": "sha1-NJvSqpl32wcQkcExRNXk8WtbMQ4=" + }, + "d3-color": { + "version": "1.4.1", + "resolved": "http://127.0.0.1:8001/d3-color/download/d3-color-1.4.1.tgz", + "integrity": "sha1-xSACv4hGraRCTVXZeYL+8m6zvIo=" + }, + "d3-composite-projections": { + "version": "1.4.0", + "resolved": "http://127.0.0.1:8001/d3-composite-projections/download/d3-composite-projections-1.4.0.tgz", + "integrity": "sha1-J7GC+mNaWGk0n+kRzgGAuXTRfxI=", + "requires": { + "d3-geo": "^2.0.1", + "d3-path": "^2.0.0" + }, + "dependencies": { + "d3-geo": { + "version": "2.0.1", + "resolved": "http://127.0.0.1:8001/d3-geo/download/d3-geo-2.0.1.tgz", + "integrity": "sha1-JDf9/tP+OrooEr2PMGCcrIOn7jk=", + "requires": { + "d3-array": ">=2.5" + } + } + } + }, + "d3-dsv": { + "version": "1.2.0", + "resolved": "http://127.0.0.1:8001/d3-dsv/download/d3-dsv-1.2.0.tgz", + "integrity": "sha1-nV91w6X4q9YR900/WEew1DOLiFw=", + "requires": { + "commander": "2", + "iconv-lite": "0.4", + "rw": "1" + } + }, + "d3-ease": { + "version": "1.0.7", + "resolved": "http://127.0.0.1:8001/d3-ease/download/d3-ease-1.0.7.tgz", + "integrity": "sha1-moNIkO+LiujFWLL+Vb1X9Zk7heI=" + }, + "d3-geo": { + "version": "1.6.4", + "resolved": "http://127.0.0.1:8001/d3-geo/download/d3-geo-1.6.4.tgz", + "integrity": "sha1-8g4eRhyxhF9ai+Vatvh2VCp+MZk=", + "requires": { + "d3-array": "1" + }, + "dependencies": { + "d3-array": { + "version": "1.2.4", + "resolved": "http://127.0.0.1:8001/d3-array/download/d3-array-1.2.4.tgz", + "integrity": "sha1-Y1zk1e6nWfb2BYY9vPww7cc39x8=" + } + } + }, + "d3-geo-projection": { + "version": "2.1.2", + "resolved": "http://127.0.0.1:8001/d3-geo-projection/download/d3-geo-projection-2.1.2.tgz", + "integrity": "sha1-ffjh6dBG1jHGUJ9+UxNX1K3CSqM=", + "requires": { + "commander": "2", + "d3-array": "1", + "d3-geo": "^1.1.0" + }, + "dependencies": { + "d3-array": { + "version": "1.2.4", + "resolved": "http://127.0.0.1:8001/d3-array/download/d3-array-1.2.4.tgz", + "integrity": "sha1-Y1zk1e6nWfb2BYY9vPww7cc39x8=" + } + } + }, + "d3-hexjson": { + "version": "1.1.0", + "resolved": "http://127.0.0.1:8001/d3-hexjson/download/d3-hexjson-1.1.0.tgz", + "integrity": "sha1-x+xYr7fEZnT14tq2PVWkL5Cr7gc=", + "requires": { + "d3-array": "1" + }, + "dependencies": { + "d3-array": { + "version": "1.2.4", + "resolved": "http://127.0.0.1:8001/d3-array/download/d3-array-1.2.4.tgz", + "integrity": "sha1-Y1zk1e6nWfb2BYY9vPww7cc39x8=" + } + } + }, + "d3-hierarchy": { + "version": "1.1.9", + "resolved": "http://127.0.0.1:8001/d3-hierarchy/download/d3-hierarchy-1.1.9.tgz", + "integrity": "sha1-L2vuJMqupD+Nw3VF+gFihVlkeoM=" + }, + "d3-interpolate": { + "version": "1.4.0", + "resolved": "http://127.0.0.1:8001/d3-interpolate/download/d3-interpolate-1.4.0.tgz", + "integrity": "sha1-Um554tgNqjg/ngwcHH3MDwWD6Yc=", + "requires": { + "d3-color": "1" + } + }, + "d3-path": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/d3-path/download/d3-path-2.0.0.tgz", + "integrity": "sha1-VdhqwTGgVIra4kHuv7VrRYLdCdg=" + }, + "d3-sankey": { + "version": "0.9.1", + "resolved": "http://127.0.0.1:8001/d3-sankey/download/d3-sankey-0.9.1.tgz", + "integrity": "sha1-uFAUWjKEERY23eyQ39qMZJGb7k4=", + "requires": { + "d3-array": "1", + "d3-collection": "1", + "d3-shape": "^1.2.0" + }, + "dependencies": { + "d3-array": { + "version": "1.2.4", + "resolved": "http://127.0.0.1:8001/d3-array/download/d3-array-1.2.4.tgz", + "integrity": "sha1-Y1zk1e6nWfb2BYY9vPww7cc39x8=" + } + } + }, + "d3-shape": { + "version": "1.3.7", + "resolved": "http://127.0.0.1:8001/d3-shape/download/d3-shape-1.3.7.tgz", + "integrity": "sha1-32OAG+B7yYa8VPY3ibT+UCmStdc=", + "requires": { + "d3-path": "1" + }, + "dependencies": { + "d3-path": { + "version": "1.0.9", + "resolved": "http://127.0.0.1:8001/d3-path/download/d3-path-1.0.9.tgz", + "integrity": "sha1-SMBQux/owmJJOoyvVSTj6VkXAc8=" + } + } + }, + "d3-timer": { + "version": "1.0.10", + "resolved": "http://127.0.0.1:8001/d3-timer/download/d3-timer-1.0.10.tgz", + "integrity": "sha1-3+dripF0iDGxO22ceT/71QjdneU=" + }, + "d3-voronoi": { + "version": "1.1.4", + "resolved": "http://127.0.0.1:8001/d3-voronoi/download/d3-voronoi-1.1.4.tgz", + "integrity": "sha1-3Tx412U9K7NZKErkeGRdlZRMgpc=" + }, + "dagre": { + "version": "0.8.5", + "resolved": "http://127.0.0.1:8001/dagre/download/dagre-0.8.5.tgz", + "integrity": "sha1-ujCwBV2sErbB/MJHgXRCd30Gr+4=", + "requires": { + "graphlib": "^2.1.8", + "lodash": "^4.17.15" + }, + "dependencies": { + "lodash": { + "version": "4.17.20", + "resolved": "http://127.0.0.1:8001/lodash/download/lodash-4.17.20.tgz", + "integrity": "sha1-tEqbYpe8tpjxxRo1RaKzs2jVnFI=" + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "http://127.0.0.1:8001/dashdash/download/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "de-indent": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/de-indent/download/de-indent-1.0.2.tgz", + "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=" + }, + "debug": { + "version": "4.1.0", + "resolved": "http://127.0.0.1:8001/debug/download/debug-4.1.0.tgz", + "integrity": "sha1-NzaHv/pnizixzZH4YbY4UANd3Ic=", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "http://127.0.0.1:8001/decamelize/download/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "http://127.0.0.1:8001/deep-is/download/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "http://127.0.0.1:8001/define-properties/download/define-properties-1.1.3.tgz", + "integrity": "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE=", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "del": { + "version": "2.2.2", + "resolved": "http://127.0.0.1:8001/del/download/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/delayed-stream/download/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/delegates/download/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "detect-browser": { + "version": "5.2.0", + "resolved": "http://127.0.0.1:8001/detect-browser/download/detect-browser-5.2.0.tgz", + "integrity": "sha1-yc1a+pamoZ/aC76em+SKa24enJc=" + }, + "doctrine": { + "version": "2.1.0", + "resolved": "http://127.0.0.1:8001/doctrine/download/doctrine-2.1.0.tgz", + "integrity": "sha1-XNAfwQFiG0LEzX9dGmYkNxbT850=", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "http://127.0.0.1:8001/dom-serializer/download/dom-serializer-0.1.1.tgz", + "integrity": "sha1-HsQFnihLq+027sKUHUqXChic58A=", + "dev": true, + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "http://127.0.0.1:8001/domelementtype/download/domelementtype-1.3.1.tgz", + "integrity": "sha1-0EjESzew0Qp/Kj1f7j9DM9eQSB8=", + "dev": true + }, + "domhandler": { + "version": "2.4.2", + "resolved": "http://127.0.0.1:8001/domhandler/download/domhandler-2.4.2.tgz", + "integrity": "sha1-iAUJfpM9ZehVRvcm1g9euItE+AM=", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "http://127.0.0.1:8001/domutils/download/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "http://127.0.0.1:8001/ecc-jsbn/download/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "http://127.0.0.1:8001/emoji-regex/download/emoji-regex-7.0.3.tgz", + "integrity": "sha1-kzoEBShgyF6DwSJHnEdIqOTHIVY=", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "http://127.0.0.1:8001/emojis-list/download/emojis-list-3.0.0.tgz", + "integrity": "sha1-VXBmIEatKeLpFucariYKvf9Pang=", + "dev": true + }, + "entities": { + "version": "1.1.2", + "resolved": "http://127.0.0.1:8001/entities/download/entities-1.1.2.tgz", + "integrity": "sha1-vfpzUplmTfr9NFKe1PhSKidf6lY=", + "dev": true + }, + "errno": { + "version": "0.1.7", + "resolved": "http://127.0.0.1:8001/errno/download/errno-0.1.7.tgz", + "integrity": "sha1-RoTXF3mtOa8Xfj8AeZb3xnyFJhg=", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "http://127.0.0.1:8001/error-ex/download/error-ex-1.3.2.tgz", + "integrity": "sha1-tKxAZIEH/c3PriQvQovqihTU8b8=", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.17.7", + "resolved": "http://127.0.0.1:8001/es-abstract/download/es-abstract-1.17.7.tgz", + "integrity": "sha1-pN5hsvZpifx0IWdsHLl4dXOs5Uw=", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "http://127.0.0.1:8001/es-to-primitive/download/es-to-primitive-1.2.1.tgz", + "integrity": "sha1-5VzUyc3BiLzvsDs2bHNjI/xciYo=", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "http://127.0.0.1:8001/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "5.8.0", + "resolved": "http://127.0.0.1:8001/eslint/download/eslint-5.8.0.tgz", + "integrity": "sha1-kfvyT24Ecej99oGk2d0bLJ8oMJs=", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.5.3", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^2.1.0", + "eslint-scope": "^4.0.0", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^4.0.0", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "imurmurhash": "^0.1.4", + "inquirer": "^6.1.0", + "is-resolvable": "^1.1.0", + "js-yaml": "^3.12.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.5", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.0.2", + "text-table": "^0.2.0" + } + }, + "eslint-config-airbnb-base": { + "version": "13.2.0", + "resolved": "http://127.0.0.1:8001/eslint-config-airbnb-base/download/eslint-config-airbnb-base-13.2.0.tgz", + "integrity": "sha1-9uqBRZ/03sLdogDDXx2PdBnVeUM=", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.5", + "object.assign": "^4.1.0", + "object.entries": "^1.1.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "http://127.0.0.1:8001/eslint-import-resolver-node/download/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha1-hf+oGULCUBLYIxCW3fZ5wDBCxxc=", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "http://127.0.0.1:8001/debug/download/debug-2.6.9.tgz", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/ms/download/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.6.0", + "resolved": "http://127.0.0.1:8001/eslint-module-utils/download/eslint-module-utils-2.6.0.tgz", + "integrity": "sha1-V569CU9Wr3eX0ZyYZsnJSGYpv6Y=", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "http://127.0.0.1:8001/debug/download/debug-2.6.9.tgz", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "http://127.0.0.1:8001/find-up/download/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/locate-path/download/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/ms/download/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "http://127.0.0.1:8001/p-limit/download/p-limit-1.3.0.tgz", + "integrity": "sha1-uGvV8MJWkJEcdZD8v8IBDVSzzLg=", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/p-locate/download/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/p-try/download/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/pkg-dir/download/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.22.1", + "resolved": "http://127.0.0.1:8001/eslint-plugin-import/download/eslint-plugin-import-2.22.1.tgz", + "integrity": "sha1-CJbH5qDPRBCaLZe5WQPCu2iddwI=", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-module-utils": "^2.6.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.1", + "read-pkg-up": "^2.0.0", + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "http://127.0.0.1:8001/debug/download/debug-2.6.9.tgz", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "http://127.0.0.1:8001/doctrine/download/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/ms/download/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-scope": { + "version": "4.0.0", + "resolved": "http://127.0.0.1:8001/eslint-scope/download/eslint-scope-4.0.0.tgz", + "integrity": "sha1-UL8wcekzi83EMzF5Sgy1M/ATYXI=", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "http://127.0.0.1:8001/eslint-utils/download/eslint-utils-1.3.1.tgz", + "integrity": "sha1-moUbqJ7nxGA0b5fPiTnHKYgn5RI=", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/eslint-visitor-keys/download/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha1-PzGA+y4pEBdxastMnW1bXDSmqB0=", + "dev": true + }, + "espree": { + "version": "4.1.0", + "resolved": "http://127.0.0.1:8001/espree/download/espree-4.1.0.tgz", + "integrity": "sha1-co1UUeD9FWwEOEp62J7VH/VOsl8=", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "http://127.0.0.1:8001/esprima/download/esprima-4.0.1.tgz", + "integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE=", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/esquery/download/esquery-1.0.1.tgz", + "integrity": "sha1-QGxRZYsfWZGl+bYrHcJbAOPlxwg=", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "http://127.0.0.1:8001/esrecurse/download/esrecurse-4.2.1.tgz", + "integrity": "sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8=", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "http://127.0.0.1:8001/estraverse/download/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "http://127.0.0.1:8001/esutils/download/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "http://127.0.0.1:8001/extend/download/extend-3.0.2.tgz", + "integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=", + "dev": true + }, + "external-editor": { + "version": "3.0.3", + "resolved": "http://127.0.0.1:8001/external-editor/download/external-editor-3.0.3.tgz", + "integrity": "sha1-WGbbKal4Jtvkvzr9JAcOrZ6kOic=", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "http://127.0.0.1:8001/extsprintf/download/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "http://127.0.0.1:8001/fast-deep-equal/download/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/fast-json-stable-stringify/download/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "http://127.0.0.1:8001/fast-levenshtein/download/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fecha": { + "version": "4.2.0", + "resolved": "http://127.0.0.1:8001/fecha/download/fecha-4.2.0.tgz", + "integrity": "sha1-P/tjlUU+Pz7/+FBATwpZtnR/X0E=" + }, + "figures": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/figures/download/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/file-entry-cache/download/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "http://127.0.0.1:8001/find-up/download/find-up-3.0.0.tgz", + "integrity": "sha1-SRafHXmTQwZG2mHsxa41XCHJe3M=", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "http://127.0.0.1:8001/flat-cache/download/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" + } + }, + "follow-redirects": { + "version": "1.12.1", + "resolved": "http://127.0.0.1:8001/follow-redirects/download/follow-redirects-1.12.1.tgz", + "integrity": "sha1-3lSmIFMRuT1gOY68Ac9wFWgjErY=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "http://127.0.0.1:8001/forever-agent/download/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "http://127.0.0.1:8001/form-data/download/form-data-2.3.3.tgz", + "integrity": "sha1-3M5SwF9kTymManq5Nr1yTO/786Y=", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/fs.realpath/download/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fstream": { + "version": "1.0.12", + "resolved": "http://127.0.0.1:8001/fstream/download/fstream-1.0.12.tgz", + "integrity": "sha1-Touo7i1Ivk99DeUFRVVI6uWTIEU=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "http://127.0.0.1:8001/function-bind/download/function-bind-1.1.1.tgz", + "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/functional-red-black-tree/download/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "http://127.0.0.1:8001/gauge/download/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "http://127.0.0.1:8001/ansi-regex/download/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/is-fullwidth-code-point/download/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/string-width/download/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://127.0.0.1:8001/strip-ansi/download/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "gaze": { + "version": "1.1.3", + "resolved": "http://127.0.0.1:8001/gaze/download/gaze-1.1.3.tgz", + "integrity": "sha1-xEFzPhO5J6yMD/C0w7Az8ogSkko=", + "dev": true, + "requires": { + "globule": "^1.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "http://127.0.0.1:8001/get-caller-file/download/get-caller-file-2.0.5.tgz", + "integrity": "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34=", + "dev": true + }, + "get-intrinsic": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/get-intrinsic/download/get-intrinsic-1.0.1.tgz", + "integrity": "sha1-lKl2j8vdBZWhySc6rPTInQdWMb4=", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "http://127.0.0.1:8001/getpass/download/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "gl-matrix": { + "version": "3.3.0", + "resolved": "http://127.0.0.1:8001/gl-matrix/download/gl-matrix-3.3.0.tgz", + "integrity": "sha1-Iy7vYLHIswooy751ssr2xI/WNYs=" + }, + "glob": { + "version": "7.1.3", + "resolved": "http://127.0.0.1:8001/glob/download/glob-7.1.3.tgz", + "integrity": "sha1-OWCDLT8VdBCDQtr9OmezMsCWnfE=", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globals": { + "version": "11.8.0", + "resolved": "http://127.0.0.1:8001/globals/download/globals-11.8.0.tgz", + "integrity": "sha1-we9F7pvta63wZjxcuQ6NGt7BMh0=", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "http://127.0.0.1:8001/globby/download/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "globule": { + "version": "1.3.2", + "resolved": "http://127.0.0.1:8001/globule/download/globule-1.3.2.tgz", + "integrity": "sha1-2L3Z6eTu+PluJFmZpd7n612FKcQ=", + "dev": true, + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + } + }, + "graceful-fs": { + "version": "4.1.14", + "resolved": "http://127.0.0.1:8001/graceful-fs/download/graceful-fs-4.1.14.tgz", + "integrity": "sha1-G26DYu+MXstdp5mQHzkpfjBUdzo=", + "dev": true + }, + "graphlib": { + "version": "2.1.8", + "resolved": "http://127.0.0.1:8001/graphlib/download/graphlib-2.1.8.tgz", + "integrity": "sha1-V2HUFHN4cAhMkux7XbywWSydNdo=", + "requires": { + "lodash": "^4.17.15" + }, + "dependencies": { + "lodash": { + "version": "4.17.20", + "resolved": "http://127.0.0.1:8001/lodash/download/lodash-4.17.20.tgz", + "integrity": "sha1-tEqbYpe8tpjxxRo1RaKzs2jVnFI=" + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/har-schema/download/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "http://127.0.0.1:8001/har-validator/download/har-validator-5.1.5.tgz", + "integrity": "sha1-HwgDufjLIMD6E4It8ezds2veHv0=", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "http://127.0.0.1:8001/ajv/download/ajv-6.12.6.tgz", + "integrity": "sha1-uvWmLoArB9l3A0WG+MO69a3ybfQ=", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "http://127.0.0.1:8001/fast-deep-equal/download/fast-deep-equal-3.1.3.tgz", + "integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=", + "dev": true + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "http://127.0.0.1:8001/has/download/has-1.0.3.tgz", + "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/has-ansi/download/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "http://127.0.0.1:8001/ansi-regex/download/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "http://127.0.0.1:8001/has-flag/download/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/has-symbols/download/has-symbols-1.0.1.tgz", + "integrity": "sha1-n1IUdYpEGWxAbZvXbOv4HsLdMeg=", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "http://127.0.0.1:8001/has-unicode/download/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "http://127.0.0.1:8001/he/download/he-1.2.0.tgz", + "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=" + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "http://127.0.0.1:8001/hosted-git-info/download/hosted-git-info-2.7.1.tgz", + "integrity": "sha1-l/I2l3vW4SVAiTD/bePuxigewEc=", + "dev": true + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "http://127.0.0.1:8001/htmlparser2/download/htmlparser2-3.10.1.tgz", + "integrity": "sha1-vWedw/WYl7ajS7EHSchVu1OpOS8=", + "dev": true, + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "http://127.0.0.1:8001/http-signature/download/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "http://127.0.0.1:8001/iconv-lite/download/iconv-lite-0.4.24.tgz", + "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "http://127.0.0.1:8001/ignore/download/ignore-4.0.6.tgz", + "integrity": "sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "http://127.0.0.1:8001/imurmurhash/download/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "in-publish": { + "version": "2.0.1", + "resolved": "http://127.0.0.1:8001/in-publish/download/in-publish-2.0.1.tgz", + "integrity": "sha1-lIsaU1yAMFYc6lIvc/ePS+NX4Aw=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "http://127.0.0.1:8001/inflight/download/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "http://127.0.0.1:8001/inherits/download/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inquirer": { + "version": "6.2.0", + "resolved": "http://127.0.0.1:8001/inquirer/download/inquirer-6.2.0.tgz", + "integrity": "sha1-Ua3Nd29mE2ncHolIWcJWCiJKvdg=", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.0", + "figures": "^2.0.0", + "lodash": "^4.17.10", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.1.0", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "http://127.0.0.1:8001/is-arrayish/download/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "http://127.0.0.1:8001/is-buffer/download/is-buffer-1.1.6.tgz", + "integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=" + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/is-builtin-module/download/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.2", + "resolved": "http://127.0.0.1:8001/is-callable/download/is-callable-1.2.2.tgz", + "integrity": "sha1-x8ZxXNItTdtI0+GZcCI6zquwgNk=", + "dev": true + }, + "is-core-module": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/is-core-module/download/is-core-module-2.0.0.tgz", + "integrity": "sha1-WFMbcK7R23wOjU6xoKLR3dZL0S0=", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/is-date-object/download/is-date-object-1.0.2.tgz", + "integrity": "sha1-vac28s2P0G0yhE53Q7+nSUw7/X4=", + "dev": true + }, + "is-finite": { + "version": "1.1.0", + "resolved": "http://127.0.0.1:8001/is-finite/download/is-finite-1.1.0.tgz", + "integrity": "sha1-kEE1x3+0LAZB1qobzbxNqo2ggvM=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/is-fullwidth-code-point/download/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/is-negative-zero/download/is-negative-zero-2.0.0.tgz", + "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", + "dev": true + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/is-path-cwd/download/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/is-path-in-cwd/download/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha1-WsSLNF72dTOb1sekipEhELJBz1I=", + "dev": true, + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/is-path-inside/download/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "http://127.0.0.1:8001/is-promise/download/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "http://127.0.0.1:8001/is-regex/download/is-regex-1.1.1.tgz", + "integrity": "sha1-xvmKrMVG9s7FRooHt7FTq1ZKV7k=", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "http://127.0.0.1:8001/is-resolvable/download/is-resolvable-1.1.0.tgz", + "integrity": "sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg=", + "dev": true + }, + "is-string": { + "version": "1.0.5", + "resolved": "http://127.0.0.1:8001/is-string/download/is-string-1.0.5.tgz", + "integrity": "sha1-QEk+0ZjvP/R3uMf5L2ROyCpc06Y=", + "dev": true + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "http://127.0.0.1:8001/is-symbol/download/is-symbol-1.0.3.tgz", + "integrity": "sha1-OOEBS55jKb4N6dJKQU/XRB7GGTc=", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/is-typedarray/download/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "http://127.0.0.1:8001/is-utf8/download/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/isarray/download/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/isexe/download/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "http://127.0.0.1:8001/isstream/download/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "js-base64": { + "version": "2.6.4", + "resolved": "http://127.0.0.1:8001/js-base64/download/js-base64-2.6.4.tgz", + "integrity": "sha1-9OaGxd4eofhn28rT1G2WlCjfmMQ=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "http://127.0.0.1:8001/js-tokens/download/js-tokens-4.0.0.tgz", + "integrity": "sha1-GSA/tZmR35jjoocFDUZHzerzJJk=", + "dev": true + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "http://127.0.0.1:8001/js-yaml/download/js-yaml-3.12.0.tgz", + "integrity": "sha1-6u1lbsg0TxD1J8a/obbiJE3hZ9E=", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "http://127.0.0.1:8001/jsbn/download/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "http://127.0.0.1:8001/jsesc/download/jsesc-2.5.2.tgz", + "integrity": "sha1-gFZNLkg9rPbo7yCWUKZ98/DCg6Q=", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "http://127.0.0.1:8001/json-schema/download/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "http://127.0.0.1:8001/json-schema-traverse/download/json-schema-traverse-0.4.1.tgz", + "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/json-stable-stringify-without-jsonify/download/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "http://127.0.0.1:8001/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/json5/download/json5-1.0.1.tgz", + "integrity": "sha1-d5+wAYYE+oVOrL9iUhgNg1Q+Pb4=", + "dev": true, + "requires": { + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "http://127.0.0.1:8001/minimist/download/minimist-1.2.5.tgz", + "integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI=", + "dev": true + } + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "http://127.0.0.1:8001/jsprim/download/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "klona": { + "version": "2.0.4", + "resolved": "http://127.0.0.1:8001/klona/download/klona-2.0.4.tgz", + "integrity": "sha1-e7Hjr/sMuGJFR+9+j2cI6i4538A=", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "http://127.0.0.1:8001/levn/download/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/load-json-file/download/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "parse-json": { + "version": "2.2.0", + "resolved": "http://127.0.0.1:8001/parse-json/download/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + } + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/loader-utils/download/loader-utils-2.0.0.tgz", + "integrity": "sha1-5MrOW4FtQloWa18JfhDNErNgZLA=", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "dependencies": { + "json5": { + "version": "2.1.3", + "resolved": "http://127.0.0.1:8001/json5/download/json5-2.1.3.tgz", + "integrity": "sha1-ybD3+pIzv+WAf+ZvzzpWF+1ZfUM=", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "http://127.0.0.1:8001/minimist/download/minimist-1.2.5.tgz", + "integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI=", + "dev": true + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "http://127.0.0.1:8001/locate-path/download/locate-path-3.0.0.tgz", + "integrity": "sha1-2+w7OrdZdYBxtY/ln8QYca8hQA4=", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "http://127.0.0.1:8001/lodash/download/lodash-4.17.11.tgz", + "integrity": "sha1-s56mIp72B+zYniyN8SU2iRysm40=" + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "http://127.0.0.1:8001/loud-rejection/download/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "http://127.0.0.1:8001/lru-cache/download/lru-cache-4.1.5.tgz", + "integrity": "sha1-i75Q6oW+1ZvJ4z3KuCNe6bz0Q80=", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/map-obj/download/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "memory-fs": { + "version": "0.5.0", + "resolved": "http://127.0.0.1:8001/memory-fs/download/memory-fs-0.5.0.tgz", + "integrity": "sha1-MkwBKIuIZSlm0WHbd4OHIIRajjw=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "http://127.0.0.1:8001/readable-stream/download/readable-stream-2.3.7.tgz", + "integrity": "sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "http://127.0.0.1:8001/safe-buffer/download/safe-buffer-5.1.2.tgz", + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "http://127.0.0.1:8001/string_decoder/download/string_decoder-1.1.1.tgz", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "meow": { + "version": "3.7.0", + "resolved": "http://127.0.0.1:8001/meow/download/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "http://127.0.0.1:8001/find-up/download/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "http://127.0.0.1:8001/load-json-file/download/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "http://127.0.0.1:8001/minimist/download/minimist-1.2.5.tgz", + "integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI=", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "resolved": "http://127.0.0.1:8001/parse-json/download/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "http://127.0.0.1:8001/path-exists/download/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "http://127.0.0.1:8001/path-type/download/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "http://127.0.0.1:8001/read-pkg/download/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/read-pkg-up/download/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/strip-bom/download/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + } + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "http://127.0.0.1:8001/mime-db/download/mime-db-1.44.0.tgz", + "integrity": "sha1-+hHF6wrKEzS0Izy01S8QxaYnL5I=", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "http://127.0.0.1:8001/mime-types/download/mime-types-2.1.27.tgz", + "integrity": "sha1-R5SfmOJ56lMRn1ci4PNOUpvsAJ8=", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "http://127.0.0.1:8001/mimic-fn/download/mimic-fn-1.2.0.tgz", + "integrity": "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "http://127.0.0.1:8001/minimatch/download/minimatch-3.0.4.tgz", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "http://127.0.0.1:8001/minimist/download/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://127.0.0.1:8001/mkdirp/download/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "moment": { + "version": "2.29.1", + "resolved": "http://127.0.0.1:8001/moment/download/moment-2.29.1.tgz", + "integrity": "sha1-sr52n6MZQL6e7qZGnAdeNQBvo9M=", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "http://127.0.0.1:8001/ms/download/ms-2.1.1.tgz", + "integrity": "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo=", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "http://127.0.0.1:8001/mute-stream/download/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "nan": { + "version": "2.14.2", + "resolved": "http://127.0.0.1:8001/nan/download/nan-2.14.2.tgz", + "integrity": "sha1-9TdkAGlRaPTMaUrJOT0MlYXu6hk=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "http://127.0.0.1:8001/natural-compare/download/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "http://127.0.0.1:8001/neo-async/download/neo-async-2.6.2.tgz", + "integrity": "sha1-tKr7k+OustgXTKU88WOrfXMIMF8=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "http://127.0.0.1:8001/nice-try/download/nice-try-1.0.5.tgz", + "integrity": "sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y=", + "dev": true + }, + "node-gyp": { + "version": "3.8.0", + "resolved": "http://127.0.0.1:8001/node-gyp/download/node-gyp-3.8.0.tgz", + "integrity": "sha1-VAMEJhwzDoDQ1e3OJTpoyzlkIYw=", + "dev": true, + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "http://127.0.0.1:8001/semver/download/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + } + } + }, + "node-sass": { + "version": "4.14.1", + "resolved": "http://127.0.0.1:8001/node-sass/download/node-sass-4.14.1.tgz", + "integrity": "sha1-mch+wu+3BH7WOPtMnbfzpC4iF7U=", + "dev": true, + "requires": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^3.0.0", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "in-publish": "^2.0.0", + "lodash": "^4.17.15", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^3.8.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "2.2.5", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "http://127.0.0.1:8001/ansi-regex/download/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "http://127.0.0.1:8001/ansi-styles/download/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://127.0.0.1:8001/chalk/download/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "cross-spawn": { + "version": "3.0.1", + "resolved": "http://127.0.0.1:8001/cross-spawn/download/cross-spawn-3.0.1.tgz", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "http://127.0.0.1:8001/get-stdin/download/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "lodash": { + "version": "4.17.20", + "resolved": "http://127.0.0.1:8001/lodash/download/lodash-4.17.20.tgz", + "integrity": "sha1-tEqbYpe8tpjxxRo1RaKzs2jVnFI=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://127.0.0.1:8001/strip-ansi/download/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/supports-color/download/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "http://127.0.0.1:8001/nopt/download/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "http://127.0.0.1:8001/normalize-package-data/download/normalize-package-data-2.4.0.tgz", + "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "http://127.0.0.1:8001/npmlog/download/npmlog-4.1.2.tgz", + "integrity": "sha1-CKfyqL9zRgR3mp76StXMcXq7lUs=", + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/nth-check/download/nth-check-1.0.2.tgz", + "integrity": "sha1-sr0pXDfj3VijvwcAN2Zjuk2c8Fw=", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/number-is-nan/download/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "http://127.0.0.1:8001/oauth-sign/download/oauth-sign-0.9.0.tgz", + "integrity": "sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "http://127.0.0.1:8001/object-assign/download/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-inspect": { + "version": "1.8.0", + "resolved": "http://127.0.0.1:8001/object-inspect/download/object-inspect-1.8.0.tgz", + "integrity": "sha1-34B+Xs9TpgnMa/6T6sPMe+WzqdA=", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "http://127.0.0.1:8001/object-keys/download/object-keys-1.1.1.tgz", + "integrity": "sha1-HEfyct8nfzsdrwYWd9nILiMixg4=", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "http://127.0.0.1:8001/object.assign/download/object.assign-4.1.2.tgz", + "integrity": "sha1-DtVKNC7Os3s4/3brgxoOeIy2OUA=", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.entries": { + "version": "1.1.2", + "resolved": "http://127.0.0.1:8001/object.entries/download/object.entries-1.1.2.tgz", + "integrity": "sha1-vHPwCstra7FsIDQ0sQ+afnl9Ot0=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "has": "^1.0.3" + } + }, + "object.values": { + "version": "1.1.1", + "resolved": "http://127.0.0.1:8001/object.values/download/object.values-1.1.1.tgz", + "integrity": "sha1-aKmezeNWt+kpWjxeDOMdyMlT3l4=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "once": { + "version": "1.4.0", + "resolved": "http://127.0.0.1:8001/once/download/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "http://127.0.0.1:8001/onetime/download/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "http://127.0.0.1:8001/optionator/download/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/os-homedir/download/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/os-tmpdir/download/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "http://127.0.0.1:8001/osenv/download/osenv-0.1.5.tgz", + "integrity": "sha1-hc36+uso6Gd/QW4odZK18/SepBA=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-limit": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/p-limit/download/p-limit-2.0.0.tgz", + "integrity": "sha1-5iTtVO6MRgp3izyfNnBJb/ileuw=", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "http://127.0.0.1:8001/p-locate/download/p-locate-3.0.0.tgz", + "integrity": "sha1-Mi1poFwCZLJZl9n0DNiokasAZKQ=", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/p-try/download/p-try-2.0.0.tgz", + "integrity": "sha1-hQgLuHxkaI+keZb+j3376CEXYLE=", + "dev": true + }, + "parse-svg-path": { + "version": "0.1.2", + "resolved": "http://127.0.0.1:8001/parse-svg-path/download/parse-svg-path-0.1.2.tgz", + "integrity": "sha1-en7A0esG+lMlx9PgCbhZoJtdSes=" + }, + "parse5": { + "version": "3.0.3", + "resolved": "http://127.0.0.1:8001/parse5/download/parse5-3.0.3.tgz", + "integrity": "sha1-BC95L/3TaFFVHPTp4Gazh0q0W1w=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "http://127.0.0.1:8001/path-exists/download/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/path-is-absolute/download/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/path-is-inside/download/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "http://127.0.0.1:8001/path-key/download/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "http://127.0.0.1:8001/path-parse/download/path-parse-1.0.6.tgz", + "integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/path-type/download/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "http://127.0.0.1:8001/performance-now/download/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "http://127.0.0.1:8001/pify/download/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "http://127.0.0.1:8001/pinkie/download/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "http://127.0.0.1:8001/pinkie-promise/download/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pluralize": { + "version": "7.0.0", + "resolved": "http://127.0.0.1:8001/pluralize/download/pluralize-7.0.0.tgz", + "integrity": "sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c=", + "dev": true + }, + "point-at-length": { + "version": "1.1.0", + "resolved": "http://127.0.0.1:8001/point-at-length/download/point-at-length-1.1.0.tgz", + "integrity": "sha1-CtcuvQmA1/WhqxIpbAVfnrazDlc=", + "requires": { + "abs-svg-path": "~0.1.1", + "isarray": "~0.0.1", + "parse-svg-path": "~0.1.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "http://127.0.0.1:8001/isarray/download/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + } + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "http://127.0.0.1:8001/prelude-ls/download/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "http://127.0.0.1:8001/process-nextick-args/download/process-nextick-args-2.0.1.tgz", + "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=", + "dev": true + }, + "progress": { + "version": "2.0.1", + "resolved": "http://127.0.0.1:8001/progress/download/progress-2.0.1.tgz", + "integrity": "sha1-ySQhaTQrHCnSdYiclXNGIbGVLjE=", + "dev": true + }, + "prr": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/prr/download/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/pseudomap/download/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.8.0", + "resolved": "http://127.0.0.1:8001/psl/download/psl-1.8.0.tgz", + "integrity": "sha1-kyb4vPsBOtzABf3/BWrM4CDlHCQ=", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "http://127.0.0.1:8001/punycode/download/punycode-2.1.1.tgz", + "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "http://127.0.0.1:8001/qs/download/qs-6.5.2.tgz", + "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=", + "dev": true + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/read-pkg-up/download/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "http://127.0.0.1:8001/find-up/download/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/locate-path/download/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "http://127.0.0.1:8001/p-limit/download/p-limit-1.3.0.tgz", + "integrity": "sha1-uGvV8MJWkJEcdZD8v8IBDVSzzLg=", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/p-locate/download/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/p-try/download/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/read-pkg/download/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + } + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "http://127.0.0.1:8001/readable-stream/download/readable-stream-3.6.0.tgz", + "integrity": "sha1-M3u9o63AcGvT4CRCaihtS0sskZg=", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/redent/download/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + }, + "dependencies": { + "indent-string": { + "version": "2.1.0", + "resolved": "http://127.0.0.1:8001/indent-string/download/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + } + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "http://127.0.0.1:8001/regenerator-runtime/download/regenerator-runtime-0.13.7.tgz", + "integrity": "sha1-ysLazIoepnX+qrrriugziYrkb1U=" + }, + "regexpp": { + "version": "2.0.1", + "resolved": "http://127.0.0.1:8001/regexpp/download/regexpp-2.0.1.tgz", + "integrity": "sha1-jRnTHPYySCtYkEn4KB+T28uk0H8=", + "dev": true + }, + "regression": { + "version": "2.0.1", + "resolved": "http://127.0.0.1:8001/regression/download/regression-2.0.1.tgz", + "integrity": "sha1-jSnD6CJKEIUMNeM36FqLL6w7DIc=" + }, + "repeating": { + "version": "2.0.1", + "resolved": "http://127.0.0.1:8001/repeating/download/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "request": { + "version": "2.88.2", + "resolved": "http://127.0.0.1:8001/request/download/request-2.88.2.tgz", + "integrity": "sha1-1zyRhzHLWofaBH4gcjQUb2ZNErM=", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "http://127.0.0.1:8001/require-directory/download/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/require-main-filename/download/require-main-filename-2.0.0.tgz", + "integrity": "sha1-0LMp7MfMD2Fkn2IhW+aa9UqomJs=", + "dev": true + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "http://127.0.0.1:8001/require-uncached/download/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + } + }, + "resolve": { + "version": "1.18.1", + "resolved": "http://127.0.0.1:8001/resolve/download/resolve-1.18.1.tgz", + "integrity": "sha1-AY/LLFsgfSpkJK7jYcWiZtqPQTA=", + "dev": true, + "requires": { + "is-core-module": "^2.0.0", + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/resolve-from/download/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/restore-cursor/download/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "http://127.0.0.1:8001/rimraf/download/rimraf-2.6.2.tgz", + "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", + "dev": true, + "requires": { + "glob": "^7.0.5" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "http://127.0.0.1:8001/run-async/download/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rw": { + "version": "1.3.3", + "resolved": "http://127.0.0.1:8001/rw/download/rw-1.3.3.tgz", + "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" + }, + "rxjs": { + "version": "6.3.3", + "resolved": "http://127.0.0.1:8001/rxjs/download/rxjs-6.3.3.tgz", + "integrity": "sha1-PGp/pCDoRKgTkPsRWKnsYU9LrVU=", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "http://127.0.0.1:8001/safe-buffer/download/safe-buffer-5.2.1.tgz", + "integrity": "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY=", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "http://127.0.0.1:8001/safer-buffer/download/safer-buffer-2.1.2.tgz", + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=" + }, + "sass-graph": { + "version": "2.2.5", + "resolved": "http://127.0.0.1:8001/sass-graph/download/sass-graph-2.2.5.tgz", + "integrity": "sha1-qYHIdEa4MZ2W3OBnHkh4eb0kwug=", + "dev": true, + "requires": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^13.3.2" + } + }, + "sass-loader": { + "version": "10.0.5", + "resolved": "http://127.0.0.1:8001/sass-loader/download/sass-loader-10.0.5.tgz", + "integrity": "sha1-9TUFtd2+30N5dHDOs0Bm3tgrt2k=", + "dev": true, + "requires": { + "klona": "^2.0.4", + "loader-utils": "^2.0.0", + "neo-async": "^2.6.2", + "schema-utils": "^3.0.0", + "semver": "^7.3.2" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "http://127.0.0.1:8001/semver/download/semver-7.3.2.tgz", + "integrity": "sha1-YElisFK4HtB4aq6EOJ/7pw/9OTg=", + "dev": true + } + } + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "http://127.0.0.1:8001/schema-utils/download/schema-utils-3.0.0.tgz", + "integrity": "sha1-Z1AvaqK2ai1AMrQnmilEl4oJE+8=", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "http://127.0.0.1:8001/ajv/download/ajv-6.12.6.tgz", + "integrity": "sha1-uvWmLoArB9l3A0WG+MO69a3ybfQ=", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "http://127.0.0.1:8001/fast-deep-equal/download/fast-deep-equal-3.1.3.tgz", + "integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=", + "dev": true + } + } + }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "http://127.0.0.1:8001/scss-tokenizer/download/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "dev": true, + "requires": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "http://127.0.0.1:8001/source-map/download/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "semver": { + "version": "5.6.0", + "resolved": "http://127.0.0.1:8001/semver/download/semver-5.6.0.tgz", + "integrity": "sha1-fnQlb7qknHWqfHogXMInmcrIAAQ=", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/set-blocking/download/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "http://127.0.0.1:8001/shebang-command/download/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/shebang-regex/download/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "http://127.0.0.1:8001/signal-exit/download/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-statistics": { + "version": "6.1.1", + "resolved": "http://127.0.0.1:8001/simple-statistics/download/simple-statistics-6.1.1.tgz", + "integrity": "sha1-46B5n/xJkU1vQhxaSsWF9qE+K60=" + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/slice-ansi/download/slice-ansi-1.0.0.tgz", + "integrity": "sha1-BE8aSdiEL/MHqta1Be0Xi9lQE00=", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "http://127.0.0.1:8001/source-map/download/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "spdx-correct": { + "version": "3.0.2", + "resolved": "http://127.0.0.1:8001/spdx-correct/download/spdx-correct-3.0.2.tgz", + "integrity": "sha1-GbtAnpG0exrVQVkkP3MSqFjbPC4=", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "http://127.0.0.1:8001/spdx-exceptions/download/spdx-exceptions-2.2.0.tgz", + "integrity": "sha1-LqRQrudPKom/uUUZwH/Nb0EyKXc=", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "http://127.0.0.1:8001/spdx-expression-parse/download/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha1-meEZt6XaAOBUkcn6M4t5BII7QdA=", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.2", + "resolved": "http://127.0.0.1:8001/spdx-license-ids/download/spdx-license-ids-3.0.2.tgz", + "integrity": "sha1-pZ78CXhMKlutoTz+r1x13SFARNI=", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "http://127.0.0.1:8001/sprintf-js/download/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "http://127.0.0.1:8001/sshpk/download/sshpk-1.16.1.tgz", + "integrity": "sha1-+2YcC+8ps520B2nuOfpwCT1vaHc=", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stdout-stream": { + "version": "1.4.1", + "resolved": "http://127.0.0.1:8001/stdout-stream/download/stdout-stream-1.4.1.tgz", + "integrity": "sha1-WsF0zdXNcmEEqgwLK9g4FdjVNd4=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "http://127.0.0.1:8001/readable-stream/download/readable-stream-2.3.7.tgz", + "integrity": "sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "http://127.0.0.1:8001/safe-buffer/download/safe-buffer-5.1.2.tgz", + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "http://127.0.0.1:8001/string_decoder/download/string_decoder-1.1.1.tgz", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "http://127.0.0.1:8001/string-width/download/string-width-2.1.1.tgz", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/string.prototype.trimend/download/string.prototype.trimend-1.0.2.tgz", + "integrity": "sha1-bd2ah5a8cUtImjriIkaiCPN7+kY=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "http://127.0.0.1:8001/es-abstract/download/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha1-bjoKS9pxflAjqzuOkL7DYQjSLGg=", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } + } + }, + "string.prototype.trimstart": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/string.prototype.trimstart/download/string.prototype.trimstart-1.0.2.tgz", + "integrity": "sha1-ItRdqBAVMJzQzdeXh+iRn8XGE+c=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "http://127.0.0.1:8001/es-abstract/download/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha1-bjoKS9pxflAjqzuOkL7DYQjSLGg=", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "http://127.0.0.1:8001/string_decoder/download/string_decoder-1.3.0.tgz", + "integrity": "sha1-QvEUWUpGzxqOMLCoT1bHjD7awh4=", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "http://127.0.0.1:8001/strip-ansi/download/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "http://127.0.0.1:8001/strip-bom/download/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "http://127.0.0.1:8001/strip-indent/download/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + }, + "dependencies": { + "get-stdin": { + "version": "4.0.1", + "resolved": "http://127.0.0.1:8001/get-stdin/download/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + } + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "http://127.0.0.1:8001/strip-json-comments/download/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "http://127.0.0.1:8001/supports-color/download/supports-color-5.5.0.tgz", + "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.1.0", + "resolved": "http://127.0.0.1:8001/table/download/table-5.1.0.tgz", + "integrity": "sha1-aaVGRPbwGtFij4F4cVtAjca/Efc=", + "dev": true, + "requires": { + "ajv": "^6.5.3", + "lodash": "^4.17.10", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + } + }, + "tar": { + "version": "2.2.2", + "resolved": "http://127.0.0.1:8001/tar/download/tar-2.2.2.tgz", + "integrity": "sha1-DKiEhWLHKZuLRG/2pNYM27I+3EA=", + "dev": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "http://127.0.0.1:8001/text-table/download/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "http://127.0.0.1:8001/through/download/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "http://127.0.0.1:8001/tmp/download/tmp-0.0.33.tgz", + "integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/to-fast-properties/download/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "topojson-client": { + "version": "3.1.0", + "resolved": "http://127.0.0.1:8001/topojson-client/download/topojson-client-3.1.0.tgz", + "integrity": "sha1-Iuix7QiiuSL+60r29Ttu8JpGe5k=", + "requires": { + "commander": "2" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "http://127.0.0.1:8001/tough-cookie/download/tough-cookie-2.5.0.tgz", + "integrity": "sha1-zZ+yoKodWhK0c72fuW+j3P9lreI=", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/trim-newlines/download/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "true-case-path": { + "version": "1.0.3", + "resolved": "http://127.0.0.1:8001/true-case-path/download/true-case-path-1.0.3.tgz", + "integrity": "sha1-+BO1qMhrQNpZYGcisUTjIleZ9H0=", + "dev": true, + "requires": { + "glob": "^7.1.2" + } + }, + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "http://127.0.0.1:8001/tsconfig-paths/download/tsconfig-paths-3.9.0.tgz", + "integrity": "sha1-CYVHpsREiAfo/Ljq4IEGTumjyQs=", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "http://127.0.0.1:8001/minimist/download/minimist-1.2.5.tgz", + "integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI=", + "dev": true + } + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "http://127.0.0.1:8001/tslib/download/tslib-1.9.3.tgz", + "integrity": "sha1-1+TdeSRdhUKMTX5IIqeZF5VMooY=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "http://127.0.0.1:8001/tunnel-agent/download/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "http://127.0.0.1:8001/tweetnacl/download/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "http://127.0.0.1:8001/type-check/download/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "http://127.0.0.1:8001/uri-js/download/uri-js-4.2.2.tgz", + "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/util-deprecate/download/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "http://127.0.0.1:8001/uuid/download/uuid-3.4.0.tgz", + "integrity": "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "http://127.0.0.1:8001/validate-npm-package-license/download/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha1-/JH2uce6FchX9MssXe/uw51PQQo=", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "http://127.0.0.1:8001/verror/download/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vue": { + "version": "2.6.11", + "resolved": "http://127.0.0.1:8001/vue/download/vue-2.6.11.tgz", + "integrity": "sha1-dllNh31LEiNEBuhONSdcbVFBJcU=" + }, + "vue-chartjs": { + "version": "3.5.1", + "resolved": "http://127.0.0.1:8001/vue-chartjs/download/vue-chartjs-3.5.1.tgz", + "integrity": "sha1-0l6EVwj3dErlG+2dI6l19fj8ZSk=", + "dev": true, + "requires": { + "@types/chart.js": "^2.7.55" + } + }, + "vue-i18n": { + "version": "8.18.2", + "resolved": "http://127.0.0.1:8001/vue-i18n/download/vue-i18n-8.18.2.tgz", + "integrity": "sha1-zXwS8uF45vqiOw48/S97rJMF+Pw=" + }, + "vue-router": { + "version": "2.8.1", + "resolved": "http://127.0.0.1:8001/vue-router/download/vue-router-2.8.1.tgz", + "integrity": "sha1-mDPJ7lesg76wJpBW/v7nFxPyBpU=" + }, + "vue-template-compiler": { + "version": "2.6.11", + "resolved": "http://127.0.0.1:8001/vue-template-compiler/download/vue-template-compiler-2.6.11.tgz", + "integrity": "sha1-wEcE749JixUxMAGJk+VjCdRpgIA=", + "requires": { + "de-indent": "^1.0.2", + "he": "^1.1.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "http://127.0.0.1:8001/which/download/which-1.3.1.tgz", + "integrity": "sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo=", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "http://127.0.0.1:8001/which-module/download/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "http://127.0.0.1:8001/wide-align/download/wide-align-1.1.3.tgz", + "integrity": "sha1-rgdOa9wMFKQx6ATmJFScYzsABFc=", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wolfy87-eventemitter": { + "version": "5.2.9", + "resolved": "http://127.0.0.1:8001/wolfy87-eventemitter/download/wolfy87-eventemitter-5.2.9.tgz", + "integrity": "sha1-6Hn3cLMPu2USqK+7Mww4hZEJnCo=" + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "http://127.0.0.1:8001/wordwrap/download/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "http://127.0.0.1:8001/wrappy/download/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "http://127.0.0.1:8001/write/download/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "xss": { + "version": "1.0.7", + "resolved": "http://127.0.0.1:8001/xss/download/xss-1.0.7.tgz", + "integrity": "sha1-pVTL1ekJMkvWiT+0f/9EGtVOKpU=", + "requires": { + "commander": "^2.20.3", + "cssfilter": "0.0.10" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "http://127.0.0.1:8001/commander/download/commander-2.20.3.tgz", + "integrity": "sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=" + } + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "http://127.0.0.1:8001/y18n/download/y18n-4.0.0.tgz", + "integrity": "sha1-le+U+F7MgdAHwmThkKEg8KPIVms=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "http://127.0.0.1:8001/yallist/download/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "http://127.0.0.1:8001/yargs/download/yargs-13.3.2.tgz", + "integrity": "sha1-rX/+/sGqWVZayRX4Lcyzipwxot0=", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "http://127.0.0.1:8001/ansi-regex/download/ansi-regex-4.1.0.tgz", + "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "http://127.0.0.1:8001/string-width/download/string-width-3.1.0.tgz", + "integrity": "sha1-InZ74htirxCBV0MG9prFG2IgOWE=", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "http://127.0.0.1:8001/strip-ansi/download/strip-ansi-5.2.0.tgz", + "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "http://127.0.0.1:8001/yargs-parser/download/yargs-parser-13.1.2.tgz", + "integrity": "sha1-Ew8JcC667vJlDVTObj5XBvek+zg=", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "http://127.0.0.1:8001/camelcase/download/camelcase-5.3.1.tgz", + "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=", + "dev": true + } + } + } + } +} diff --git a/ui/package.json b/ui/package.json new file mode 100644 index 00000000..a81879ea --- /dev/null +++ b/ui/package.json @@ -0,0 +1,48 @@ +{ + "name": "Exchangis", + "version": "0.5.0", + "description": "Exchangis", + "main": "app.js", + "scripts": { + "build": "fes build", + "dev": "fes dev", + "fix": "eslint --ext .fes src --fix" + }, + "keywords": [ + "管理端", + "fes", + "fast", + "easy", + "strong" + ], + "files": [ + ".eslintrc.js", + ".gitignore", + "fes.config.js", + "mock.js", + "package.json", + "README.md", + "/src" + ], + "repository": { + "type": "git" + }, + "author": "harrywan qlin", + "license": "MIT", + "devDependencies": { + "@webank/eslint-config-webank": "^0.1.4", + "chart.js": "^2.9.4", + "csp-html-webpack-plugin": "^4.0.0", + "node-sass": "^4.14.1", + "sass-loader": "^10.0.4", + "vue-chartjs": "^3.5.1" + }, + "dependencies": { + "@antv/data-set": "^0.11.7", + "@antv/g2": "^4.0.15", + "@babel/runtime-corejs3": "^7.11.2", + "@webank/fes-core": "0.0.11", + "@webank/ui-webank": "^2.3.42" + }, + "gitHead": "357575247bde6d1d24a8d2e11d2bfe7adbe6abd6" +} diff --git a/ui/replace.js b/ui/replace.js new file mode 100644 index 00000000..5a6bcea7 --- /dev/null +++ b/ui/replace.js @@ -0,0 +1,57 @@ +var fs = require('fs'); +var path = require('path'); +var json = JSON.parse(fs.readFileSync('./cn.json', 'utf-8')).cn; + +function fileDisplay(filePath) { + fs.readdir(filePath, function (err, files) { + if (err) { + console.warn(err) + } else { + files.forEach(function (filename) { + var filedir = path.join(filePath, filename); + fs.stat(filedir, function (eror, stats) { + if (eror) { + console.warn('获取文件stats失败'); + } else { + var isFile = stats.isFile(); + var isDir = stats.isDirectory(); + if (isFile) { + // console.log(filedir); + var content = fs.readFileSync(filedir, 'utf-8'); + + var values = Object.values(json); + var keys = Object.keys(json) + values = values.sort((a, b) => b.length - a.length); + + values.forEach((it) => { + var key = keys.find(k => json[k] == it) + // title="单表校验" + // name="技术规则" + // 未通过校验 + var titleReg = new RegExp(` title="${it}"`, 'g') + var nameReg = new RegExp(` name="${it}"`, 'g') + var tagReg = new RegExp(`>${it}<`, 'g') + content = content.replace(titleReg, ` :title="$t('${key}')"`) + content = content.replace(nameReg, ` :name="$t('${key}')"`) + content = content.replace(tagReg, `>{{ $t('${key}') }}<`) + content = content.replace(new RegExp(it, 'g'), `$t('${key}')`) + }) + + fs.writeFile(filedir, content, function (err) { + if (err) { + throw err; + } + console.log('done.'); + }) + } + if (isDir) { + fileDisplay(filedir); + } + } + }) + }); + } + }); +} +var filePath = path.resolve('./src/pages/taskQuery'); +fileDisplay(filePath); diff --git a/ui/src/app.js b/ui/src/app.js new file mode 100644 index 00000000..3df960ac --- /dev/null +++ b/ui/src/app.js @@ -0,0 +1,89 @@ +import './assets/styles/main.scss' +export default function() { + // 设置路由钩子 + this.setBeforeRouter(function(from, to, next) { + // dqm 登录后检查登录并设置登录信息 + if (from.path === '/home') return next(); + this.FesApi.fetch("api/v1/projector/role", "get").then(({roles,username}) => { + if(Array.isArray(roles)){ + roles = roles.map(item => item.toLowerCase()) + let userRole = roles[0]; + this.FesFesx.set('userRole', userRole); + } + let role = 'noauth'; + this.FesStorage.set("userLogin", true); + if (!this.FesStorage.get('simulatedUser')) { + this.FesApp.set("FesRoleName", ""); + if(roles && roles.indexOf('admin') > -1 ){ + role = 'admin'; + this.FesApp.set("FesRoleName", "管理员"); + } + this.FesApp.set("FesUserName", username); + this.FesApp.setRole(role, false); + this.FesStorage.set('firstRole', role); + } + if (from.path === '/') { + next({path: '/dashboard'}); + }else { + next(); + } + }).catch((err) => { + console.error(err); + next({path: '/home'}); + }); + }); + + // 设置AJAX配置 + this.FesApi.option({ + timeout: 1000 * 60 + }); + const that = this; + const lang = this.FesFesx.get('currentLanguage'); + + this.FesApi.setError({ + 404: function() { + that.router.replace({path: '/error'}) + }, + 401: ({data:{data}}) => { + let lastRedirect = this.FesStorage.get('redirect_to_um_login'); + if(!data) { + let mes = lang === 'zh-cn' ? '登录失败,请检查密码或帐号' :'Login failed, please check your password or account'; + window.Toast.error(mes); + this.FesStorage.set('userLogin', false); + this.FesApp.setRole('unLogin'); + } else { + // 防止接口问题引起循环跳转, 正常登录不会有问题如果sso登录回调回来没有登录态就会循环 setBeforeRouter 里有获取角色的信息 + if( (!lastRedirect || +new Date() - lastRedirect > 3000) && data.redirect) { + this.FesStorage.set('redirect_to_um_login', +new Date()); + let splitChar = data.redirect.indexOf('?') > 0 ? '&' : '?'; + data.redirect = `${data.redirect}${splitChar}link=${encodeURIComponent(window.location.href)}`; + this.FesApp.setRole('admin'); + window.location.href = data.redirect; + } + } + } + }) + setTimeout(() => { + let currentLanguage = this.FesFesx.get('currentLanguage'); + if(currentLanguage && currentLanguage === 'en'){ + this.FesApp.setLocale('en') + this.FesFesx.set('currentLanguage', 'en') + this.FesFesx.set('Language', 'en_US') + }else { + this.FesApp.setLocale('zh-cn') + this.FesFesx.set('currentLanguage', 'zh-cn') + this.FesFesx.set('Language', 'zh_CN') + } + this.FesApi.setHeader({ + 'Content-Language': this.FesFesx.get('Language') + }) + }, 0) + + // 设置响应结构 + this.FesApi.setResponse({ + successCode: '200', + codePath: 'code', + messagePath: 'message', + resultPath: 'data' + }); +} diff --git a/ui/src/assets/images/bg.png b/ui/src/assets/images/bg.png new file mode 100644 index 00000000..28a4e820 Binary files /dev/null and b/ui/src/assets/images/bg.png differ diff --git a/ui/src/assets/images/caret-down.png b/ui/src/assets/images/caret-down.png new file mode 100644 index 00000000..3353b9d5 Binary files /dev/null and b/ui/src/assets/images/caret-down.png differ diff --git a/ui/src/assets/images/logo.png b/ui/src/assets/images/logo.png new file mode 100644 index 00000000..ffcfec2c Binary files /dev/null and b/ui/src/assets/images/logo.png differ diff --git a/ui/src/assets/images/qualitis.png b/ui/src/assets/images/qualitis.png new file mode 100644 index 00000000..4710c567 Binary files /dev/null and b/ui/src/assets/images/qualitis.png differ diff --git a/ui/src/assets/images/webank-logo.png b/ui/src/assets/images/webank-logo.png new file mode 100644 index 00000000..9e065675 Binary files /dev/null and b/ui/src/assets/images/webank-logo.png differ diff --git a/ui/src/assets/js/sizeList.js b/ui/src/assets/js/sizeList.js new file mode 100644 index 00000000..56fa2f72 --- /dev/null +++ b/ui/src/assets/js/sizeList.js @@ -0,0 +1,9 @@ +/* +用于分页 +*/ +const sizeList = [5, 10, 15, 20, 50, 100]; + + +export { + sizeList +} \ No newline at end of file diff --git a/ui/src/assets/js/utils.js b/ui/src/assets/js/utils.js new file mode 100644 index 00000000..09f55a0e --- /dev/null +++ b/ui/src/assets/js/utils.js @@ -0,0 +1,341 @@ +function dateFormat(fmt, date = new Date()) { + var o = { + "M+": date.getMonth() + 1, //月份 + "d+": date.getDate(), //日 + "H+": date.getHours(), //小时 + "m+": date.getMinutes(), //分 + "s+": date.getSeconds(), //秒 + "q+": Math.floor((date.getMonth() + 3) / 3), //季度 + "S": date.getMilliseconds() //毫秒 + }; + if (/(y+)/.test(fmt)) { + fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length)); + } + for (var k in o) { + if (new RegExp("(" + k + ")").test(fmt)) { + fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]) + .length))); + } + } + return fmt; +} + +/** + * 获取人事接口提供的人员信息,并缓存 + */ +function getStaff(ctx) { + return new Promise(async (resolve, reject)=> { + if(typeof ctx === 'undefined' || !ctx.FesApi){ + console.warn('ctx must not undefined'); + resolve([]); + return; + } + let cacheStaff = ctx.FesApp.get("staffList"); + if (Array.isArray(cacheStaff)) { + resolve(cacheStaff); + return; + } + + let staff = []; + try { + let result = await ctx.FesApi.fetch("api/v1/projector/staff", {}, "get"); + if (Array.isArray(result)) { + staff = result.map((item) => { + let info = item.split(","); + return { + "username": info[0], + "chinese_name": info[1], + "full_name": `${info[0]}(${info[1]})`, + "org_name": info[2] + } + }); + staff = _.uniqBy(staff,"username"); + } + ctx.FesApp.set("staffList", staff); + } catch (error) { + console.error(error); + reject(error); + } + resolve(staff); + }) +} + + +/* + * Download--Excel + * @param {blob} data + * @param {文件名} fileName + */ +function forceDownload(blob, fileName) { + const elink = document.createElement('a'); + elink.style.display = 'none'; + elink.download = fileName; + elink.href = blob; + elink.click(); +} + + +/** + *是否为IE浏览器 + */ +function isIE() { + if (!!window.ActiveXObject || "ActiveXObject" in window) { + alert('请使用Chrome或其他高级浏览器,IE可能会无法正常显示'); + return true; + } +} + +function getUserRole(params) { + params.FesApi.fetch("api/v1/projector/role", "get").then(({roles,username}) => { + if(Array.isArray(roles)){ + roles = roles.map(item => item.toLowerCase()) + } + let role = 'noauth'; + if(roles && roles.indexOf('admin') > -1 ){ + role = 'admin'; + params.FesApp.set("FesRoleName", "管理员"); + } + params.FesApp.setRole(role); + if (!params.FesStorage.get('simulatedUser')) { + params.FesApp.set("FesUserName", username); + } + params.$router.push({ path: "/dashboard" }); + }).catch(() => { + let role = params.FesStorage.get('firstRole'); + if (role) { + params.FesApp.setRole(role); + }else { + params.FesApp.setRole('noauth'); + } + }); +} + +function DWSMessage(key, ruleGroupId, action) { + const jsonStr = { + type: 'qualitis', + nodeId: key, + data: { + ruleGroupId, + action + } + } + window.parent.postMessage(JSON.stringify(jsonStr), '*') +} + +function sha256(s) { + var chrsz = 8; + var hexcase = 0; + function safe_add(x, y) { + var lsw = (x & 0xffff) + (y & 0xffff); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xffff); + } + function S(X, n) { + return (X >>> n) | (X << (32 - n)); + } + function R(X, n) { + return X >>> n; + } + function Ch(x, y, z) { + return (x & y) ^ (~x & z); + } + function Maj(x, y, z) { + return (x & y) ^ (x & z) ^ (y & z); + } + function Sigma0256(x) { + return S(x, 2) ^ S(x, 13) ^ S(x, 22); + } + function Sigma1256(x) { + return S(x, 6) ^ S(x, 11) ^ S(x, 25); + } + function Gamma0256(x) { + return S(x, 7) ^ S(x, 18) ^ R(x, 3); + } + function Gamma1256(x) { + return S(x, 17) ^ S(x, 19) ^ R(x, 10); + } + function core_sha256(m, l) { + var K = new Array( + 0x428a2f98, + 0x71374491, + 0xb5c0fbcf, + 0xe9b5dba5, + 0x3956c25b, + 0x59f111f1, + 0x923f82a4, + 0xab1c5ed5, + 0xd807aa98, + 0x12835b01, + 0x243185be, + 0x550c7dc3, + 0x72be5d74, + 0x80deb1fe, + 0x9bdc06a7, + 0xc19bf174, + 0xe49b69c1, + 0xefbe4786, + 0xfc19dc6, + 0x240ca1cc, + 0x2de92c6f, + 0x4a7484aa, + 0x5cb0a9dc, + 0x76f988da, + 0x983e5152, + 0xa831c66d, + 0xb00327c8, + 0xbf597fc7, + 0xc6e00bf3, + 0xd5a79147, + 0x6ca6351, + 0x14292967, + 0x27b70a85, + 0x2e1b2138, + 0x4d2c6dfc, + 0x53380d13, + 0x650a7354, + 0x766a0abb, + 0x81c2c92e, + 0x92722c85, + 0xa2bfe8a1, + 0xa81a664b, + 0xc24b8b70, + 0xc76c51a3, + 0xd192e819, + 0xd6990624, + 0xf40e3585, + 0x106aa070, + 0x19a4c116, + 0x1e376c08, + 0x2748774c, + 0x34b0bcb5, + 0x391c0cb3, + 0x4ed8aa4a, + 0x5b9cca4f, + 0x682e6ff3, + 0x748f82ee, + 0x78a5636f, + 0x84c87814, + 0x8cc70208, + 0x90befffa, + 0xa4506ceb, + 0xbef9a3f7, + 0xc67178f2 + ); + var HASH = new Array( + 0x6a09e667, + 0xbb67ae85, + 0x3c6ef372, + 0xa54ff53a, + 0x510e527f, + 0x9b05688c, + 0x1f83d9ab, + 0x5be0cd19 + ); + var W = new Array(64); + var a, b, c, d, e, f, g, h, i, j; + var T1, T2; + m[l >> 5] |= 0x80 << (24 - (l % 32)); + m[(((l + 64) >> 9) << 4) + 15] = l; + for (i = 0; i < m.length; i += 16) { + a = HASH[0]; + b = HASH[1]; + c = HASH[2]; + d = HASH[3]; + e = HASH[4]; + f = HASH[5]; + g = HASH[6]; + h = HASH[7]; + for (j = 0; j < 64; j++) { + if (j < 16) W[j] = m[j + i]; + else + W[j] = safe_add( + safe_add( + safe_add(Gamma1256(W[j - 2]), W[j - 7]), + Gamma0256(W[j - 15]) + ), + W[j - 16] + ); + T1 = safe_add( + safe_add( + safe_add( + safe_add(h, Sigma1256(e)), + Ch(e, f, g) + ), + K[j] + ), + W[j] + ); + T2 = safe_add(Sigma0256(a), Maj(a, b, c)); + h = g; + g = f; + f = e; + e = safe_add(d, T1); + d = c; + c = b; + b = a; + a = safe_add(T1, T2); + } + HASH[0] = safe_add(a, HASH[0]); + HASH[1] = safe_add(b, HASH[1]); + HASH[2] = safe_add(c, HASH[2]); + HASH[3] = safe_add(d, HASH[3]); + HASH[4] = safe_add(e, HASH[4]); + HASH[5] = safe_add(f, HASH[5]); + HASH[6] = safe_add(g, HASH[6]); + HASH[7] = safe_add(h, HASH[7]); + } + return HASH; + } + function str2binb(str) { + var bin = Array(); + var mask = (1 << chrsz) - 1; + for (var i = 0; i < str.length * chrsz; i += chrsz) { + bin[i >> 5] |= + (str.charCodeAt(i / chrsz) & mask) << (24 - (i % 32)); + } + return bin; + } + function Utf8Encode(string) { + string = string.replace(/\r\n/g, "\n"); + var utftext = ""; + for (var n = 0; n < string.length; n++) { + var c = string.charCodeAt(n); + if (c < 128) { + utftext += String.fromCharCode(c); + } else if (c > 127 && c < 2048) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + } + return utftext; + } + function binb2hex(binarray) { + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var str = ""; + for (var i = 0; i < binarray.length * 4; i++) { + str += + hex_tab.charAt( + (binarray[i >> 2] >> ((3 - (i % 4)) * 8 + 4)) & 0xf + ) + + hex_tab.charAt( + (binarray[i >> 2] >> ((3 - (i % 4)) * 8)) & 0xf + ); + } + return str; + } + s = Utf8Encode(s); + return binb2hex(core_sha256(str2binb(s), s.length * chrsz)); +} +export { + dateFormat, + getStaff, + forceDownload, + isIE, + getUserRole, + DWSMessage, + sha256 +} diff --git a/ui/src/assets/styles/component.scss b/ui/src/assets/styles/component.scss new file mode 100644 index 00000000..808378d2 --- /dev/null +++ b/ui/src/assets/styles/component.scss @@ -0,0 +1,38 @@ +.ui-checkbox-inner { + border: 1px solid #999; +} +.dashboard .ui-page-select { + display: none; +} +.help-document .ui-menu-submenu-ul { + display: block !important; +} +.help-document .ui-icon-down:before { + content: " "; +} +.technical-rules .rule-output:nth-of-type(1) .ui-form-content .ui-input-swap { + margin-left: 10px; +} +.technical-rules .select-options .ui-select { + width: 85%; + margin-left: 10px; +} +.technical-rules .select-content .select-options:nth-of-type(2) .ui-form-label { + text-align: center; +} +.technical-rules .select-content .select-options:nth-of-type(2) .ui-form-content .ui-select { + margin-left: 45px; +} +.technical-rules .source .ui-form-content .ui-input-prepend { + width: 90px; + border: none; +} +.technical-rules .source .ui-form-content .ui-input-append { + border: none; +} +.technical-rules .source .ui-form-content { + margin-left: 0px !important; +} +.technical-rules .fieldWrapper:nth-of-type(4) .ui-form-label { + text-align: left; +} \ No newline at end of file diff --git a/ui/src/assets/styles/crossTable.scss b/ui/src/assets/styles/crossTable.scss new file mode 100644 index 00000000..6c34897b --- /dev/null +++ b/ui/src/assets/styles/crossTable.scss @@ -0,0 +1,126 @@ +//跨表校验css,勿动 +@import "variables"; +.mapSource { + display: inline-block; + width: 49%; + margin-top: 20px; + padding: 10px 0; + border: 1px solid #d7dde4; + border-radius: 4px; + .table-title { + margin: 0 0 5px 10px; + } + .table-main { + display: flex; + width: 100%; + margin: 0 auto; + padding-bottom: 20px; + span { + min-width: 130px; + margin: 8px 15px 0 10px; + } + .table-title { + max-width: 130px; + overflow:hidden; + text-overflow:ellipsis; + white-space:nowrap; + } + .table-content { + width: 80%; + .ulList { + li { + display: inline-block; + padding: 2px 5px; + cursor: pointer; + } + .circle { + margin: 5px 5px; + width: 50px; + border: 1px solid #d7dde4; + border-radius: 50%; + text-align: center; + color: $primary-color; + } + .stress { + border: 1px solid #d7dde4; + margin: 5px 5px; + border-radius: 5px; + color: $primary-color; + } + } + + } + .col { + display: flex; + margin-left: 10px; + .col-select { + flex: 1; + height: 130px; + margin-left: 10px; + overflow: auto; + overflow-y: visible; + border: 1px solid #d7dde4; + border-radius: 4px; + ul { + li { + display: inline-block; + padding: 5px 5px; + margin: 2px 2px; + border: 1px solid #d7dde4; + border-radius: 2px; + } + } + } + .scale { + flex: 1; + } + .col-content { + max-height: 100px; + overflow: auto; + overflow-y: visible; + .col-list { + width: 100%; + li { + padding: 7px 16px; + display: block; + } + } + } + .no-border{ + border: 1px solid #d7dde4; + border-top: none; + } + } + .map-col { + width: 92%; + } + .custom-input { + width: 72%; + } + /deep/ + textarea { + min-height: 44px; + } + .filter-input { + height: 50px; + width: 100%; + border: 1px solid #d7dde4; + } + } +} +.filter { + margin-top: 0; + display: block; + width: 100%; + border: none; +} +.button-action { + text-align: center; + position: absolute; + bottom: 5px; + left: 50%; + transform: translateX(-50%); + .determine { + margin-right: 20px; + } +} \ No newline at end of file diff --git a/ui/src/assets/styles/global.scss b/ui/src/assets/styles/global.scss new file mode 100644 index 00000000..630c6c02 --- /dev/null +++ b/ui/src/assets/styles/global.scss @@ -0,0 +1,99 @@ + +@import "variables"; +@import "mixins"; +// Warning :此文件用于覆盖ui-webank默认样式,请谨慎修改 +.layout-left { + display: none; +} +.pointerTag { + span { + color: #267BF3; + cursor: pointer; + } +} + +.ui-menu { + .ui-menu-item, .ui-menu-submenu { + .ui-menu-item-icon, .ui-menu-submenu-icon { + width: 20px; + height: 20px; + } + } +} +.layout-right .layout-right-body { + top: 48px; +} +// Wb-menu组件 +.ui-menu { + .ui-menu-item-actived { + color: $primary-hover-color + } + .ui-menu-item, .ui-menu-submenu-title { + color: $second-text-color + } + .ui-menu-submenu { + .ui-menu-submenu-title { + color: $second-text-color; + .ui-menu-arrow { + right: 15px; + } + } + .ui-menu-submenu-ul { + width: 100%; + .ui-menu-item { + text-align: center; + color: $second-text-color; + left: -20px; + width: calc(100% + 20px); + } + } + } +} + +.ui-modal, .ui-modal.scroll { + display: flex; + align-items: center; + justify-content: center; + .ui-modal-dialog { + left: auto; + top: auto; + transform: none; + max-width: 100%; + max-height: 100%; + } +} + + +//confirm弹窗 +.ui-message-swap { + .ui-message-body { + margin-bottom: 50px; + .ui-message-buttons { + position: absolute; + right: 10px; + bottom: 10px; + } + } + .ui-button:first-child { + float: right; + margin-left: 15px; + } +} +.breadcrumb-container { + height: 30px; + border-bottom: 1px solid #e8eaec; + .breadcrumb { + color: #515a6e; + } + .breadcrumb-item-separator { + margin: 0 8px; + color: #dcdee2; + } + .breadcrumb-item-link { + font-weight: 700; + color: #515a6e; + } + .cursor{ + cursor: pointer; + } +} \ No newline at end of file diff --git a/ui/src/assets/styles/login.scss b/ui/src/assets/styles/login.scss new file mode 100644 index 00000000..23bc832d --- /dev/null +++ b/ui/src/assets/styles/login.scss @@ -0,0 +1,579 @@ +.login-panel { + position: absolute; + left: 0; + top: 0; + margin: 0; + right: 0; + width: 100%; + height: 100%; + background-color: $body-background; + background-image: url("../images/bg.png"); + background-position: left bottom; + background-repeat: no-repeat; + background-size: 100% auto; + font-size: 18px; + color: $black-text-color; +} + +.login-panel .login-panel-swap { + position: relative; + width: 945px; + height: 324px; + margin: 10% auto; + border-radius: $border-radius-small; +} + +.login-panel .logo { + display: inline-block; + vertical-align: middle; + width: 400px; + height: 100%; + text-align: center; + .logo-text { + display: inline-block; + vertical-align: middle; + margin-top: 130px; + font-size: 28px; + font-weight: bold; + } +} + +.login-panel .split { + display: inline-block; + background: $border-color-base; + width: 1px; + height: 180px; + vertical-align: middle; +} + +.login-panel .error { + margin-top: 10px; + width: 350px; + color: $error-color; + font-size: 14px; + .ui-icon-exclamation-circle { + margin-right: 6px; + } +} + +.login-panel .login-form { + position: relative; + display: inline-block; + vertical-align: middle; + padding: 0 75px 0; + height: 270px; + input::-webkit-input-placeholder { + color: $black-text-color; + } + input::-moz-placeholder { + color: $black-text-color; + } + /* ie */ + input:-ms-input-placeholder { + color: $black-text-color; + } + /* firefox 19+ */ + input:-moz-placeholder { + color: $black-text-color; + } + input:-webkit-autofill { + box-shadow: 0 0 0px 1000px white inset !important; + -webkit-text-fill-color: $black-text-color !important; + } + .line { + padding-top: 30px; + border-bottom: 1px solid $border-color-split; + } + input[type="text"], + input[type="password"] { + margin: 0; + width: 350px; + height: 40px; + line-height: 40px; + padding: 0 15px; + vertical-align: middle; + background: 0 0; + outline: 0; + border: none; + font-size: 16px; + color: $black-text-color; + } + button { + margin-top: 10px; + width: 350px; + height: 48px; + border-radius: 4px; + line-height: 46px; + border: none; + outline: 0; + background-color: $primary-color; + color: #ffffff; + cursor: pointer; + text-align: center; + font-size: 18px; + &:hover { + background-color: $selected-color; + } + } +} + +.ie-palceholder::after { + content: '用户名'; + position: absolute; + left: 88px; + top: 38px; + font-size: 16px; +} + +.ie-palceholder-password::after { + content: '密码'; + top: 110px; +} + +.img { + margin-top: 20px; +} + +.nav { + width: 10%; + font-size: 16px; +} + +.system { + margin-left: 30% +} + + +.footer { + bottom: 0; + left: 0; + right: 0; + height: 60px; + text-align: center; + line-height: 60px; + font-size: 16px; + border-top: 1px solid #dcdcdc; + background: #fff; +} + +.middle-wrapper { + height: 100%; + overflow-x: hidden; +} + +.all-wrapper { + width: 100%; + height: 100%; +} + +.Row-wrapper { + height: 100%; +} + +.left-content { + height: 100%; +} + +.right-content { + height: 100%; +} + +.head-wrapper { + height: 100px; + text-align: center; + line-height: 100px; +} + +.filter-wrapper { + height: 30px; + line-height: 32px; + text-align: center; + font-size: 14px; + width: 90%; + border: 1px solid #dcdcdc; +} + +.right-head { + height: 100px; + line-height: 100px; + display: flex; + justify-content: center; + align-items: center; +} + +.right-wrapper { + height: 700px; + border: 1px solid #dcdcdc; +} + +.item-wrapper { + display: inline-block; + height: 35px; + line-height: 35px; + text-align: center; + width: 50%; + font-size: 14px; + margin: 0 20px; + border: 1px solid #dcdcdc; +} + +.right-top { + height: 25%; + width: 100%; +} + +.right-bottom { + height: 50%; + width: 100%; +} + +.item-title { + height: 60px; + line-height: 60px; +} + +.item-input { + width: 100px; + margin-bottom: 1px; +} + +.item-list { + height: 40px; + line-height: 40px; + text-align: center; +} + +.item-page { + height: 44px; + text-align: right; + line-height: 54px; +} + +.page-wrapper { + margin-right: 20px; +} + +.rightContent { + height: 100%; + width: calc(100% - 200px); + overflow-y: scroll; + overflow-x: hidden; + padding-left:10px; + padding-right: 20px +} + +.parameterButton { + height: 60px; + display: flex; + justify-content: flex-end; + align-items: center +} + +.addButton { + margin: 0 20px; +} + + +.dataWrapper { + width: 370px; + margin-left: 20px; +} + +.ascertainWrapper { + height: 60px; + display: flex; + justify-content: start; + align-items: center; + line-height: 60px; +} + +.stencilHead { + height: 40px; + line-height: 40px; + font-size: 16px; + border-bottom: 1px solid #dcdcdc; +} + +.stencilHeadTitle { + height: 100%; + text-align: center; + line-height: 40px; +} + +.typeWrapper { + width: 150px; +} + +.qualityWrapper { + display: flex; + justify-content: center; + align-items: center; + height: 60px; +} + +.checkRule { + width: 20%; + height: 300px; + margin-top: 10px; + float: left; + margin-left: 20px; + border: 1px solid #dcdcdc; + position: relative; + font-size: 14px; +} + +.checkRuleWrapper { + position: absolute; + top: 0; + left: 40%; + width: 70px; + line-height: 40px; + height: 40px; + text-align: center; + border: 1px solid #dcdcdc; + border-top: none; +} + +.dataCheckbox { + height: 30px; + line-height: 30px; + text-align: left; + margin-left: 40%; + font-size: 14px; +} + +.depositTableSearch { + width: 370px; + margin-left: 20px; +} + +.confirmWrapper { + display: flex; + justify-content: center; + height: 50px; + align-items: center; + margin-top: 70px; +} + +.firstBtn { + margin-right: 80px; + margin-left: 20px; +} + +.qualityTestForm { + border: 1px solid #dcdcdc; + margin-left: 20px; +} + +.addQualityTest { + margin-left: 40px; + float: left; + font-size: 22px; + margin-top: 5px; +} + +.delStencilWrapper { + height: 120px; + display: flex; + justify-content: center; + align-items: center; + font-size: 14px; +} + +.delStencil { + height: 60px; + width: 180px; + border: 1px solid #dcdcdc; + text-align: center; + line-height: 60px; +} + +.tdInput { + border: none; + outline: none; + cursor: pointer; + width: 80px; +} + +.submitWrapper .ui-form-content { + margin-top: 50px; +} + +.borderLeft { + border-left: 1px solid #dcdcdc; + margin-left: -1px; +} + +.reportAllBox { + margin: 0 10px; +} + +.leftPageWrapper .ui-page .ui-page-prev { + text-indent: 0; + line-height: 30px; +} + +.leftPageWrapper .ui-page .ui-page-item { + text-indent: 0; + line-height: 30px; +} + +.leftPageWrapper .ui-page .ui-page-next { + text-indent: 0; + line-height: 30px; +} + +.leftPageWrapper .ui-page .ui-page-select { + display: none; +} + +.addProjectColor { + color: blue; + font-size: 14px !important; +} + +.checkRule .ui-radio-group-vertical { + margin-top: 20px; +} + +.radioSpan { + margin: 0 10px; +} + +.myProject { + line-height: 48px; + text-indent: 24px; + cursor: pointer; + position: relative; + color: #657180; + margin-left: 10px; + font-size: 16px; +} + +.iconWrapper { + color: #999; + float: right; + position: absolute; + top: 1px; + right: 24px; + text-indent: 0; +} + +.hoverColor:hover { + background-color: #f3f3f3; +} + +.cursor { + cursor: pointer; +} + +.childMenu li { + text-indent: 48px; + cursor: pointer; + position: relative; + line-height: 48px; + font-size: 15px; + position: relative; +} + +.active { + color: #128bd6; + border-right: 2px solid #128bd6; +} + +.tabActive { + color: #128bd6; +} + +.radioLable { + margin: 0 20px; +} + +.regInput { + width: 70%; + min-width: 120px !important +} + +.templateForm { + width: 18%; + height: 350px; + float: left; + margin-left: 20px; + border: 1px solid #dcdcdc; +} + +.columnWrapper { + max-height: 120px; + overflow: auto; + overflow-x: hidden; + min-height: 50px; + text-align: center; +} + +.checkboxInputWrapper { + height: 40px; +} + +.checkboxInput { + float: left; + width: 60%; + min-width: 130px; + margin-right: 20px; +} + +.showColumnWrapper { + margin-top: 10px; +} + +.retract { + position: absolute; + top: 50px; + left: 160px; + color: white; +} + +.columnSearch { + font-size: 14px; + min-width: 80px; + width: 30%; + height: 30px; + line-height: 30px; + text-align: center; + float: left; + margin: 0 20px; + border: 1px solid #dcdcdc; +} + +.templateForm { + width: 18%; + min-width: 250px; + height: 300px; + float: left; + margin-left: 20px; + border: 1px solid #dcdcdc; + margin-top: 10px; +} + +.showRulePage { + width: 0; +} + +.showRulePage .ui-input { + right: 14px; + width: 45px; + height: 28px; + text-align: center; +} + +.rulePageLi { + text-indent: 15px !important; +} + +.rulePageLi a { + font-size: 14px; +} + +.rulePageLi span { + font-size: 14px; + margin-left: 45px; +} diff --git a/ui/src/assets/styles/main.scss b/ui/src/assets/styles/main.scss new file mode 100644 index 00000000..95d70001 --- /dev/null +++ b/ui/src/assets/styles/main.scss @@ -0,0 +1,136 @@ +@import "variables"; +@import "login"; +@import "component.scss"; +@import "global.scss"; +.article { + padding: 20px; + + h1 { + font-size: 26px; + font-weight: 400; + margin: 12px 0; + } + + h2 { + margin: 25px 0 12px; + font-size: 20px; + font-weight: 400; + } + + h3 { + font-size: 16px; + font-weight: 400; + } + + p { + font-size: 14px; + margin: 5px; + } + + ul { + padding-left: 40px; + } + + li { + list-style-type: disc; + margin-bottom: 5px; + font-size: 14px; + } + + table { + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + border: 1px solid #e9e9e9; + width: 500px; + margin-bottom: 24px; + } + + th, + td { + border: 1px solid #e9e9e9; + padding: 8px 16px; + text-align: left; + } +} +.ui-table-tbody > tr > td, .ui-table-thead > tr > th { + padding: 8px; +} +.p10 { + padding: 10px; +} +.p20 { + padding: 20px; +} +.pb20 { + padding-bottom: 20px; +} +.pr20 { + padding-right: 20px; +} +.pt20 { + padding-top: 20px; +} +.pl20 { + padding-left: 20px; +} +.mb20 { + margin-bottom: 20px; +} +.mt20 { + margin-top:20px; +} +.m10 { + margin: 10px; +} +.mb10 { + margin-bottom: 10px; +} +.mt10 { + margin-top: 10px; +} +.mr10 { + margin-right: 10px; +} +.ml10 { + margin-left: 10px; +} +.textCenter { + text-align: center; +} +.inline-block { + display: inline-block; +} +.border1px { + border: 1px solid #e3e8ee; +} +.fr { + float: right; +} +.flex { + display: flex; +} +.pointer { + cursor: pointer; +} +.loading-layout { + position: absolute; + top: 30%; + left: 50%; + height: 70px !important; + width: 70px !important; +} +.loading-content { + position: relative; +} + +.layout-right .layout-right-header { + height: 48px; + line-height: 48px; +} + +.button-container { + position: absolute; + bottom: 10px; + right: 0; +} \ No newline at end of file diff --git a/ui/src/assets/styles/mixins.scss b/ui/src/assets/styles/mixins.scss new file mode 100644 index 00000000..6b88508c --- /dev/null +++ b/ui/src/assets/styles/mixins.scss @@ -0,0 +1,6 @@ +// 当长度超过宽度时,使用省略号来避免显示太长 +@mixin text-ellipsis { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} \ No newline at end of file diff --git a/ui/src/assets/styles/variables.scss b/ui/src/assets/styles/variables.scss new file mode 100644 index 00000000..9eb4de00 --- /dev/null +++ b/ui/src/assets/styles/variables.scss @@ -0,0 +1,121 @@ +// Color +$primary-color : #3399ff; +$info-color : #2db7f5; +$success-color : #00cc66; +$warning-color : #ff9900; +$error-color : #ff5500; +$link-color : #3399ff; +$link-hover-color : #5cadff; +$link-focus-color : rgba(51,153,255, .2); +$link-active-color : #3091f2; +$selected-color : rgba($primary-color, .9); +$tooltip-color : #fff; +$primary-hover-color : #126ce9; +//辅助/图标 +$subsidiary-color : #9ea7b4; +$disabled-color : #f3f3f3; + +// 辅助色 +$success-color : #22c677; // 成功 +$warning-color : #ffa027; // 危险 +$error-color : #fd3838; // 错误 +$invalid-color : #cccccc; // 失效 +$background-color : #f7f7f7; // 背景色 +$background-hover-color : #f2f2f2; // 背景hover色 +$shadow-color : #e1e1e1; // 投影 +$border-color : #d7d7d7; // 线框 +$division-color : #e4e4e4; // 分割线 + +// Base +$body-background : #fff; +$component-background : #fff; +$font-family : "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; +$code-family : Consolas,Menlo,Courier,monospace; +$title-color : #464c5b; +$text-color : #657180; +$black-text-color : #333333; +$sub-text-color : #999; +$dark-color : #333; + +//失效 Disabled +$tip-color : #c3cbd6; +$font-size-lg : 16px; +$font-size-base : 14px; +$font-size-small : 12px; +$line-height-base : 1.5; +$line-height-computed : floor(($font-size-base * $line-height-base)); +$border-radius-base : 6px; +$border-radius-small : 4px; +$cursor-disabled : not-allowed; + +// Border color +$border-color-base : #d7dde4; // outside +$border-color-split : #e3e8ee; // inside + + +// Background color +$background-color-base : #f7f7f7; // base +$background-color-select-hover: #f3f3f3; +$tooltip-bg : rgba(70, 76, 91, .9); +$head-bg : #f9fafc; +$table-thead-bg : #f5f7f9; +$table-td-stripe-bg : #f5f7f9; +$table-td-hover-bg : #ebf7ff; +$table-td-highlight-bg : #ebf7ff; + +// Z-index +$zindex-spin : 8; +$zindex-affix : 10; +$zindex-back-top : 10; +$zindex-select : 900; +$zindex-modal : 1000; +$zindex-message : 1010; +$zindex-notification : 1010; +$zindex-tooltip : 1060; +$zindex-loading-bar : 2000; + +// Animation +$animation-time : .3s; +$transition-time : .2s; +$ease-out : cubic-bezier(0.215, 0.61, 0.355, 1); +$ease-in : cubic-bezier(0.55, 0.055, 0.675, 0.19); +$ease-in-out : cubic-bezier(0.645, 0.045, 0.355, 1); +$ease-out-back : cubic-bezier(0.12, 0.4, 0.29, 1.46); +$ease-in-back : cubic-bezier(0.71, -0.46, 0.88, 0.6); +$ease-in-out-back : cubic-bezier(0.71, -0.46, 0.29, 1.46); +$ease-out-circ : cubic-bezier(0.08, 0.82, 0.17, 1); +$ease-in-circ : cubic-bezier(0.6, 0.04, 0.98, 0.34); +$ease-in-out-circ : cubic-bezier(0.78, 0.14, 0.15, 0.86); +$ease-out-quint : cubic-bezier(0.23, 1, 0.32, 1); +$ease-in-quint : cubic-bezier(0.755, 0.05, 0.855, 0.06); +$ease-in-out-quint : cubic-bezier(0.86, 0, 0.07, 1); + +// Shadow +$shadow-color : rgba(0, 0, 0, .2); +$shadow-1-up : 0 -1px 6px $shadow-color; +$shadow-1-down : 0 1px 6px $shadow-color; +$shadow-1-left : -1px 0 6px $shadow-color; +$shadow-1-right : 1px 0 6px $shadow-color; +$shadow-2 : 0 2px 8px $shadow-color; +$box-shadow-base : $shadow-1-down; + +$mask-color: rgba(55, 55, 55, .6); + +//header +$nav-hover-color : #1e252f; // 导航hover色 +$nav-color : #2e3846; // 导航色 + +// 文字颜色 +$first-text-color : #333333; // 一级文字 +$second-text-color : #666666; // 二级文字 +$third-text-color : #999999; // 三级文字 +$hint-text-color : #cccccc; // 提示文字 +$link-text-color : #267bf3; // 链接文字 +$error-text-color : #f62525; // 错误文字 +$white-text-color : #ffffff; // 反白文字 + +// 字体 +$font-family : "PingFang SC","Helvetica Neue","Hiragino Sans GB",Helvetica,"Microsoft YaHei",Arial,sans-serif; +$heading-font-size : 16px; // 对应颜色为 $first-text-color +$nav-font-size : 14px; // 对应颜色为 $first-text-color +$content-font-size : 12px; // 正文、辅助文字、提示文字、链接文字、错误文字均使用这个大小,对应颜色请参照上文“文字颜色” \ No newline at end of file diff --git a/ui/src/components/fesHeader.fes b/ui/src/components/fesHeader.fes new file mode 100644 index 00000000..ea996e8a --- /dev/null +++ b/ui/src/components/fesHeader.fes @@ -0,0 +1,324 @@ + + + + + + diff --git a/ui/src/components/fesLeft.fes b/ui/src/components/fesLeft.fes new file mode 100644 index 00000000..6e240e00 --- /dev/null +++ b/ui/src/components/fesLeft.fes @@ -0,0 +1,3 @@ + diff --git a/ui/src/components/filterDescription.fes b/ui/src/components/filterDescription.fes new file mode 100644 index 00000000..f04eefe0 --- /dev/null +++ b/ui/src/components/filterDescription.fes @@ -0,0 +1,17 @@ + + + diff --git a/ui/src/components/goBack.fes b/ui/src/components/goBack.fes new file mode 100644 index 00000000..92d6084f --- /dev/null +++ b/ui/src/components/goBack.fes @@ -0,0 +1,25 @@ + + + diff --git a/ui/src/components/leftMenu.fes b/ui/src/components/leftMenu.fes new file mode 100644 index 00000000..6dd22089 --- /dev/null +++ b/ui/src/components/leftMenu.fes @@ -0,0 +1,267 @@ + + + + + + + \ No newline at end of file diff --git a/ui/src/components/leftMenuPage.fes b/ui/src/components/leftMenuPage.fes new file mode 100644 index 00000000..bdff0c56 --- /dev/null +++ b/ui/src/components/leftMenuPage.fes @@ -0,0 +1,34 @@ + + + + diff --git a/ui/src/components/template.fes b/ui/src/components/template.fes new file mode 100644 index 00000000..bfc6d91e --- /dev/null +++ b/ui/src/components/template.fes @@ -0,0 +1,172 @@ + + + + + diff --git a/ui/src/pages/addGroupTechniqueRule/index.fes b/ui/src/pages/addGroupTechniqueRule/index.fes new file mode 100644 index 00000000..e0f196b6 --- /dev/null +++ b/ui/src/pages/addGroupTechniqueRule/index.fes @@ -0,0 +1,391 @@ + + + + + diff --git a/ui/src/pages/addTechniqueRule/index.fes b/ui/src/pages/addTechniqueRule/index.fes new file mode 100644 index 00000000..9d2f0040 --- /dev/null +++ b/ui/src/pages/addTechniqueRule/index.fes @@ -0,0 +1,1148 @@ + + + + diff --git a/ui/src/pages/configureParameter/index.fes b/ui/src/pages/configureParameter/index.fes new file mode 100644 index 00000000..d0c7dc88 --- /dev/null +++ b/ui/src/pages/configureParameter/index.fes @@ -0,0 +1,304 @@ + + + + \ No newline at end of file diff --git a/ui/src/pages/crossTableCheck/config.fes b/ui/src/pages/crossTableCheck/config.fes new file mode 100644 index 00000000..2a852bb8 --- /dev/null +++ b/ui/src/pages/crossTableCheck/config.fes @@ -0,0 +1,143 @@ + + + + + \ No newline at end of file diff --git a/ui/src/pages/crossTableCheck/filterCondition.fes b/ui/src/pages/crossTableCheck/filterCondition.fes new file mode 100644 index 00000000..d958fc05 --- /dev/null +++ b/ui/src/pages/crossTableCheck/filterCondition.fes @@ -0,0 +1,200 @@ + + + + + diff --git a/ui/src/pages/crossTableCheck/index.fes b/ui/src/pages/crossTableCheck/index.fes new file mode 100644 index 00000000..9dd8bedb --- /dev/null +++ b/ui/src/pages/crossTableCheck/index.fes @@ -0,0 +1,1426 @@ + + + + + + + diff --git a/ui/src/pages/crossTableCheck/mapRelation.fes b/ui/src/pages/crossTableCheck/mapRelation.fes new file mode 100644 index 00000000..d2cfd53d --- /dev/null +++ b/ui/src/pages/crossTableCheck/mapRelation.fes @@ -0,0 +1,160 @@ + + + + + diff --git a/ui/src/pages/crossTableCheck/whereCondition.fes b/ui/src/pages/crossTableCheck/whereCondition.fes new file mode 100644 index 00000000..3df3737d --- /dev/null +++ b/ui/src/pages/crossTableCheck/whereCondition.fes @@ -0,0 +1,205 @@ + + + diff --git a/ui/src/pages/customTechnicalRule/index.fes b/ui/src/pages/customTechnicalRule/index.fes new file mode 100644 index 00000000..83809f68 --- /dev/null +++ b/ui/src/pages/customTechnicalRule/index.fes @@ -0,0 +1,761 @@ + + + + + \ No newline at end of file diff --git a/ui/src/pages/dashboard/AlarmsList.fes b/ui/src/pages/dashboard/AlarmsList.fes new file mode 100644 index 00000000..c23027de --- /dev/null +++ b/ui/src/pages/dashboard/AlarmsList.fes @@ -0,0 +1,64 @@ + + + + + diff --git a/ui/src/pages/dashboard/index.fes b/ui/src/pages/dashboard/index.fes new file mode 100644 index 00000000..c2e7e45b --- /dev/null +++ b/ui/src/pages/dashboard/index.fes @@ -0,0 +1,333 @@ + + + + + \ No newline at end of file diff --git a/ui/src/pages/error/index.fes b/ui/src/pages/error/index.fes new file mode 100644 index 00000000..a728eaac --- /dev/null +++ b/ui/src/pages/error/index.fes @@ -0,0 +1,39 @@ + + + diff --git a/ui/src/pages/home/index.fes b/ui/src/pages/home/index.fes new file mode 100644 index 00000000..75f0cdaa --- /dev/null +++ b/ui/src/pages/home/index.fes @@ -0,0 +1,116 @@ + + + + + diff --git a/ui/src/pages/metadataManagement/index.fes b/ui/src/pages/metadataManagement/index.fes new file mode 100644 index 00000000..e13a614e --- /dev/null +++ b/ui/src/pages/metadataManagement/index.fes @@ -0,0 +1,413 @@ + + + + + diff --git a/ui/src/pages/myProject/projects/add.fes b/ui/src/pages/myProject/projects/add.fes new file mode 100644 index 00000000..bff4cf10 --- /dev/null +++ b/ui/src/pages/myProject/projects/add.fes @@ -0,0 +1,21 @@ + + diff --git a/ui/src/pages/myProject/projects/index.fes b/ui/src/pages/myProject/projects/index.fes new file mode 100644 index 00000000..37e74b8f --- /dev/null +++ b/ui/src/pages/myProject/projects/index.fes @@ -0,0 +1,547 @@ + + + + + diff --git a/ui/src/pages/myProject/projects/list/index.fes b/ui/src/pages/myProject/projects/list/index.fes new file mode 100644 index 00000000..0e7564a5 --- /dev/null +++ b/ui/src/pages/myProject/projects/list/index.fes @@ -0,0 +1,481 @@ + + + diff --git a/ui/src/pages/myProject/projects/projForm.fes b/ui/src/pages/myProject/projects/projForm.fes new file mode 100644 index 00000000..a28f9bc0 --- /dev/null +++ b/ui/src/pages/myProject/projects/projForm.fes @@ -0,0 +1,324 @@ + + + diff --git a/ui/src/pages/optionManage/components/permissionTable.fes b/ui/src/pages/optionManage/components/permissionTable.fes new file mode 100644 index 00000000..4885468e --- /dev/null +++ b/ui/src/pages/optionManage/components/permissionTable.fes @@ -0,0 +1,227 @@ + + diff --git a/ui/src/pages/optionManage/components/roleTable.fes b/ui/src/pages/optionManage/components/roleTable.fes new file mode 100644 index 00000000..7683dd7a --- /dev/null +++ b/ui/src/pages/optionManage/components/roleTable.fes @@ -0,0 +1,290 @@ + + diff --git a/ui/src/pages/optionManage/components/roleperTable.fes b/ui/src/pages/optionManage/components/roleperTable.fes new file mode 100644 index 00000000..2a399d05 --- /dev/null +++ b/ui/src/pages/optionManage/components/roleperTable.fes @@ -0,0 +1,370 @@ + + diff --git a/ui/src/pages/optionManage/components/userroleTable.fes b/ui/src/pages/optionManage/components/userroleTable.fes new file mode 100644 index 00000000..ff997cd5 --- /dev/null +++ b/ui/src/pages/optionManage/components/userroleTable.fes @@ -0,0 +1,359 @@ + + \ No newline at end of file diff --git a/ui/src/pages/optionManage/components/userspecTable.fes b/ui/src/pages/optionManage/components/userspecTable.fes new file mode 100644 index 00000000..45a7095a --- /dev/null +++ b/ui/src/pages/optionManage/components/userspecTable.fes @@ -0,0 +1,393 @@ + + diff --git a/ui/src/pages/optionManage/index.fes b/ui/src/pages/optionManage/index.fes new file mode 100644 index 00000000..3c38c32f --- /dev/null +++ b/ui/src/pages/optionManage/index.fes @@ -0,0 +1,52 @@ + + + + diff --git a/ui/src/pages/personnelManage/groupUser.fes b/ui/src/pages/personnelManage/groupUser.fes new file mode 100644 index 00000000..cd07f328 --- /dev/null +++ b/ui/src/pages/personnelManage/groupUser.fes @@ -0,0 +1,196 @@ + + + diff --git a/ui/src/pages/personnelManage/index.fes b/ui/src/pages/personnelManage/index.fes new file mode 100644 index 00000000..30d7aa36 --- /dev/null +++ b/ui/src/pages/personnelManage/index.fes @@ -0,0 +1,424 @@ + + + diff --git a/ui/src/pages/route.fes b/ui/src/pages/route.fes new file mode 100644 index 00000000..1aeda226 --- /dev/null +++ b/ui/src/pages/route.fes @@ -0,0 +1,24 @@ + + diff --git a/ui/src/pages/ruleQuery/index.fes b/ui/src/pages/ruleQuery/index.fes new file mode 100644 index 00000000..6796ff57 --- /dev/null +++ b/ui/src/pages/ruleQuery/index.fes @@ -0,0 +1,258 @@ + + + \ No newline at end of file diff --git a/ui/src/pages/ruleQuery/projectId.fes b/ui/src/pages/ruleQuery/projectId.fes new file mode 100644 index 00000000..ad68112e --- /dev/null +++ b/ui/src/pages/ruleQuery/projectId.fes @@ -0,0 +1,324 @@ + + + + + \ No newline at end of file diff --git a/ui/src/pages/ruleTemplateList/detail.fes b/ui/src/pages/ruleTemplateList/detail.fes new file mode 100644 index 00000000..189e5bd1 --- /dev/null +++ b/ui/src/pages/ruleTemplateList/detail.fes @@ -0,0 +1,192 @@ +