From 78b91ee3e0b72623192ac433775d4e8da2418766 Mon Sep 17 00:00:00 2001 From: Ioannis Kalyvas Date: Wed, 11 Jul 2018 16:47:36 +0300 Subject: [PATCH] no message --- .env | 8 +- .gitignore | 2 + ELK.Docker/.env | 4 +- ELK.Docker/docker-compose.yml | 69 +- dmp-backend/Dockerfile | 10 +- dmp-backend/data/pom.xml | 5 + .../data/dao/criteria/DatasetCriteria.java | 11 + .../java/eu/eudat/data/entities/Dataset.java | 22 +- dmp-backend/elastic/pom.xml | 14 + .../eu/eudat/elastic/criteria/Criteria.java | 7 + .../elastic/criteria/DatasetCriteria.java | 20 + .../eudat/elastic/criteria/TagCriteria.java | 7 + .../eu/eudat/elastic/entities/Dataset.java | 60 + .../eudat/elastic/entities/ElasticEntity.java | 15 + .../java/eu/eudat/elastic/entities/Tag.java | 45 + .../elastic/repository/DatasetRepository.java | 72 + .../elastic/repository/ElasticRepository.java | 36 + .../eudat/elastic/repository/Repository.java | 22 + dmp-backend/pom.xml | 23 +- dmp-backend/queryengine/pom.xml | 22 + .../queryengine/src/main/java/Main.java | 14 + .../query/engine/builder/QueryBuilder.java | 16 + .../engine/builder/QueryBuilderImpl.java | 22 + .../expressions/AbstractFieldExpression.java | 17 + .../expressions/ComparisonExpression.java | 43 + .../query/engine/expressions/Expression.java | 7 + .../query/engine/predicates/AndPredicate.java | 11 + .../predicates/ComparisonPredicate.java | 9 + .../query/engine/predicates/Predicate.java | 11 + .../comparison/ComparisonExpressionType.java | 8 + dmp-backend/web/pom.xml | 9 + .../java/eu/eudat/cache/ResponsesCache.java | 1 + .../ElasticSearchConfiguration.java | 39 + .../DynamicProjectConfigurationProdImpl.java | 3 +- .../controllers/DatasetWizardController.java | 3 +- .../eu/eudat/controllers/TagController.java | 67 + .../eudat/logic/managers/CommonsManager.java | 2 + .../eudat/logic/managers/DatasetManager.java | 74 +- .../logic/proxy/config/ExternalUrls.java | 10 + .../configloaders/ProductionConfigLoader.java | 3 +- .../logic/proxy/config/entities/TagUrls.java | 35 + .../logic/proxy/fetching/RemoteFetcher.java | 9 + .../eudat/logic/services/ApiContextImpl.java | 2 + .../operations/OperationsContext.java | 2 + .../operations/OperationsContextImpl.java | 14 +- .../datasetwizard/DatasetWizardModel.java | 10 + .../external/TagExternalSourcesModel.java | 22 + .../ExternalSourcesConfiguration.java | 9 + .../web/src/main/resources/ExternalUrls.xml | 39 + .../src/main/resources/application.properties | 11 +- dmp-frontend/.angular-cli.json | 60 - dmp-frontend/Dockerfile | 6 +- dmp-frontend/angular.json | 132 + dmp-frontend/package-lock.json | 3201 +++++++++++------ dmp-frontend/package.json | 42 +- dmp-frontend/src/app/app.component.html | 2 +- dmp-frontend/src/app/app.component.scss | 5 +- dmp-frontend/src/app/app.module.ts | 5 +- .../field-form/field-form.component.html | 174 +- .../section-form/section-form.component.html | 136 +- .../dataset-wizard.component.html | 57 +- .../dataset-wizard.component.ts | 32 +- .../dmp-profile-editor.component.ts | 1 - dmp-frontend/src/app/dmps/dmps.module.ts | 1 + .../app/dmps/editor/dmp-editor.component.html | 37 +- .../app/dmps/editor/dmp-editor.component.ts | 1 - .../app/dmps/wizard/dmp-wizard.component.html | 36 +- .../app/dmps/wizard/dmp-wizard.component.ts | 9 +- .../editor/dmp-wizard-editor.component.ts | 1 - .../autocomplete-remote.component.ts | 10 +- .../dynamic-form-field.component.html | 47 +- .../dynamic-form-field.component.ts | 2 +- .../dynamic-form-group.component.ts | 2 +- .../dynamic-form-section.ts | 2 +- .../pprogress-bar/progress-bar.component.html | 4 +- .../pprogress-bar/progress-bar.component.ts | 2 +- .../table-of-contents.component.html | 10 +- .../table-of-contents.component.ts | 15 +- .../src/app/homepage/homepage.component.ts | 4 +- .../criteria/dataset/DatasetCriteria.ts | 8 +- .../app/models/criteria/tags/TagsCriteria.ts | 6 + .../app/models/datasets/DatasetWizardModel.ts | 16 +- .../ExternalSourcesConfiguration.ts | 11 +- dmp-frontend/src/app/models/tags/TagModel.ts | 27 + .../editor/project-editor.component.ts | 1 - .../listing/project-listing.component.ts | 8 +- .../src/app/services/auth/auth.service.ts | 2 - .../external-sources.service.ts | 15 + .../add-researchers.component.ts | 2 +- .../auto-complete.component.html | 4 +- .../auto-complete/auto-complete.component.ts | 6 + .../autocomplete/autocomplete.component.html | 23 +- .../autocompleteChips.component.html | 37 +- .../available-profiles.component.ts | 6 +- .../breadcrumb/breadcrumb.component.html | 8 +- .../criteria/base/base-criteria.component.ts | 180 +- .../dmp-criteria.component.ts | 7 +- .../datasets/datasets-criteria.component.html | 23 +- .../datasets/datasets-criteria.component.ts | 110 +- .../projects/projects-criteria.component.html | 2 +- .../external-item-listing.component.html | 5 +- .../external-item-listing.component.ts | 3 + .../external-item.component.html | 4 +- .../external-item/external-item.component.ts | 3 + .../file-uploader.component.html | 20 +- .../invitation/invitation.component.ts | 10 +- .../navigation/navigation.component.html | 3 - .../navigation/navigation.component.ts | 8 +- .../url-listing/url-listing.component.ts | 2 +- .../combobox/combobox-component.html | 28 +- .../radiobox/radiobox-component.html | 48 +- .../wordlist/wordlist-component.html | 46 +- .../help-content/help-content.component.ts | 1 + .../admin-login/admin-login.component.html | 58 +- .../admin-login/admin-login.component.scss | 271 +- .../login/login.component.html | 15 +- .../login/login.component.scss | 57 +- .../user-management/utilties/login-service.ts | 394 +- .../roles/user-role-editor.component.ts | 16 +- .../app/users/components/users.component.ts | 1 - .../base-http.service.ts | 16 +- .../app/welcomepage/welcomepage.component.ts | 1 - dmp-frontend/src/assets/lang/en.json | 3 +- dmp-frontend/src/environments/environment.ts | 2 +- dmp-frontend/tslint.json | 1 - docker-compose.yml | 160 +- docsbox-master/.gitignore | 48 + docsbox-master/.travis.yml | 7 + docsbox-master/LICENSE | 21 + docsbox-master/README.md | 134 + docsbox-master/docker-compose.yml | 67 + docsbox-master/docsbox/Dockerfile | 17 + docsbox-master/docsbox/__init__.py | 32 + docsbox-master/docsbox/docs/__init__.py | 0 docsbox-master/docsbox/docs/tasks.py | 56 + .../docsbox/docs/tests/samples/sample.docx | Bin 0 -> 215696 bytes .../docsbox/docs/tests/test_views.py | 149 + docsbox-master/docsbox/docs/utils.py | 40 + docsbox-master/docsbox/docs/views.py | 93 + docsbox-master/docsbox/requirements.txt | 14 + docsbox-master/docsbox/settings.py | 98 + docsbox-master/nginx/Dockerfile | 3 + docsbox-master/nginx/sites-enabled/docsbox | 20 + elastic-config/elasticsearch-custom.yml | 3 + 144 files changed, 5325 insertions(+), 2187 deletions(-) create mode 100644 dmp-backend/elastic/pom.xml create mode 100644 dmp-backend/elastic/src/main/java/eu/eudat/elastic/criteria/Criteria.java create mode 100644 dmp-backend/elastic/src/main/java/eu/eudat/elastic/criteria/DatasetCriteria.java create mode 100644 dmp-backend/elastic/src/main/java/eu/eudat/elastic/criteria/TagCriteria.java create mode 100644 dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Dataset.java create mode 100644 dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/ElasticEntity.java create mode 100644 dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Tag.java create mode 100644 dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java create mode 100644 dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/ElasticRepository.java create mode 100644 dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/Repository.java create mode 100644 dmp-backend/queryengine/pom.xml create mode 100644 dmp-backend/queryengine/src/main/java/Main.java create mode 100644 dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/builder/QueryBuilder.java create mode 100644 dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/builder/QueryBuilderImpl.java create mode 100644 dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/expressions/AbstractFieldExpression.java create mode 100644 dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/expressions/ComparisonExpression.java create mode 100644 dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/expressions/Expression.java create mode 100644 dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/predicates/AndPredicate.java create mode 100644 dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/predicates/ComparisonPredicate.java create mode 100644 dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/predicates/Predicate.java create mode 100644 dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/types/expression/comparison/ComparisonExpressionType.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/configurations/ElasticSearchConfiguration.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/controllers/TagController.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/TagUrls.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/external/TagExternalSourcesModel.java delete mode 100644 dmp-frontend/.angular-cli.json create mode 100644 dmp-frontend/angular.json create mode 100644 dmp-frontend/src/app/models/criteria/tags/TagsCriteria.ts create mode 100644 dmp-frontend/src/app/models/tags/TagModel.ts create mode 100644 docsbox-master/.gitignore create mode 100644 docsbox-master/.travis.yml create mode 100644 docsbox-master/LICENSE create mode 100644 docsbox-master/README.md create mode 100644 docsbox-master/docker-compose.yml create mode 100644 docsbox-master/docsbox/Dockerfile create mode 100644 docsbox-master/docsbox/__init__.py create mode 100644 docsbox-master/docsbox/docs/__init__.py create mode 100644 docsbox-master/docsbox/docs/tasks.py create mode 100644 docsbox-master/docsbox/docs/tests/samples/sample.docx create mode 100644 docsbox-master/docsbox/docs/tests/test_views.py create mode 100644 docsbox-master/docsbox/docs/utils.py create mode 100644 docsbox-master/docsbox/docs/views.py create mode 100644 docsbox-master/docsbox/requirements.txt create mode 100644 docsbox-master/docsbox/settings.py create mode 100644 docsbox-master/nginx/Dockerfile create mode 100644 docsbox-master/nginx/sites-enabled/docsbox create mode 100644 elastic-config/elasticsearch-custom.yml diff --git a/.env b/.env index abfd8c55f..31c132e98 100644 --- a/.env +++ b/.env @@ -1,6 +1,6 @@ -TAG=6.2.1 -ENV=dev +TAG=6.3.0 +ENV=prod PROFILE=production -AOT=no-aot -ELASTIC_VERSION=6.2.1 +AOT=aot +ELASTIC_VERSION=6.3.0 ELASTIC_PASSWORD=changeme diff --git a/.gitignore b/.gitignore index a064ebc2a..688694412 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ dmp-backend/web/src/main/ui-resources/static/ dmp-backend/data/target/data-1.0-SNAPSHOT.jar dmp-backend/data/target/ dmp-backend/queryable/target/ +dmp-backend/elastic/target/ +dmp-backend/queryengine/target/ diff --git a/ELK.Docker/.env b/ELK.Docker/.env index fcb78b08a..d2aa1da5a 100644 --- a/ELK.Docker/.env +++ b/ELK.Docker/.env @@ -1,3 +1,3 @@ -TAG=6.2.1 -ELASTIC_VERSION=6.2.1 +TAG=6.3.1 +ELASTIC_VERSION=6.3.1 ELASTIC_PASSWORD=changeme diff --git a/ELK.Docker/docker-compose.yml b/ELK.Docker/docker-compose.yml index 28357dce4..e64762965 100644 --- a/ELK.Docker/docker-compose.yml +++ b/ELK.Docker/docker-compose.yml @@ -100,7 +100,72 @@ services: networks: ['stack'] depends_on: ['kibana'] -#volumes: + +##########################DOCSBOX###################################################################### + web: + restart: always + build: ./docsbox-master/docsbox + expose: + - "8000" + links: + - redis:redis + volumes: + - docsbox:/home/docsbox + - media:/home/docsbox/media + command: gunicorn -b :8000 docsbox:app + networks: ['stack'] + + rqworker: + restart: always + build: ./docsbox-master/docsbox + links: + - redis:redis + volumes: + - web + command: rq worker -c docsbox.settings + networks: ['stack'] + + rqscheduler: + restart: always + build: ./docsbox-master/docsbox + links: + - redis:redis + volumes: + - web + command: rqscheduler -H redis -p 6379 -d 0 + networks: ['stack'] + + nginx: + restart: always + build: ./docsbox-master/nginx/ + ports: + - "81:80" + volumes: + - web + links: + - web:web + networks: ['stack'] + + redis: + restart: always + image: redis:latest + expose: + - "6379" + volumes: + - redisdata:/data + networks: ['stack'] + + +##########################SETTIGNS###################################################################### + +volumes: #esdata: - # driver: local + #driver: local + redisdata: + driver: local + docsbox: + driver: local + media: + driver: local networks: {stack: {}} + diff --git a/dmp-backend/Dockerfile b/dmp-backend/Dockerfile index 79cf08791..8701a23a0 100644 --- a/dmp-backend/Dockerfile +++ b/dmp-backend/Dockerfile @@ -1,5 +1,11 @@ FROM openjdk:8-jdk-alpine +RUN apk add --update \ + curl \ + && rm -rf /var/cache/apk/* VOLUME /tmp -ARG PROFILE=dev +ARG PROFILE=production +ENV PROF $PROFILE +ADD web/src/main/resources/ProjectConfiguration.xml /tmp/ProjectConfiguration.xml +ADD web/src/main/resources/ExternalUrls.xml /tmp/ExternalUrls.xml ADD web/target/web-1.0-SNAPSHOT.jar app.jar -ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=${PROFILE}","-jar","/app.jar"] \ No newline at end of file +ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom" ,"-Dspring.profiles.active=${PROF}","-jar","/app.jar"] \ No newline at end of file diff --git a/dmp-backend/data/pom.xml b/dmp-backend/data/pom.xml index c7cfef263..7a256c0ea 100644 --- a/dmp-backend/data/pom.xml +++ b/dmp-backend/data/pom.xml @@ -21,5 +21,10 @@ queryable 1.0-SNAPSHOT + + eu.eudat + elastic + 1.0.0-SNAPSHOT + \ No newline at end of file diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetCriteria.java index 2ffabff41..31072be46 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetCriteria.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetCriteria.java @@ -1,6 +1,7 @@ package eu.eudat.data.dao.criteria; import eu.eudat.data.entities.Dataset; +import eu.eudat.elastic.entities.Tag; import java.util.Date; import java.util.List; @@ -12,8 +13,10 @@ public class DatasetCriteria extends Criteria { private Date periodStart; private Date periodEnd; private List dmpIds; + private List tags; private boolean allVersions; + public boolean getAllVersions() { return allVersions; } @@ -53,4 +56,12 @@ public class DatasetCriteria extends Criteria { public void setDmpIds(List dmpIds) { this.dmpIds = dmpIds; } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java index 58969ef3b..e9adc4d5a 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java @@ -14,15 +14,23 @@ import java.util.stream.Collectors; @NamedEntityGraphs({ @NamedEntityGraph( name = "datasetListingModel", - attributeNodes = {@NamedAttributeNode("services"), @NamedAttributeNode("datasetDataRepositories"), @NamedAttributeNode("datasetExternalDatasets"), @NamedAttributeNode("registries"), + attributeNodes = {@NamedAttributeNode("services"), @NamedAttributeNode(value = "datasetDataRepositories", subgraph = "datasetDataRepositories"), @NamedAttributeNode("datasetExternalDatasets"), @NamedAttributeNode("registries"), @NamedAttributeNode(value = "dmp", subgraph = "dmp"), @NamedAttributeNode("profile"), @NamedAttributeNode("creator")}, - subgraphs = @NamedSubgraph(name = "dmp", attributeNodes = {@NamedAttributeNode("creator"), @NamedAttributeNode("users")})), + subgraphs = { + @NamedSubgraph(name = "dmp", attributeNodes = {@NamedAttributeNode("creator"), @NamedAttributeNode("users")}), + @NamedSubgraph(name = "datasetDataRepositories", attributeNodes = {@NamedAttributeNode("dataRepository")}) + }), + @NamedEntityGraph( name = "datasetWizardModel", attributeNodes = {@NamedAttributeNode("services"), @NamedAttributeNode("datasetDataRepositories"), @NamedAttributeNode("datasetExternalDatasets"), @NamedAttributeNode("registries"), @NamedAttributeNode("dmp"), @NamedAttributeNode("profile"), @NamedAttributeNode("creator")}), @NamedEntityGraph( name = "datasetRecentActivity", + attributeNodes = {@NamedAttributeNode(value = "dmp", subgraph = "dmp")}, + subgraphs = @NamedSubgraph(name = "dmp", attributeNodes = {@NamedAttributeNode("users")})), + @NamedEntityGraph( + name = "datasetDataRepositories", attributeNodes = {@NamedAttributeNode(value = "dmp", subgraph = "dmp"), @NamedAttributeNode("creator")}, subgraphs = @NamedSubgraph(name = "dmp", attributeNodes = {@NamedAttributeNode("creator"), @NamedAttributeNode("users")})) }) @@ -291,10 +299,10 @@ public class Dataset implements DataEntity { @Override public void update(Dataset entity) { this.setRegistries(entity.getRegistries()); - if(this.getDatasetDataRepositories()==null) this.setDatasetDataRepositories(new HashSet<>()); - if(!this.getDatasetDataRepositories().containsAll(entity.getDatasetDataRepositories())){ + if (this.getDatasetDataRepositories() == null) this.setDatasetDataRepositories(new HashSet<>()); + if (!this.getDatasetDataRepositories().containsAll(entity.getDatasetDataRepositories())) { this.getDatasetDataRepositories().removeAll(this.getDatasetDataRepositories()); - this.getDatasetDataRepositories().addAll(entity.getDatasetDataRepositories().stream().map(item->{ + this.getDatasetDataRepositories().addAll(entity.getDatasetDataRepositories().stream().map(item -> { item.setDataset(this); return item; }).collect(Collectors.toList())); @@ -302,8 +310,8 @@ public class Dataset implements DataEntity { this.setDescription(entity.getDescription()); this.setLabel(entity.getLabel()); this.setProperties(entity.getProperties()); - if(this.getDatasetExternalDatasets()==null) this.setDatasetExternalDatasets(new HashSet<>()); - if(!this.getDatasetExternalDatasets().containsAll(entity.getDatasetExternalDatasets())) { + if (this.getDatasetExternalDatasets() == null) this.setDatasetExternalDatasets(new HashSet<>()); + if (!this.getDatasetExternalDatasets().containsAll(entity.getDatasetExternalDatasets())) { this.getDatasetExternalDatasets().removeAll(this.getDatasetExternalDatasets()); this.getDatasetExternalDatasets().addAll(entity.getDatasetExternalDatasets().stream().map(item -> { item.setDataset(this); diff --git a/dmp-backend/elastic/pom.xml b/dmp-backend/elastic/pom.xml new file mode 100644 index 000000000..a78208200 --- /dev/null +++ b/dmp-backend/elastic/pom.xml @@ -0,0 +1,14 @@ + + + + dmp-backend + eu.eudat + 1.0.0-SNAPSHOT + + 4.0.0 + + elastic + + \ No newline at end of file diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/criteria/Criteria.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/criteria/Criteria.java new file mode 100644 index 000000000..fa1bcd635 --- /dev/null +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/criteria/Criteria.java @@ -0,0 +1,7 @@ +package eu.eudat.elastic.criteria; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public abstract class Criteria { +} diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/criteria/DatasetCriteria.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/criteria/DatasetCriteria.java new file mode 100644 index 000000000..61a6ae3dc --- /dev/null +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/criteria/DatasetCriteria.java @@ -0,0 +1,20 @@ +package eu.eudat.elastic.criteria; + +import eu.eudat.elastic.entities.Tag; + +import java.util.List; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public class DatasetCriteria extends Criteria { + public List tags; + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } +} diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/criteria/TagCriteria.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/criteria/TagCriteria.java new file mode 100644 index 000000000..37a8f9861 --- /dev/null +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/criteria/TagCriteria.java @@ -0,0 +1,7 @@ +package eu.eudat.elastic.criteria; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public class TagCriteria extends Criteria { +} diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Dataset.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Dataset.java new file mode 100644 index 000000000..2fca86b57 --- /dev/null +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Dataset.java @@ -0,0 +1,60 @@ +package eu.eudat.elastic.entities; + +import org.elasticsearch.common.xcontent.XContentBuilder; + +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public class Dataset implements ElasticEntity { + + private String id; + private List tags = new LinkedList<>(); + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + @Override + public XContentBuilder toElasticEntity(XContentBuilder builder) throws IOException { + builder.startObject(); + builder.field("id", this.id); + builder.startArray("tags"); + this.tags.forEach(x -> { + try { + x.toElasticEntity(builder); + } catch (IOException e) { + e.printStackTrace(); + } + }); + builder.endArray(); + builder.endObject(); + return builder; + } + + @Override + public Dataset fromElasticEntity(Map fields) { + if (fields != null) { + this.id = (String) fields.get("id"); + this.tags = ((List) fields.get("tags")); + } + return this; + } + +} diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/ElasticEntity.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/ElasticEntity.java new file mode 100644 index 000000000..2f6b5f714 --- /dev/null +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/ElasticEntity.java @@ -0,0 +1,15 @@ +package eu.eudat.elastic.entities; + +import org.elasticsearch.common.document.DocumentField; +import org.elasticsearch.common.xcontent.XContentBuilder; + +import java.io.IOException; +import java.util.Map; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public interface ElasticEntity { + XContentBuilder toElasticEntity(XContentBuilder builder) throws IOException; + T fromElasticEntity(Map fields); +} diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Tag.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Tag.java new file mode 100644 index 000000000..27e27a86f --- /dev/null +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Tag.java @@ -0,0 +1,45 @@ +package eu.eudat.elastic.entities; + +import org.elasticsearch.common.xcontent.XContentBuilder; + +import java.io.IOException; +import java.util.Map; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public class Tag implements ElasticEntity { + + private String id; + private String name; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public XContentBuilder toElasticEntity(XContentBuilder builder) throws IOException { + builder.startObject(); + builder.field("id", this.id); + builder.field("name", this.name); + builder.endObject(); + return builder; + } + + @Override + public Object fromElasticEntity(Map fields) { + return null; + } +} diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java new file mode 100644 index 000000000..c5be3055e --- /dev/null +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java @@ -0,0 +1,72 @@ +package eu.eudat.elastic.repository; + +import eu.eudat.elastic.criteria.DatasetCriteria; +import eu.eudat.elastic.entities.Dataset; +import org.elasticsearch.action.admin.indices.get.GetIndexRequest; +import org.elasticsearch.action.get.GetRequest; +import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.SearchType; +import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.index.query.BoolQueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; + +/** + * Created by ikalyvas on 7/5/2018. + */ +@Service("datasetRepository") +public class DatasetRepository extends ElasticRepository { + + @Autowired + public DatasetRepository(RestHighLevelClient client) { + super(client); + } + + @Override + public Dataset createOrUpdate(Dataset entity) throws IOException { + XContentBuilder builder = XContentFactory.jsonBuilder(); + IndexRequest request = new IndexRequest("datasets", "doc", entity.getId()).source(entity.toElasticEntity(builder)); + this.getClient().index(request); + return entity; + } + + @Override + public Dataset findDocument(String id) throws IOException { + GetRequest request = new GetRequest("datasets","doc",id); + GetResponse response = this.getClient().get(request); + return new Dataset().fromElasticEntity(response.getSourceAsMap()); + } + + @Override + public List query(DatasetCriteria criteria) throws ExecutionException, InterruptedException, IOException { + SearchRequest searchRequest = new SearchRequest(); + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); + + BoolQueryBuilder boolQuery = QueryBuilders.boolQuery() + .should(QueryBuilders.termsQuery("tags.name.keyword", criteria.getTags().stream().map(x -> x.getName()).collect(Collectors.toList()))); + searchSourceBuilder.query(boolQuery); + searchRequest.source(searchSourceBuilder); + SearchResponse response = this.getClient().search(searchRequest); + return Arrays.stream(response.getHits().getHits()).map(x -> this.transformFromString(x.getSourceAsString(), Dataset.class)).collect(Collectors.toList()); + } + + @Override + public boolean exists() throws IOException { + GetIndexRequest request = new GetIndexRequest(); + request.indices("datasets"); + return this.getClient().indices().exists(request); + } +} diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/ElasticRepository.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/ElasticRepository.java new file mode 100644 index 000000000..90b9f3d36 --- /dev/null +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/ElasticRepository.java @@ -0,0 +1,36 @@ +package eu.eudat.elastic.repository; + +import com.fasterxml.jackson.databind.ObjectMapper; +import eu.eudat.elastic.criteria.Criteria; +import eu.eudat.elastic.entities.ElasticEntity; +import org.elasticsearch.client.Client; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestHighLevelClient; + +import java.io.IOException; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public abstract class ElasticRepository implements Repository { + private RestHighLevelClient client; + + public RestHighLevelClient getClient() { + return client; + } + + public ElasticRepository(RestHighLevelClient client) { + this.client = client; + } + + public T transformFromString(String value, Class tClass) { + ObjectMapper mapper = new ObjectMapper(); + T item = null; + try { + item = mapper.readValue(value, tClass); + } catch (IOException e) { + e.printStackTrace(); + } + return item; + } +} diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/Repository.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/Repository.java new file mode 100644 index 000000000..22b98db46 --- /dev/null +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/Repository.java @@ -0,0 +1,22 @@ +package eu.eudat.elastic.repository; + +import eu.eudat.elastic.criteria.Criteria; +import eu.eudat.elastic.entities.ElasticEntity; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ExecutionException; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public interface Repository { + + ET createOrUpdate(ET entity) throws IOException; + + ET findDocument(String id) throws IOException; + + List query(C criteria) throws ExecutionException, InterruptedException, IOException; + + boolean exists() throws IOException; +} diff --git a/dmp-backend/pom.xml b/dmp-backend/pom.xml index 14d450858..691660a05 100644 --- a/dmp-backend/pom.xml +++ b/dmp-backend/pom.xml @@ -18,7 +18,8 @@ web data logging - + queryengine + elastic @@ -65,6 +66,19 @@ org.springframework.boot spring-boot-starter-data-jpa + + + + org.elasticsearch + elasticsearch + 6.3.1 + + + + org.elasticsearch.client + elasticsearch-rest-high-level-client + 6.3.1 + org.hibernate hibernate-core @@ -172,6 +186,11 @@ hibernate-jpamodelgen + + org.elasticsearch.client + transport + 6.3.0 + @@ -188,7 +207,7 @@ production - war + jar diff --git a/dmp-backend/queryengine/pom.xml b/dmp-backend/queryengine/pom.xml new file mode 100644 index 000000000..7e74fc9f2 --- /dev/null +++ b/dmp-backend/queryengine/pom.xml @@ -0,0 +1,22 @@ + + + + dmp-backend + eu.eudat + 1.0.0-SNAPSHOT + + 4.0.0 + + query-engine + + + + eu.eudat + data + 1.0-SNAPSHOT + + + + \ No newline at end of file diff --git a/dmp-backend/queryengine/src/main/java/Main.java b/dmp-backend/queryengine/src/main/java/Main.java new file mode 100644 index 000000000..d8e1c8d56 --- /dev/null +++ b/dmp-backend/queryengine/src/main/java/Main.java @@ -0,0 +1,14 @@ +import eu.eudat.data.entities.DataRepository; +import eu.eudat.query.engine.builder.QueryBuilder; +import eu.eudat.query.engine.builder.QueryBuilderImpl; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public class Main { + public void Test(){ + QueryBuilder queryBuilder = new QueryBuilderImpl<>(); + queryBuilder.where((entity, comparisonExpression) -> comparisonExpression.field("id").greaterThan(5)); + //queryBuilder.and(((entity, expression) -> expression.field("id").greaterThan(4)),((entity, expression) -> expression.field("id").greaterThan(5))); + } +} diff --git a/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/builder/QueryBuilder.java b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/builder/QueryBuilder.java new file mode 100644 index 000000000..d81cb366c --- /dev/null +++ b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/builder/QueryBuilder.java @@ -0,0 +1,16 @@ +package eu.eudat.query.engine.builder; + +import eu.eudat.query.engine.expressions.Expression; +import eu.eudat.query.engine.predicates.AndPredicate; +import eu.eudat.query.engine.predicates.ComparisonPredicate; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public interface QueryBuilder { + + Expression where(ComparisonPredicate wherePredicate); + + Expression and(AndPredicate andPredicate); + +} diff --git a/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/builder/QueryBuilderImpl.java b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/builder/QueryBuilderImpl.java new file mode 100644 index 000000000..2ded22651 --- /dev/null +++ b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/builder/QueryBuilderImpl.java @@ -0,0 +1,22 @@ +package eu.eudat.query.engine.builder; + +import eu.eudat.query.engine.expressions.Expression; +import eu.eudat.query.engine.predicates.AndPredicate; +import eu.eudat.query.engine.predicates.ComparisonPredicate; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public class QueryBuilderImpl implements QueryBuilder { + + + @Override + public Expression where(ComparisonPredicate wherePredicate) { + return null; + } + + @Override + public Expression and(AndPredicate andPredicate) { + return null; + } +} diff --git a/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/expressions/AbstractFieldExpression.java b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/expressions/AbstractFieldExpression.java new file mode 100644 index 000000000..c61161db3 --- /dev/null +++ b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/expressions/AbstractFieldExpression.java @@ -0,0 +1,17 @@ +package eu.eudat.query.engine.expressions; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public abstract class AbstractFieldExpression> { + private String field; + + protected String getField() { + return field; + } + + public T field(String field) { + this.field = field; + return (T)this; + } +} diff --git a/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/expressions/ComparisonExpression.java b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/expressions/ComparisonExpression.java new file mode 100644 index 000000000..38d59facf --- /dev/null +++ b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/expressions/ComparisonExpression.java @@ -0,0 +1,43 @@ +package eu.eudat.query.engine.expressions; + +import eu.eudat.query.engine.types.expression.comparison.ComparisonExpressionType; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public class ComparisonExpression extends AbstractFieldExpression implements Expression { + + private ComparisonExpressionType type; + private Object value; + + public Expression greaterThan(T value){ + this.value = value; + this.type = ComparisonExpressionType.GREATER_THAN; + return this; + } + + public Expression greaterThanOrEqual(T value){ + this.value = value; + this.type = ComparisonExpressionType.GREATER_OR_EQUAL_THAN; + return this; + } + + public Expression equal(T value){ + this.value = value; + this.type = ComparisonExpressionType.EQUAL; + return this; + } + + public Expression lessThan(T value){ + this.value = value; + this.type = ComparisonExpressionType.LESS_THAN; + return this; + } + + public Expression lessOrEqualThan(T value){ + this.value = value; + this.type = ComparisonExpressionType.LESS_OR_EQUAL_THAN; + return this; + } + +} diff --git a/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/expressions/Expression.java b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/expressions/Expression.java new file mode 100644 index 000000000..5109ed351 --- /dev/null +++ b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/expressions/Expression.java @@ -0,0 +1,7 @@ +package eu.eudat.query.engine.expressions; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public interface Expression { +} diff --git a/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/predicates/AndPredicate.java b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/predicates/AndPredicate.java new file mode 100644 index 000000000..b7015e47a --- /dev/null +++ b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/predicates/AndPredicate.java @@ -0,0 +1,11 @@ +package eu.eudat.query.engine.predicates; + +import eu.eudat.query.engine.expressions.ComparisonExpression; +import eu.eudat.query.engine.expressions.Expression; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public interface AndPredicate { + Expression and(ComparisonPredicate... predicates); +} diff --git a/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/predicates/ComparisonPredicate.java b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/predicates/ComparisonPredicate.java new file mode 100644 index 000000000..49c5da05a --- /dev/null +++ b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/predicates/ComparisonPredicate.java @@ -0,0 +1,9 @@ +package eu.eudat.query.engine.predicates; + +import eu.eudat.query.engine.expressions.ComparisonExpression; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public interface ComparisonPredicate extends Predicate { +} diff --git a/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/predicates/Predicate.java b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/predicates/Predicate.java new file mode 100644 index 000000000..50598f472 --- /dev/null +++ b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/predicates/Predicate.java @@ -0,0 +1,11 @@ +package eu.eudat.query.engine.predicates; + +import eu.eudat.query.engine.expressions.Expression; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public interface Predicate { + Expression where(T entity, E expression); + +} diff --git a/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/types/expression/comparison/ComparisonExpressionType.java b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/types/expression/comparison/ComparisonExpressionType.java new file mode 100644 index 000000000..f2b9ec5ed --- /dev/null +++ b/dmp-backend/queryengine/src/main/java/eu/eudat/query/engine/types/expression/comparison/ComparisonExpressionType.java @@ -0,0 +1,8 @@ +package eu.eudat.query.engine.types.expression.comparison; + +/** + * Created by ikalyvas on 7/5/2018. + */ +public enum ComparisonExpressionType { + EQUAL, GREATER_THAN, GREATER_OR_EQUAL_THAN, LESS_THAN, LESS_OR_EQUAL_THAN +} diff --git a/dmp-backend/web/pom.xml b/dmp-backend/web/pom.xml index d196e05b2..f54b3995c 100644 --- a/dmp-backend/web/pom.xml +++ b/dmp-backend/web/pom.xml @@ -31,6 +31,15 @@ queryable 1.0-SNAPSHOT + + + eu.eudat + elastic + 1.0.0-SNAPSHOT + + + + org.springframework.boot spring-boot-starter-web diff --git a/dmp-backend/web/src/main/java/eu/eudat/cache/ResponsesCache.java b/dmp-backend/web/src/main/java/eu/eudat/cache/ResponsesCache.java index 09a73cb87..23ef674a3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/cache/ResponsesCache.java +++ b/dmp-backend/web/src/main/java/eu/eudat/cache/ResponsesCache.java @@ -32,6 +32,7 @@ public class ResponsesCache { caches.add(new GuavaCache("organisations", CacheBuilder.newBuilder().expireAfterAccess(HOW_MANY, TIME_UNIT).build())); caches.add(new GuavaCache("registries", CacheBuilder.newBuilder().expireAfterAccess(HOW_MANY, TIME_UNIT).build())); caches.add(new GuavaCache("services", CacheBuilder.newBuilder().expireAfterAccess(HOW_MANY, TIME_UNIT).build())); + caches.add(new GuavaCache("tags", CacheBuilder.newBuilder().expireAfterAccess(HOW_MANY, TIME_UNIT).build())); caches.add(new GuavaCache("researchers", CacheBuilder.newBuilder().expireAfterAccess(HOW_MANY, TIME_UNIT).build())); simpleCacheManager.setCaches(caches); System.out.println("OK"); diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/ElasticSearchConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/ElasticSearchConfiguration.java new file mode 100644 index 000000000..e9e8f9b1c --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/configurations/ElasticSearchConfiguration.java @@ -0,0 +1,39 @@ +package eu.eudat.configurations; + +import org.apache.http.HttpHost; +import org.elasticsearch.client.Client; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.client.transport.TransportClient; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.transport.TransportAddress; +import org.elasticsearch.transport.client.PreBuiltTransportClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; + +import java.net.InetAddress; + +/** + * Created by ikalyvas on 7/5/2018. + */ +@Configuration +public class ElasticSearchConfiguration { + + private Environment environment; + + @Autowired + public ElasticSearchConfiguration(Environment environment) { + this.environment = environment; + } + + @Bean + public RestHighLevelClient client() throws Exception { + RestHighLevelClient client = new RestHighLevelClient( + RestClient.builder( + new HttpHost(this.environment.getProperty("elasticsearch.host"), + Integer.parseInt(this.environment.getProperty("elasticsearch.port")), "http"))); + return client; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicproject/DynamicProjectConfigurationProdImpl.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicproject/DynamicProjectConfigurationProdImpl.java index a70fd4ed6..3060e8cef 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicproject/DynamicProjectConfigurationProdImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicproject/DynamicProjectConfigurationProdImpl.java @@ -14,6 +14,7 @@ import javax.xml.bind.Unmarshaller; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.nio.file.Paths; import java.util.LinkedList; import java.util.List; @@ -47,7 +48,7 @@ public class DynamicProjectConfigurationProdImpl implements DynamicProjectConfig JAXBContext jaxbContext = JAXBContext.newInstance(Configuration.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - is = new URL("file:///" + System.getenv("CATALINA_HOME") + fileUrl).openStream(); + is = new URL(Paths.get(fileUrl).toUri().toURL().toString()).openStream(); this.configuration = (Configuration) jaxbUnmarshaller.unmarshal(is); } catch (Exception ex) { ex.printStackTrace(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetWizardController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetWizardController.java index 2e04b02c5..3d111f234 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetWizardController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetWizardController.java @@ -74,7 +74,8 @@ public class DatasetWizardController extends BaseController { public @ResponseBody ResponseEntity> getSingle(@PathVariable String id, Principal principal) { try { - DatasetWizardModel dataset = new DatasetManager().getSingle(this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao(), id); + DatasetWizardModel dataset = new DatasetManager().getSingle(this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao(),this.getApiContext().getOperationsContext().getDatasetRepository() + ,id); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataset)); } catch (Exception ex) { ex.printStackTrace(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/TagController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/TagController.java new file mode 100644 index 000000000..8bdc1b995 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/TagController.java @@ -0,0 +1,67 @@ +package eu.eudat.controllers; + +import eu.eudat.elastic.criteria.TagCriteria; +import eu.eudat.elastic.entities.Dataset; +import eu.eudat.elastic.entities.Tag; +import eu.eudat.elastic.repository.Repository; +import eu.eudat.logic.proxy.config.exceptions.HugeResultSet; +import eu.eudat.logic.proxy.config.exceptions.NoURLFound; +import eu.eudat.logic.services.ApiContext; +import eu.eudat.models.data.external.TagExternalSourcesModel; +import eu.eudat.models.data.helpers.responses.ResponseItem; +import eu.eudat.types.ApiMessageCode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +/** + * Created by ikalyvas on 7/5/2018. + */ +@RestController +@CrossOrigin +@RequestMapping(value = {"/api"}) +public class TagController extends BaseController{ + + private Repository datasetRepository; + + @Autowired + public TagController(ApiContext apiContext, Repository tagRepository) { + super(apiContext); + this.datasetRepository = tagRepository; + } + + @Transactional + @RequestMapping(method = RequestMethod.POST, value = {"/tag/create"}, consumes = "application/json", produces = "application/json") + public @ResponseBody + ResponseEntity> create(@RequestBody Dataset dataset) { + try { + Dataset tagEntity = this.datasetRepository.createOrUpdate(dataset); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(dataset).status(ApiMessageCode.SUCCESS_MESSAGE)); + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message(e.getMessage())); + } + } + + @RequestMapping(method = RequestMethod.GET, value = {"/external/tags"}, produces = "application/json") + public @ResponseBody + ResponseEntity> listExternalTagModel( + @RequestParam(value = "query", required = false) String query,@RequestParam(value = "type", required = false) String type) { + try { + List> remoteRepos = this.getApiContext().getOperationsContext().getRemoteFetcher().getTags(query,type); + TagExternalSourcesModel researchersExternalSourcesModel = new TagExternalSourcesModel().fromExternalItem(remoteRepos); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(researchersExternalSourcesModel).status(ApiMessageCode.NO_MESSAGE)); + } catch (NoURLFound ex) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("External Url Not Found")); + } catch (HugeResultSet ex) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("Huge Result Set")); + } catch (Exception ex) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(ex.getMessage())); + } + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/CommonsManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/CommonsManager.java index 19284f53e..94df54e41 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/CommonsManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/CommonsManager.java @@ -20,6 +20,8 @@ public class CommonsManager { .map(item-> new ExternalSourcesConfiguration.ExternalSourcesUrlModel(item.getKey(),item.getLabel())).collect(Collectors.toList())); externalSourcesConfiguration.setServices(configLoader.getExternalUrls().getServices().getUrls().stream() .map(item-> new ExternalSourcesConfiguration.ExternalSourcesUrlModel(item.getKey(),item.getLabel())).collect(Collectors.toList())); + externalSourcesConfiguration.setTags(configLoader.getExternalUrls().getTags().getUrls().stream() + .map(item-> new ExternalSourcesConfiguration.ExternalSourcesUrlModel(item.getKey(),item.getLabel())).collect(Collectors.toList())); return externalSourcesConfiguration; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java index 0e43a22ca..531363dc5 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java @@ -1,25 +1,27 @@ package eu.eudat.logic.managers; -import eu.eudat.logic.builders.entity.UserInfoBuilder; +import eu.eudat.data.dao.criteria.DataRepositoryCriteria; +import eu.eudat.data.dao.criteria.ExternalDatasetCriteria; +import eu.eudat.data.dao.criteria.RegistryCriteria; +import eu.eudat.data.dao.criteria.ServiceCriteria; import eu.eudat.data.dao.entities.*; import eu.eudat.data.entities.*; +import eu.eudat.data.query.items.table.dataset.DatasetTableRequest; +import eu.eudat.elastic.criteria.DatasetCriteria; +import eu.eudat.elastic.repository.DatasetRepository; +import eu.eudat.logic.builders.entity.UserInfoBuilder; +import eu.eudat.logic.services.ApiContext; +import eu.eudat.logic.services.forms.VisibilityRuleService; import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; import eu.eudat.logic.utilities.documents.word.WordBuilder; import eu.eudat.logic.utilities.documents.xml.ExportXmlBuilder; import eu.eudat.models.HintedModelFactory; -import eu.eudat.data.dao.criteria.DataRepositoryCriteria; -import eu.eudat.data.dao.criteria.ExternalDatasetCriteria; -import eu.eudat.data.dao.criteria.RegistryCriteria; -import eu.eudat.data.dao.criteria.ServiceCriteria; -import eu.eudat.data.query.items.table.dataset.DatasetTableRequest; import eu.eudat.models.data.datasetwizard.DatasetWizardModel; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.listingmodels.DatasetListingModel; import eu.eudat.models.data.security.Principal; import eu.eudat.models.data.user.composite.PagedDatasetProfile; import eu.eudat.queryable.QueryableList; -import eu.eudat.logic.services.ApiContext; -import eu.eudat.logic.services.forms.VisibilityRuleService; import org.apache.commons.io.IOUtils; import org.json.JSONObject; import org.springframework.core.env.Environment; @@ -35,6 +37,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -42,8 +45,19 @@ import java.util.zip.ZipInputStream; public class DatasetManager { public DataTableData getPaged(ApiContext apiContext, DatasetTableRequest datasetTableRequest, Principal principal) throws Exception { + DatasetCriteria datasetCriteria = new DatasetCriteria(); + datasetCriteria.setTags(datasetTableRequest.getCriteria().getTags()); + List datasets = apiContext.getOperationsContext().getDatasetRepository().exists() ? + apiContext.getOperationsContext().getDatasetRepository().query(datasetCriteria) : new LinkedList<>(); + UserInfo userInfo = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().getWithCriteria(datasetTableRequest.getCriteria()).withHint(HintedModelFactory.getHint(DatasetListingModel.class)); + if (datasetTableRequest.getCriteria().getTags() != null && !datasetTableRequest.getCriteria().getTags().isEmpty()) { + if (!datasets.isEmpty()) + items.where((builder, root) -> root.get("id").in(datasets.stream().map(x -> UUID.fromString(x.getId())).collect(Collectors.toList()))); + else + items.where((builder, root) -> root.get("id").in(new UUID[]{UUID.randomUUID()})); + } QueryableList authItems = apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().getAuthenticated(items, userInfo); QueryableList pagedItems = PaginationManager.applyPaging(authItems, datasetTableRequest); DataTableData dataTable = new DataTableData(); @@ -62,11 +76,14 @@ public class DatasetManager { return dataTable; } - public DatasetWizardModel getSingle(DatasetDao datatasetRepository, String id) throws InstantiationException, IllegalAccessException { + public DatasetWizardModel getSingle(DatasetDao datatasetRepository, DatasetRepository elasticDatasetRepository, String id) throws InstantiationException, IllegalAccessException, IOException { DatasetWizardModel dataset = new DatasetWizardModel(); eu.eudat.data.entities.Dataset datasetEntity = datatasetRepository.find(UUID.fromString(id), HintedModelFactory.getHint(DatasetWizardModel.class)); + eu.eudat.elastic.entities.Dataset datasetElastic = elasticDatasetRepository.exists() ? + elasticDatasetRepository.findDocument(id) : new eu.eudat.elastic.entities.Dataset(); dataset.setDatasetProfileDefinition(getPagedProfile(dataset, datasetEntity)); dataset.fromDataModel(datasetEntity); + dataset.setTags(datasetElastic.getTags()); return dataset; } @@ -75,7 +92,7 @@ public class DatasetManager { datasetprofile.setStatus(dataset.getStatus()); if (datasetEntity.getProperties() != null) { JSONObject jobject = new JSONObject(datasetEntity.getProperties()); - Map properties = (Map) jobject.toMap(); + Map properties = jobject.toMap(); datasetprofile.fromJsonObject(properties); } PagedDatasetProfile pagedDatasetProfile = new PagedDatasetProfile(); @@ -180,15 +197,16 @@ public class DatasetManager { return newFile; } - public static eu.eudat.data.entities.Dataset createOrUpdate(ApiContext apiContext, DatasetWizardModel profile, Principal principal) throws Exception { - eu.eudat.data.entities.Dataset dataset = profile.toDataModel(); - propertiesModelToString(profile, dataset); + public static eu.eudat.data.entities.Dataset createOrUpdate(ApiContext apiContext, DatasetWizardModel datasetWizardModel, Principal principal) throws Exception { + eu.eudat.data.entities.Dataset dataset = datasetWizardModel.toDataModel(); + propertiesModelToString(datasetWizardModel, dataset); UserInfo userInfo = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); dataset.setCreator(userInfo); + updateTags(apiContext.getOperationsContext().getDatasetRepository(), datasetWizardModel); createRegistriesIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getRegistryDao(), dataset); createDataRepositoriesIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getDataRepositoryDao(), dataset); - createServicesIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getDatasetServiceDao(),apiContext.getOperationsContext().getDatabaseRepository().getServiceDao(), dataset); - createExternalDatasetsIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getDatasetExternalDatasetDao(),apiContext.getOperationsContext().getDatabaseRepository().getExternalDatasetDao(), dataset); + createServicesIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getDatasetServiceDao(), apiContext.getOperationsContext().getDatabaseRepository().getServiceDao(), dataset); + createExternalDatasetsIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getDatasetExternalDatasetDao(), apiContext.getOperationsContext().getDatabaseRepository().getExternalDatasetDao(), dataset); return apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().createOrUpdate(dataset); } @@ -200,6 +218,15 @@ public class DatasetManager { dataset.setProperties(jobject.toString()); } + private static void updateTags(DatasetRepository datasetRepository, DatasetWizardModel datasetWizardModel) throws IOException { + if (datasetWizardModel.getTags() != null && !datasetWizardModel.getTags().isEmpty()) { + eu.eudat.elastic.entities.Dataset dataset = new eu.eudat.elastic.entities.Dataset(); + dataset.setId(datasetWizardModel.getId().toString()); + dataset.setTags(datasetWizardModel.getTags()); + datasetRepository.createOrUpdate(dataset); + } + } + private static void createRegistriesIfTheyDontExist(RegistryDao registryDao, eu.eudat.data.entities.Dataset dataset) { if (dataset.getRegistries() != null && !dataset.getRegistries().isEmpty()) { @@ -226,8 +253,7 @@ public class DatasetManager { datasetDataRepository.getDataRepository().setId(entries.get(0).getId()); datasetDataRepository.setDataset(dataset); dataset.getDatasetDataRepositories().add(datasetDataRepository); - } - else { + } else { DataRepository dataRepository = dataRepositoryDao.createOrUpdate(datasetDataRepository.getDataRepository()); datasetDataRepository.setDataRepository(dataRepository); dataset.getDatasetDataRepositories().add(datasetDataRepository); @@ -236,7 +262,7 @@ public class DatasetManager { } } - private static void createServicesIfTheyDontExist(DatasetServiceDao datasetServiceDao,ServiceDao serviceDao, eu.eudat.data.entities.Dataset dataset) { + private static void createServicesIfTheyDontExist(DatasetServiceDao datasetServiceDao, ServiceDao serviceDao, eu.eudat.data.entities.Dataset dataset) { Set services = dataset.getServices(); dataset.setServices(new HashSet<>()); if (services != null && !services.isEmpty()) { @@ -244,21 +270,20 @@ public class DatasetManager { ServiceCriteria criteria = new ServiceCriteria(); criteria.setLike(datasetService.getService().getLabel()); List entries = serviceDao.getWithCriteria(criteria).toList(); - if (entries != null && !entries.isEmpty()){ + if (entries != null && !entries.isEmpty()) { datasetService.getService().setId(entries.get(0).getId()); datasetService.setDataset(dataset); dataset.getServices().add(datasetService); - } - else { + } else { Service service = serviceDao.createOrUpdate(datasetService.getService()); - datasetService.setService(service ); + datasetService.setService(service); dataset.getServices().add(datasetService); } } } } - private static void createExternalDatasetsIfTheyDontExist(DatasetExternalDatasetDao datasetExternalDatasetDao,ExternalDatasetDao externalDatasetDao, eu.eudat.data.entities.Dataset dataset) { + private static void createExternalDatasetsIfTheyDontExist(DatasetExternalDatasetDao datasetExternalDatasetDao, ExternalDatasetDao externalDatasetDao, eu.eudat.data.entities.Dataset dataset) { Set externalDatasets = dataset.getDatasetExternalDatasets(); dataset.setDatasetExternalDatasets(new HashSet<>()); if (externalDatasets != null && !externalDatasets.isEmpty()) { @@ -270,8 +295,7 @@ public class DatasetManager { datasetExternalDataset.getExternalDataset().setId(entries.get(0).getId()); datasetExternalDataset.setDataset(dataset); dataset.getDatasetExternalDatasets().add(datasetExternalDataset); - } - else { + } else { ExternalDataset externalDataset = externalDatasetDao.createOrUpdate(datasetExternalDataset.getExternalDataset()); datasetExternalDataset.setExternalDataset(externalDataset); dataset.getDatasetExternalDatasets().add(datasetExternalDataset); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/ExternalUrls.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/ExternalUrls.java index cc5c34260..5571e9e7b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/ExternalUrls.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/ExternalUrls.java @@ -23,6 +23,7 @@ public class ExternalUrls implements Serializable { ResearcherUrls researchers; OrganisationUrls organisations; DatasetUrls datasets; + TagUrls tags; public RegistryUrls getRegistries() { @@ -59,6 +60,15 @@ public class ExternalUrls implements Serializable { return researchers; } + public TagUrls getTags() { + return tags; + } + + @XmlElement(name = "tags") + public void setTags(TagUrls tags) { + this.tags = tags; + } + @XmlElement(name = "researchers") public void setResearchers(ResearcherUrls researchers) { this.researchers = researchers; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ProductionConfigLoader.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ProductionConfigLoader.java index 82828a0ed..37c1ab854 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ProductionConfigLoader.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ProductionConfigLoader.java @@ -11,6 +11,7 @@ import javax.xml.bind.Unmarshaller; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.nio.file.Paths; /** * Created by ikalyvas on 2/9/2018. @@ -34,7 +35,7 @@ public class ProductionConfigLoader implements ConfigLoader { JAXBContext jaxbContext = JAXBContext.newInstance(ExternalUrls.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - is = new URL("file:///" + System.getenv("CATALINA_HOME") + fileUrl).openStream(); + is = new URL(Paths.get(fileUrl).toUri().toURL().toString()).openStream(); externalUrls = (ExternalUrls) jaxbUnmarshaller.unmarshal(is); } catch (Exception ex) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/TagUrls.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/TagUrls.java new file mode 100644 index 000000000..e3040b1a5 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/TagUrls.java @@ -0,0 +1,35 @@ +package eu.eudat.logic.proxy.config.entities; + +import eu.eudat.logic.proxy.config.FetchStrategy; +import eu.eudat.logic.proxy.config.UrlConfiguration; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import java.util.List; + +/** + * Created by ikalyvas on 7/9/2018. + */ +public class TagUrls { + List urls; + FetchStrategy fetchMode; + + public List getUrls() { + return urls; + } + + @XmlElementWrapper + @XmlElement(name = "urlConfig") + public void setUrls(List urls) { + this.urls = urls; + } + + public FetchStrategy getFetchMode() { + return fetchMode; + } + + @XmlElement(name = "fetchMode") + public void setFetchMode(FetchStrategy fetchMode) { + this.fetchMode = fetchMode; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java index 4e8f4c74a..08141fe5b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java @@ -85,6 +85,15 @@ public class RemoteFetcher { return getAll(urlConfigs, fetchStrategy, query); } + @Cacheable("tags") + public List> getTags(String query, String key) throws NoURLFound, HugeResultSet { + List urlConfigs = + key != null && !key.isEmpty() ? configLoader.getExternalUrls().getTags().getUrls().stream().filter(item -> item.getKey().equals(key)).collect(Collectors.toList()) + : configLoader.getExternalUrls().getTags().getUrls(); + FetchStrategy fetchStrategy = configLoader.getExternalUrls().getTags().getFetchMode(); + return getAll(urlConfigs, fetchStrategy, query); + } + @Cacheable("datasets") public List> getDatasets(String query, String key) throws NoURLFound, HugeResultSet { List urlConfigs = diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/ApiContextImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/ApiContextImpl.java index 4e6b12331..42920db8a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/ApiContextImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/ApiContextImpl.java @@ -3,6 +3,7 @@ package eu.eudat.logic.services; import eu.eudat.logic.services.helpers.HelpersService; import eu.eudat.logic.services.operations.OperationsContext; import eu.eudat.logic.services.utilities.UtilitiesService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -13,6 +14,7 @@ public class ApiContextImpl implements ApiContext { private HelpersService helpersService; private UtilitiesService utilitiesService; + @Autowired public ApiContextImpl(OperationsContext operationsContext, HelpersService helpersService, UtilitiesService utilitiesService) { this.operationsContext = operationsContext; this.helpersService = helpersService; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/OperationsContext.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/OperationsContext.java index 678b306ad..ccd6d914d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/OperationsContext.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/OperationsContext.java @@ -1,5 +1,6 @@ package eu.eudat.logic.services.operations; +import eu.eudat.elastic.repository.DatasetRepository; import eu.eudat.logic.builders.BuilderFactory; import eu.eudat.logic.proxy.fetching.RemoteFetcher; import eu.eudat.logic.services.helpers.FileStorageService; @@ -20,4 +21,5 @@ public interface OperationsContext { FileStorageService getFileStorageService(); + DatasetRepository getDatasetRepository(); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/OperationsContextImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/OperationsContextImpl.java index ecc24007e..bd1ffd04c 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/OperationsContextImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/OperationsContextImpl.java @@ -1,5 +1,6 @@ package eu.eudat.logic.services.operations; +import eu.eudat.elastic.repository.DatasetRepository; import eu.eudat.logic.builders.BuilderFactory; import eu.eudat.logic.proxy.fetching.RemoteFetcher; import eu.eudat.logic.services.helpers.FileStorageService; @@ -18,15 +19,17 @@ public class OperationsContextImpl implements OperationsContext { private RemoteFetcher remoteFetcher; private BuilderFactory builderFactory; private FileStorageService fileStorageService; + private DatasetRepository datasetRepository; @Autowired public OperationsContextImpl(DatabaseRepository databaseRepository, ApplicationContext applicationContext, RemoteFetcher remoteFetcher - , BuilderFactory builderFactory, FileStorageService fileStorageService) { + , BuilderFactory builderFactory, FileStorageService fileStorageService,DatasetRepository datasetRepository) { this.databaseRepository = databaseRepository; this.applicationContext = applicationContext; this.remoteFetcher = remoteFetcher; this.builderFactory = builderFactory; this.fileStorageService = fileStorageService; + this.datasetRepository = datasetRepository; } @Override @@ -53,4 +56,13 @@ public class OperationsContextImpl implements OperationsContext { public FileStorageService getFileStorageService() { return fileStorageService; } + + @Override + public DatasetRepository getDatasetRepository() { + return datasetRepository; + } + + public void setDatasetRepository(DatasetRepository datasetRepository) { + this.datasetRepository = datasetRepository; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetwizard/DatasetWizardModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetwizard/DatasetWizardModel.java index 7ccce0b4b..24c11a629 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetwizard/DatasetWizardModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetwizard/DatasetWizardModel.java @@ -1,6 +1,7 @@ package eu.eudat.models.data.datasetwizard; import eu.eudat.data.entities.*; +import eu.eudat.elastic.entities.Tag; import eu.eudat.models.DataModel; import eu.eudat.models.data.dataset.DataRepository; import eu.eudat.models.data.dataset.Registry; @@ -29,6 +30,7 @@ public class DatasetWizardModel implements DataModel registries; private List services; private List dataRepositories; + private List tags; private List externalDatasets; private DatasetProfileListingModel profile; @@ -144,6 +146,14 @@ public class DatasetWizardModel implements DataModel getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + @Override public DatasetWizardModel fromDataModel(Dataset entity) { this.id = entity.getId(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/external/TagExternalSourcesModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/external/TagExternalSourcesModel.java new file mode 100644 index 000000000..9a52a965a --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/external/TagExternalSourcesModel.java @@ -0,0 +1,22 @@ +package eu.eudat.models.data.external; + +import java.util.List; +import java.util.Map; + +/** + * Created by ikalyvas on 7/9/2018. + */ +public class TagExternalSourcesModel extends ExternalListingItem { + + @Override + public TagExternalSourcesModel fromExternalItem(List> values) { + for (Map item : values) { + ExternalSourcesItemModel model = new ExternalSourcesItemModel(); + model.setId(item.get("pid")); + model.setUri(item.get("label")); + model.setName(item.get("name")); + this.add(model); + } + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/externalurl/ExternalSourcesConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/externalurl/ExternalSourcesConfiguration.java index b69a64d99..c9e8df87d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/externalurl/ExternalSourcesConfiguration.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/externalurl/ExternalSourcesConfiguration.java @@ -37,6 +37,15 @@ public class ExternalSourcesConfiguration { private List dataRepositories; private List services; private List externalDatasets; + private List tags; + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } public List getRegistries() { return registries; diff --git a/dmp-backend/web/src/main/resources/ExternalUrls.xml b/dmp-backend/web/src/main/resources/ExternalUrls.xml index c48d22ad2..40b80345a 100644 --- a/dmp-backend/web/src/main/resources/ExternalUrls.xml +++ b/dmp-backend/web/src/main/resources/ExternalUrls.xml @@ -44,6 +44,45 @@ FIRST + + + + cristin + + 1 + https://eestore.paas2.uninett.no/api/tags/ + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + + + $['meta']['pagination']['page','pages','count'] + + + openAire + + 1 + https://eestore.paas2.uninett.no/api/tags/ + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + + + $['meta']['pagination']['page','pages','count'] + + + + + FIRST + diff --git a/dmp-backend/web/src/main/resources/application.properties b/dmp-backend/web/src/main/resources/application.properties index 62e72673c..d2c3c7ad7 100644 --- a/dmp-backend/web/src/main/resources/application.properties +++ b/dmp-backend/web/src/main/resources/application.properties @@ -15,8 +15,8 @@ production.database.password=dmpt00lu$r ##########################/Persistence########################################## ###################Allowed Proxy Service Host ############################ eu.eudat.logic.proxy.allowed.host=https://eestore.paas2.uninett.no -configuration.externalUrls=/classes/ExternalUrls.xml -configuration.dynamicProjectUrl=/classes/ProjectConfiguration.xml +configuration.externalUrls=/tmp/ExternalUrls.xml +configuration.dynamicProjectUrl=/tmp/ProjectConfiguration.xml ####################################################### ########################/Email############################# @@ -59,7 +59,7 @@ b2access.externallogin.redirect_uri=http://dmp.eudat.org:4200/api/oauth/authoriz b2access.externallogin.clientid=eudatdmptool b2access.externallogin.clientSecret=A3b*1*92 ################################################################################# -pdf.converter.url=http://localhost/ +pdf.converter.url=http://localhost:81/ files.storage.temp = temp files.storage.final = final ################################################################################# @@ -69,4 +69,7 @@ project.configuration.grant.name = Grant ################################################################################# http-logger.initial-delay = 0 http-logger.delay = 10 -http-logger.server-address = http://logstash:31311 \ No newline at end of file +http-logger.server-address = http://logstash:31311 +#############################Elastic Search###################################### +elasticsearch.host = localhost +elasticsearch.port = 9201 diff --git a/dmp-frontend/.angular-cli.json b/dmp-frontend/.angular-cli.json deleted file mode 100644 index 5ca150f42..000000000 --- a/dmp-frontend/.angular-cli.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "$schema": "./node_modules/@angular/cli/lib/config/schema.json", - "project": { - "name": "dmp-frontend" - }, - "apps": [ - { - "root": "src", - "outDir": "dist", - "assets": [ - "assets", - "favicon.ico" - ], - "index": "index.html", - "main": "main.ts", - "polyfills": "polyfills.ts", - "test": "test.ts", - "tsconfig": "tsconfig.app.json", - "testTsconfig": "tsconfig.spec.json", - "prefix": "app", - "styles": [ - "styles.scss" - ], - "scripts": [], - "environmentSource": "environments/environment.ts", - "environments": { - "dev": "environments/environment.ts", - "prod": "environments/environment.prod.ts" - } - } - ], - "e2e": { - "protractor": { - "config": "./protractor.conf.js" - } - }, - "lint": [ - { - "project": "src/tsconfig.app.json", - "exclude": "**/node_modules/**" - }, - { - "project": "src/tsconfig.spec.json", - "exclude": "**/node_modules/**" - }, - { - "project": "e2e/tsconfig.e2e.json", - "exclude": "**/node_modules/**" - } - ], - "test": { - "karma": { - "config": "./karma.conf.js" - } - }, - "defaults": { - "styleExt": "css", - "component": {} - } -} diff --git a/dmp-frontend/Dockerfile b/dmp-frontend/Dockerfile index fd0126fdb..ef2af307d 100644 --- a/dmp-frontend/Dockerfile +++ b/dmp-frontend/Dockerfile @@ -5,9 +5,11 @@ RUN npm cache clear --force && npm install COPY ./ /app/ ARG env=dev ARG aot=--no-aot -RUN ng build --$env --$aot +RUN echo $env +RUN echo $aot +RUN if [ "$env" = "prod" ]; then ng build --$env --$aot; else ng build --$aot; fi # Stage 1, based on Nginx, to have only the compiled app, ready for production with Nginx FROM nginx:1.13 COPY --from=angular /app/dist/ /usr/share/nginx/html -COPY ./nginx-custom.conf /etc/nginx/conf.d/default.conf \ No newline at end of file +COPY ./nginx-custom.conf /etc/nginx/conf.d/default.conf diff --git a/dmp-frontend/angular.json b/dmp-frontend/angular.json new file mode 100644 index 000000000..3727a1e15 --- /dev/null +++ b/dmp-frontend/angular.json @@ -0,0 +1,132 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "dmp-frontend": { + "root": "", + "sourceRoot": "src", + "projectType": "application", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist", + "index": "src/index.html", + "main": "src/main.ts", + "tsConfig": "src/tsconfig.app.json", + "polyfills": "src/polyfills.ts", + "assets": [ + "src/assets", + "src/favicon.ico" + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [] + }, + "configurations": { + "production": { + "optimization": true, + "outputHashing": "all", + "sourceMap": false, + "extractCss": true, + "namedChunks": false, + "aot": true, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true, + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ] + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "dmp-frontend:build" + }, + "configurations": { + "production": { + "browserTarget": "dmp-frontend:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "dmp-frontend:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "karmaConfig": "./karma.conf.js", + "polyfills": "src/polyfills.ts", + "tsConfig": "src/tsconfig.spec.json", + "scripts": [], + "styles": [ + "src/styles.scss" + ], + "assets": [ + "src/assets", + "src/favicon.ico" + ] + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "src/tsconfig.app.json", + "src/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } + }, + "dmp-frontend-e2e": { + "root": "", + "sourceRoot": "e2e", + "projectType": "application", + "architect": { + "e2e": { + "builder": "@angular-devkit/build-angular:protractor", + "options": { + "protractorConfig": "./protractor.conf.js", + "devServerTarget": "dmp-frontend:serve" + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "e2e/tsconfig.e2e.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } + } + }, + "defaultProject": "dmp-frontend", + "schematics": { + "@schematics/angular:component": { + "prefix": "app", + "styleext": "css" + }, + "@schematics/angular:directive": { + "prefix": "app" + } + } +} \ No newline at end of file diff --git a/dmp-frontend/package-lock.json b/dmp-frontend/package-lock.json index c856085ab..59afa7947 100644 --- a/dmp-frontend/package-lock.json +++ b/dmp-frontend/package-lock.json @@ -4,202 +4,540 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@angular-devkit/architect": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.6.8.tgz", + "integrity": "sha512-ZKTm/zC61iY9IBHOEAKoMSzZpvhkmv+1O/HHzpHEuR551jCzu6vSyCmMY9Z7GBcccscCV+hjeSMwgFrFRcqlkw==", + "dev": true, + "requires": { + "@angular-devkit/core": "0.6.8", + "rxjs": "^6.0.0" + } + }, + "@angular-devkit/build-angular": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.6.8.tgz", + "integrity": "sha512-VGqYAk8jpISraz2UHfsDre270NOUmV0CTSZw2p9sm5g/XIr5m+IHetFZz3gpoAr9+If2aFTs8Rt3sGdCRzwBqA==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.6.8", + "@angular-devkit/build-optimizer": "0.6.8", + "@angular-devkit/core": "0.6.8", + "@ngtools/webpack": "6.0.8", + "ajv": "~6.4.0", + "autoprefixer": "^8.4.1", + "cache-loader": "^1.2.2", + "chalk": "~2.2.2", + "circular-dependency-plugin": "^5.0.2", + "clean-css": "^4.1.11", + "copy-webpack-plugin": "^4.5.1", + "file-loader": "^1.1.11", + "glob": "^7.0.3", + "html-webpack-plugin": "^3.0.6", + "istanbul": "^0.4.5", + "istanbul-instrumenter-loader": "^3.0.1", + "karma-source-map-support": "^1.2.0", + "less": "^3.0.4", + "less-loader": "^4.1.0", + "license-webpack-plugin": "^1.3.1", + "lodash": "^4.17.4", + "memory-fs": "^0.4.1", + "mini-css-extract-plugin": "~0.4.0", + "minimatch": "^3.0.4", + "node-sass": "^4.9.0", + "opn": "^5.1.0", + "parse5": "^4.0.0", + "portfinder": "^1.0.13", + "postcss": "^6.0.22", + "postcss-import": "^11.1.0", + "postcss-loader": "^2.1.5", + "postcss-url": "^7.3.2", + "raw-loader": "^0.5.1", + "resolve": "^1.5.0", + "rxjs": "^6.0.0", + "sass-loader": "^7.0.1", + "silent-error": "^1.1.0", + "source-map-support": "^0.5.0", + "stats-webpack-plugin": "^0.6.2", + "style-loader": "^0.21.0", + "stylus": "^0.54.5", + "stylus-loader": "^3.0.2", + "tree-kill": "^1.2.0", + "uglifyjs-webpack-plugin": "^1.2.5", + "url-loader": "^1.0.1", + "webpack": "~4.8.1", + "webpack-dev-middleware": "^3.1.3", + "webpack-dev-server": "^3.1.4", + "webpack-merge": "^4.1.2", + "webpack-sources": "^1.1.0", + "webpack-subresource-integrity": "^1.1.0-rc.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", + "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + } + } + }, "@angular-devkit/build-optimizer": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.3.2.tgz", - "integrity": "sha512-U0BCZtThq5rUfY08shHXpxe8ZhSsiYB/cJjUvAWRTs/ORrs8pbngS6xwseQws8d/vHoVrtqGD9GU9h8AmFRERQ==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.6.8.tgz", + "integrity": "sha512-of5syQbv3uNPp4AQkfRecfnp8AE8kvffbfYi+FFPZ6OGr7e59T1fGwk6+Zgb2qQFQg8HO2tzWI/uygtLIqmbmw==", "dev": true, "requires": { "loader-utils": "^1.1.0", "source-map": "^0.5.6", - "typescript": "~2.6.2", - "webpack-sources": "^1.0.1" + "typescript": "~2.9.1", + "webpack-sources": "^1.1.0" }, "dependencies": { "typescript": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", - "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", + "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", "dev": true } } }, "@angular-devkit/core": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.3.2.tgz", - "integrity": "sha512-zABk/iP7YX5SVbmK4e+IX7j2d0D37MQJQiKgWdV3JzfvVJhNJzddiirtT980pIafoq+KyvTgVwXtc+vnux0oeQ==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.6.8.tgz", + "integrity": "sha512-rkIa1OSVWTt4g9leLSK/PsqOj3HZbDKHbZjqlslyfVa3AyCeiumFoOgViOVXlYgPX3HHDbE5uH24nyUWSD8uww==", "dev": true, "requires": { - "ajv": "~5.5.1", - "chokidar": "^1.7.0", - "rxjs": "^5.5.6", + "ajv": "~6.4.0", + "chokidar": "^2.0.3", + "rxjs": "^6.0.0", "source-map": "^0.5.6" }, "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.2.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "lodash.debounce": "^4.0.8", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.0.5" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", "dev": true, "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, - "rxjs": { - "version": "5.5.11", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.11.tgz", - "integrity": "sha512-3bjO7UwWfA2CV7lmwYMBzj4fQ6Cq+ftHc2MvUe+WMS7wcdJ1LosDWmdjPQanYp2dBRj572p7PeU81JUxHKOcBA==", + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "symbol-observable": "1.0.1" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } } } }, "@angular-devkit/schematics": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.3.2.tgz", - "integrity": "sha512-B6zZoqvHaTJy+vVdA6EtlxnCdGMa5elCa4j9lQLC3JI8DLvMXUWkCIPVbPzJ/GSRR9nsKWpvYMYaJyfBDUqfhw==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.6.8.tgz", + "integrity": "sha512-R4YqAUdo62wtrhX/5HSRGSKXNTWqfQb66ZE6m8jj6GEJNFKdNXMdxOchxr07LCiKTxfh1w6G3nGzxIsu/+D4KA==", "dev": true, "requires": { - "@ngtools/json-schema": "^1.1.0", - "rxjs": "^5.5.6" - }, - "dependencies": { - "rxjs": { - "version": "5.5.11", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.11.tgz", - "integrity": "sha512-3bjO7UwWfA2CV7lmwYMBzj4fQ6Cq+ftHc2MvUe+WMS7wcdJ1LosDWmdjPQanYp2dBRj572p7PeU81JUxHKOcBA==", - "dev": true, - "requires": { - "symbol-observable": "1.0.1" - } - } + "@angular-devkit/core": "0.6.8", + "rxjs": "^6.0.0" } }, "@angular/animations": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-5.2.11.tgz", - "integrity": "sha512-J7wKHkFn3wV28/Y1Qm4yjGXVCwXzj1JR5DRjGDTFnxTRacUFx7Nj0ApGhN0b2+V0NOvgxQOvEW415Y22kGoblw==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-6.0.7.tgz", + "integrity": "sha512-yOig45sxzpEmlXy+eFgh2v2yxoE/Hh9rn7BX82uj71yobSpCYoe58AEOay1cu0FCcLi/P5qltHepDrRRxNxPMw==", "requires": { - "tslib": "^1.7.1" + "tslib": "^1.9.0" } }, "@angular/cdk": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-5.2.5.tgz", - "integrity": "sha512-GN8m1d+VcCE9+Bgwv06Y8YJKyZ0i9ZIq2ZPBcJYt+KVgnVVRg4JkyUNxud07LNsvzOX22DquHqmIZiC4hAG7Ag==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-6.1.0.tgz", + "integrity": "sha512-IrM+cjeUW0TmFIZb7nMtARa9dKOVU9vXlwzllcwcBYHJNb9YcnLPaWqB2LqDQFuH/JQyt+oAG+VyfMmU+yk9uw==", "requires": { "tslib": "^1.7.1" } }, "@angular/cli": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-1.7.4.tgz", - "integrity": "sha512-URdb1QtnQf+Ievy93wjq7gE81s25BkWUwJFPey+YkphBA3G1lbCAQPiEh2pntBwaIKavgEuCw+Sf2YZdgTVhDA==", - "dev": true, - "requires": { - "@angular-devkit/build-optimizer": "0.3.2", - "@angular-devkit/core": "0.3.2", - "@angular-devkit/schematics": "0.3.2", - "@ngtools/json-schema": "1.2.0", - "@ngtools/webpack": "1.10.2", - "@schematics/angular": "0.3.2", - "@schematics/package-update": "0.3.2", - "ajv": "^6.1.1", - "autoprefixer": "^7.2.3", - "cache-loader": "^1.2.0", - "chalk": "~2.2.0", - "circular-dependency-plugin": "^4.2.1", - "clean-css": "^4.1.11", - "common-tags": "^1.3.1", - "copy-webpack-plugin": "~4.4.1", - "core-object": "^3.1.0", - "denodeify": "^1.2.1", - "ember-cli-string-utils": "^1.0.0", - "extract-text-webpack-plugin": "^3.0.2", - "file-loader": "^1.1.5", - "fs-extra": "^4.0.0", - "glob": "^7.0.3", - "html-webpack-plugin": "^2.29.0", - "istanbul-instrumenter-loader": "^3.0.0", - "karma-source-map-support": "^1.2.0", - "less": "^2.7.2", - "less-loader": "^4.0.5", - "license-webpack-plugin": "^1.0.0", - "loader-utils": "1.1.0", - "lodash": "^4.11.1", - "memory-fs": "^0.4.1", - "minimatch": "^3.0.4", - "node-modules-path": "^1.0.0", - "node-sass": "^4.7.2", - "nopt": "^4.0.1", - "opn": "~5.1.0", - "portfinder": "~1.0.12", - "postcss": "^6.0.16", - "postcss-import": "^11.0.0", - "postcss-loader": "^2.0.10", - "postcss-url": "^7.1.2", - "raw-loader": "^0.5.1", + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-6.0.8.tgz", + "integrity": "sha512-DhH1Zq5Yonthw6zh6W07fhf+9XrAZbD1fcQ0MrmbxlieCfLlTAdBqyK2LavFCKwSZkUMLF6UHM3+jiNRVZSSIg==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.6.8", + "@angular-devkit/core": "0.6.8", + "@angular-devkit/schematics": "0.6.8", + "@schematics/angular": "0.6.8", + "@schematics/update": "0.6.8", + "opn": "~5.3.0", "resolve": "^1.1.7", - "rxjs": "^5.5.6", - "sass-loader": "^6.0.6", + "rxjs": "^6.0.0", "semver": "^5.1.0", "silent-error": "^1.0.0", - "source-map-support": "^0.4.1", - "style-loader": "^0.19.1", - "stylus": "^0.54.5", - "stylus-loader": "^3.0.1", - "uglifyjs-webpack-plugin": "^1.1.8", - "url-loader": "^0.6.2", - "webpack": "~3.11.0", - "webpack-dev-middleware": "~1.12.0", - "webpack-dev-server": "~2.11.0", - "webpack-merge": "^4.1.0", - "webpack-sources": "^1.0.0", - "webpack-subresource-integrity": "^1.0.1" - }, - "dependencies": { - "rxjs": { - "version": "5.5.11", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.11.tgz", - "integrity": "sha512-3bjO7UwWfA2CV7lmwYMBzj4fQ6Cq+ftHc2MvUe+WMS7wcdJ1LosDWmdjPQanYp2dBRj572p7PeU81JUxHKOcBA==", - "dev": true, - "requires": { - "symbol-observable": "1.0.1" - } - } + "symbol-observable": "^1.2.0", + "yargs-parser": "^10.0.0" } }, "@angular/common": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-5.2.11.tgz", - "integrity": "sha512-LniJjGAeftUJDJh+2+LEjltcGen08C/VMxQ/eUYmesytKy1sN+MWzh3GbpKfEWtWmyUsYTG9lAAJNo3L3jPwsw==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-6.0.7.tgz", + "integrity": "sha512-MUCCs3FLwqyp5wuvkUTHVGMTd3bNGDxD5IJNvaLgVliGe4r0IlETRXYqyRPs7gdVFPbiJ97P1DUONArj9xL9XA==", "requires": { - "tslib": "^1.7.1" + "tslib": "^1.9.0" } }, "@angular/compiler": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-5.2.11.tgz", - "integrity": "sha512-ICvB1ud1mxaXUYLb8vhJqiLhGBVocAZGxoHTglv6hMkbrRYcnlB3FZJFOzBvtj+krkd1jamoYLI43UAmesqQ6Q==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-6.0.7.tgz", + "integrity": "sha512-J9I2U4NiWIBXl0ZOJkBW5G7xXhphggSirTwFLD4yKCTeJXgyldZytJZRkDUx1uouZtI2/PycvaOZoRr85N67AA==", "requires": { - "tslib": "^1.7.1" + "tslib": "^1.9.0" } }, "@angular/compiler-cli": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-5.2.11.tgz", - "integrity": "sha512-dwrQ0yxoCM/XzKzlm7pTsyg4/6ECjT9emZufGj8t12bLMO8NDn1IJOsqXJA1+onEgQKhlr0Ziwi+96TvDTb1Cg==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-6.0.7.tgz", + "integrity": "sha512-nDIo4TtE3oXgZiQ5vJEcr5fi3FuXRDJQSOeOQinpCrtEt3s4pU5WAX5DLFGPSD2C/EXRDvHZgF9OTJeu5U4ErQ==", "dev": true, "requires": { "chokidar": "^1.4.2", "minimist": "^1.2.0", "reflect-metadata": "^0.1.2", - "tsickle": "^0.27.2" + "tsickle": "^0.29.0" }, "dependencies": { "minimist": { @@ -211,101 +549,90 @@ } }, "@angular/core": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-5.2.11.tgz", - "integrity": "sha512-h2vpvXNAdOqKzbVaZcHnHGMT5A8uDnizk6FgGq6SPyw9s3d+/VxZ9LJaPjUk3g2lICA7og1tUel+2YfF971MlQ==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-6.0.7.tgz", + "integrity": "sha512-aZ0NvbYsMGqg0zUu7+9vuDxnGzwe++RsBBhlwHZHz1ZZwJmU6VJhUhaI+MuKC7rHyFFr9vUxvJ7ilhGaK2+J7A==", "requires": { - "tslib": "^1.7.1" + "tslib": "^1.9.0" } }, "@angular/flex-layout": { - "version": "5.0.0-beta.14", - "resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-5.0.0-beta.14.tgz", - "integrity": "sha512-/fsOqXFUKdCmzzZx0bZ0HCYwcV+BSbVuIgOhaCrZKHj2rqiWKKPgj1ErU3HMT68bBBGag0u0skTdLGtrBorRIA==", + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-6.0.0-beta.16.tgz", + "integrity": "sha512-0AYtIBGrEJshdFMc6TXGloCkD19YTCRKVJl6xZHX4H5dLnUn+daqXcbh4UsWhayevnLp85HEf2ViHLmTa6jv3g==", "requires": { "tslib": "^1.7.1" } }, "@angular/forms": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-5.2.11.tgz", - "integrity": "sha512-wBllFlIubPclAFRXUc84Kc7TMeKOftzrQraVZ7ooTNeFLLa/FZLN2K8HGyRde8X/XDsMu1XAmjNfkz++spwTzA==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-6.0.7.tgz", + "integrity": "sha512-bFRdWxLmTiG7z0yZaq22oBHTgVSpJwUJEbZ5ieu21JqTgIDYne+YR/xCJrPj+P2S5NDlEK84g/4y4GoNt/thhQ==", "requires": { - "tslib": "^1.7.1" + "tslib": "^1.9.0" } }, "@angular/http": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/@angular/http/-/http-5.2.11.tgz", - "integrity": "sha512-eR7wNXh1+6MpcQNb3sq4bJVX03dx50Wl3kpPG+Q7N1VSL0oPQSobaTrR17ac3oFCEfSJn6kkUCqtUXha6wcNHg==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@angular/http/-/http-6.0.7.tgz", + "integrity": "sha512-zk/kjsfEXjEQIRpmsjuJO5wgFNxj7JGY6Bq0nianZuyCuj/mlm0zflww2NLX4O22IMnvVSun2Kx+kDY44n4hfw==", "requires": { - "tslib": "^1.7.1" + "tslib": "^1.9.0" } }, "@angular/language-service": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-5.2.11.tgz", - "integrity": "sha512-tgnFAhwBmUs1W0dmcmlBmUlMaOgkoyuSdrcF23lz8W5+nSLb+LnbH5a3blU2NVqA4ESvLKQkPW5dpKa/LuhrPQ==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-6.0.7.tgz", + "integrity": "sha512-R96kTy9Hpy5QPHirJz+5JjnzjJZdwbGwZ6rpq79Fe15RYaYfMjFTAAhmmOgWrnTFBug0QWBWyKV7950JcJIr3Q==", "dev": true }, "@angular/material": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-5.2.5.tgz", - "integrity": "sha512-IltfBeTJWnmZehOQNQ7KoFs7MGWuZTe0g21hIitGkusVNt1cIoTD24xKH5jwztjH19c04IgiwonpurMKM6pBCQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-6.1.0.tgz", + "integrity": "sha512-9FLWjVnHFzAoGSWU5dz8X/QYeBtZGijMJIp1k94QDYz+2xA10IbesEgnv8I5Ri3EPnjV/gCspeSkt1ClLc95CA==", "requires": { "tslib": "^1.7.1" } }, "@angular/platform-browser": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-5.2.11.tgz", - "integrity": "sha512-6YZ4IpBFqXx88vEzBZG2WWnaSYXbFWDgG0iT+bZPHAfwsbmqbcMcs7Ogu+XZ4VmK02dTqbrFh7U4P2W+sqrzow==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-6.0.7.tgz", + "integrity": "sha512-CASH1CDr2DD+aBrWN9qpDDFTI3H6p/oqH23h28bEV+LZl7F57r4sj8KXKgaE+mcrOFRQqXTAlPoq3hRCLmhtVA==", "requires": { - "tslib": "^1.7.1" + "tslib": "^1.9.0" } }, "@angular/platform-browser-dynamic": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-5.2.11.tgz", - "integrity": "sha512-5kKPNULcXNwkyBjpHfF+pq+Yxi8Zl866YSOK9t8txoiQ9Ctw97kMkEJcTetk6MJgBp/NP3YyjtoTAm8oXLerug==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-6.0.7.tgz", + "integrity": "sha512-8G45A9w8UJvX3vPEHqeJHt/sd0zu6w1M+rsnOCo78r35SjsLbrmDNhc4VkLZFJ+iNjgPWtNtdpeXQqtTHE46yw==", "requires": { - "tslib": "^1.7.1" + "tslib": "^1.9.0" } }, "@angular/router": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-5.2.11.tgz", - "integrity": "sha512-NT8xYl7Vr3qPygisek3PlXqNROEjg48GXOEsDEc7c8lDBo3EB9Tf328fWJD0GbLtXZNhmmNNxwIe+qqPFFhFAA==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-6.0.7.tgz", + "integrity": "sha512-KuQBeIgfiwV3bLafepMhYVJQIAF8cTckCudFh5Z0OqckJgGsWSgtvEdtBctPi+lzt7OQBi7Ym2rOv3X0dOvu0Q==", "requires": { - "tslib": "^1.7.1" + "tslib": "^1.9.0" } }, "@covalent/core": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@covalent/core/-/core-1.0.0.tgz", - "integrity": "sha512-qUGL6CtyHNa3ttKGrvuQY0lJyQR9Dxp04vP0vrXmYrKapVbfYZ82qwJ2+PrX1EcWAQ6b/B2giFe0Q83ePin04g==", + "version": "2.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@covalent/core/-/core-2.0.0-beta.2.tgz", + "integrity": "sha512-b0SXWn7WxIlzLsjSxgV+a44U23dvcNKNDUY2h81ZYO/Bd0VOWc06RTdpCsq6N23JkWArvp+2B0PvZpH6lDacYA==", "requires": { - "tslib": "^1.7.1" + "tslib": "^1.9.0" } }, - "@ngtools/json-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ngtools/json-schema/-/json-schema-1.2.0.tgz", - "integrity": "sha512-pMh+HDc6mOjUO3agRfB1tInimo7hf67u+0Cska2bfXFe6oU7rSMnr5PLVtiZVgwMoBHpx/6XjBymvcnWPo2Uzg==", - "dev": true - }, "@ngtools/webpack": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-1.10.2.tgz", - "integrity": "sha512-3u2zg2rarG3qNLSukBClGADWuq/iNn5SQtlSeAbfKzwBeyLGbF0gN1z1tVx1Bcr8YwFzR6NdRePQmJGcoqq1fg==", + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-6.0.8.tgz", + "integrity": "sha512-jorGpTd82ILbyUwg4JQekovHFaYwSMlZan4f7x+sd3+2WgyL3Z1+ZbVSGKvXZWKS/mAVx7eLkRikzJkuC4FgHw==", "dev": true, "requires": { - "chalk": "~2.2.0", - "enhanced-resolve": "^3.1.0", - "loader-utils": "^1.0.2", - "magic-string": "^0.22.3", - "semver": "^5.3.0", - "source-map": "^0.5.6", + "@angular-devkit/core": "0.6.8", "tree-kill": "^1.0.0", "webpack-sources": "^1.1.0" } @@ -318,112 +645,353 @@ "tslib": "^1.9.0" } }, - "@ngx-translate/http-loader": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@ngx-translate/http-loader/-/http-loader-3.0.1.tgz", - "integrity": "sha1-ILD5i8bCUyESnT4zAqs8xInApCo=", + "@ngx-translate/http-loader": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@ngx-translate/http-loader/-/http-loader-3.0.1.tgz", + "integrity": "sha1-ILD5i8bCUyESnT4zAqs8xInApCo=", + "requires": { + "tslib": "^1.9.0" + } + }, + "@schematics/angular": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.6.8.tgz", + "integrity": "sha512-9kRphqTYG5Df/I8fvnT1zMsw0YNDPO9tl18tQZXj4am4raT7l9UCr+WkwJdlBoA5pwG6baWE9sL0iGWV/bzF/g==", + "dev": true, + "requires": { + "@angular-devkit/core": "0.6.8", + "@angular-devkit/schematics": "0.6.8", + "typescript": ">=2.6.2 <2.8" + } + }, + "@schematics/update": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.6.8.tgz", + "integrity": "sha512-1Uq7LYnwL2wBwGVCgNz76QAR13ghAk+2vDDHOi+VX5+usHManxydrpoMGeX66OBPd+y5D3D2MFb+8mYHE7mygg==", + "dev": true, + "requires": { + "@angular-devkit/core": "0.6.8", + "@angular-devkit/schematics": "0.6.8", + "npm-registry-client": "^8.5.1", + "rxjs": "^6.0.0", + "semver": "^5.3.0", + "semver-intersect": "^1.1.2" + } + }, + "@swimlane/ngx-datatable": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/@swimlane/ngx-datatable/-/ngx-datatable-13.0.1.tgz", + "integrity": "sha512-jjMEzQhXcdD+jfKNp+7U61lWx9ZzSGDn9QbpY6pJOJwz+E2CKeek6OouT5Qcc4MY4oFL9g/SZoPjLf90cbNIRw==" + }, + "@types/file-saver": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-1.3.0.tgz", + "integrity": "sha512-fC12hKtEzVkrV/ZRcrmqvpHG/TMYDZtgpAmgMUA4F7KneDaQeFMwmPz8AfygKKJMqsdTi8bL+E+fciaaMLxUhg==" + }, + "@types/jasmine": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.8.tgz", + "integrity": "sha512-OJSUxLaxXsjjhob2DBzqzgrkLmukM3+JMpRp0r0E4HTdT1nwDCWhaswjYxazPij6uOdzHCJfNbDjmQ1/rnNbCg==", + "dev": true + }, + "@types/jasminewd2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.3.tgz", + "integrity": "sha512-hYDVmQZT5VA2kigd4H4bv7vl/OhlympwREUemqBdOqtrYTo5Ytm12a5W5/nGgGYdanGVxj0x/VhZ7J3hOg/YKg==", + "dev": true, + "requires": { + "@types/jasmine": "*" + } + }, + "@types/node": { + "version": "6.0.113", + "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.113.tgz", + "integrity": "sha512-f9XXUWFqryzjkZA1EqFvJHSFyqyasV17fq8zCDIzbRV4ctL7RrJGKvG+lcex86Rjbzd1GrER9h9VmF5sSjV0BQ==", + "dev": true + }, + "@types/q": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", + "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", + "dev": true + }, + "@types/selenium-webdriver": { + "version": "2.53.43", + "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz", + "integrity": "sha512-UBYHWph6P3tutkbXpW6XYg9ZPbTKjw/YC2hGG1/GEvWwTbvezBUv3h+mmUFw79T3RFPnmedpiXdOBbXX+4l0jg==", + "dev": true + }, + "@types/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=", + "dev": true + }, + "@types/strip-json-comments": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", + "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.4.3.tgz", + "integrity": "sha512-S6npYhPcTHDYe9nlsKa9CyWByFi8Vj8HovcAgtmMAQZUOczOZbQ8CnwMYKYC5HEZzxEE+oY0jfQk4cVlI3J59Q==", + "dev": true, + "requires": { + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/wast-parser": "1.4.3", + "debug": "^3.1.0", + "webassemblyjs": "1.4.3" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.4.3.tgz", + "integrity": "sha512-3zTkSFswwZOPNHnzkP9ONq4bjJSeKVMcuahGXubrlLmZP8fmTIJ58dW7h/zOVWiFSuG2em3/HH3BlCN7wyu9Rw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.4.3.tgz", + "integrity": "sha512-e8+KZHh+RV8MUvoSRtuT1sFXskFnWG9vbDy47Oa166xX+l0dD5sERJ21g5/tcH8Yo95e9IN3u7Jc3NbhnUcSkw==", + "dev": true, + "requires": { + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.4.3.tgz", + "integrity": "sha512-9FgHEtNsZQYaKrGCtsjswBil48Qp1agrzRcPzCbQloCoaTbOXLJ9IRmqT+uEZbenpULLRNFugz3I4uw18hJM8w==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.4.3" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.4.3.tgz", + "integrity": "sha512-JINY76U+702IRf7ePukOt037RwmtH59JHvcdWbTTyHi18ixmQ+uOuNhcdCcQHTquDAH35/QgFlp3Y9KqtyJsCQ==", + "dev": true + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.4.3.tgz", + "integrity": "sha512-I7bS+HaO0K07Io89qhJv+z1QipTpuramGwUSDkwEaficbSvCcL92CUZEtgykfNtk5wb0CoLQwWlmXTwGbNZUeQ==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.4.3.tgz", + "integrity": "sha512-p0yeeO/h2r30PyjnJX9xXSR6EDcvJd/jC6xa/Pxg4lpfcNi7JUswOpqDToZQ55HMMVhXDih/yqkaywHWGLxqyQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-buffer": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/wasm-gen": "1.4.3", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@webassemblyjs/leb128": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.4.3.tgz", + "integrity": "sha512-4u0LJLSPzuRDWHwdqsrThYn+WqMFVqbI2ltNrHvZZkzFPO8XOZ0HFQ5eVc4jY/TNHgXcnwrHjONhPGYuuf//KQ==", + "dev": true, "requires": { - "tslib": "^1.9.0" + "leb": "^0.3.0" } }, - "@schematics/angular": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.3.2.tgz", - "integrity": "sha512-Elrk0BA951s0ScFZU0AWrpUeJBYVR52DZ1QTIO5R0AhwEd1PW4olI8szPLGQlVW5Sd6H0FA/fyFLIvn2r9v6Rw==", + "@webassemblyjs/validation": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/validation/-/validation-1.4.3.tgz", + "integrity": "sha512-R+rRMKfhd9mq0rj2mhU9A9NKI2l/Rw65vIYzz4lui7eTKPcCu1l7iZNi4b9Gen8D42Sqh/KGiaQNk/x5Tn/iBQ==", "dev": true, "requires": { - "typescript": "~2.6.2" + "@webassemblyjs/ast": "1.4.3" + } + }, + "@webassemblyjs/wasm-edit": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.4.3.tgz", + "integrity": "sha512-qzuwUn771PV6/LilqkXcS0ozJYAeY/OKbXIWU3a8gexuqb6De2p4ya/baBeH5JQ2WJdfhWhSvSbu86Vienttpw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-buffer": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/helper-wasm-section": "1.4.3", + "@webassemblyjs/wasm-gen": "1.4.3", + "@webassemblyjs/wasm-opt": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "@webassemblyjs/wast-printer": "1.4.3", + "debug": "^3.1.0" }, "dependencies": { - "typescript": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", - "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", - "dev": true + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } } } }, - "@schematics/package-update": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@schematics/package-update/-/package-update-0.3.2.tgz", - "integrity": "sha512-7aVP4994Hu8vRdTTohXkfGWEwLhrdNP3EZnWyBootm5zshWqlQojUGweZe5zwewsKcixeVOiy2YtW+aI4aGSLA==", + "@webassemblyjs/wasm-gen": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.4.3.tgz", + "integrity": "sha512-eR394T8dHZfpLJ7U/Z5pFSvxl1L63JdREebpv9gYc55zLhzzdJPAuxjBYT4XqevUdW67qU2s0nNA3kBuNJHbaQ==", "dev": true, "requires": { - "rxjs": "^5.5.6", - "semver": "^5.3.0", - "semver-intersect": "^1.1.2" + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/leb128": "1.4.3" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.4.3.tgz", + "integrity": "sha512-7Gp+nschuKiDuAL1xmp4Xz0rgEbxioFXw4nCFYEmy+ytynhBnTeGc9W9cB1XRu1w8pqRU2lbj2VBBA4cL5Z2Kw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-buffer": "1.4.3", + "@webassemblyjs/wasm-gen": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "debug": "^3.1.0" }, "dependencies": { - "rxjs": { - "version": "5.5.11", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.11.tgz", - "integrity": "sha512-3bjO7UwWfA2CV7lmwYMBzj4fQ6Cq+ftHc2MvUe+WMS7wcdJ1LosDWmdjPQanYp2dBRj572p7PeU81JUxHKOcBA==", + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "symbol-observable": "1.0.1" + "ms": "2.0.0" } } } }, - "@swimlane/ngx-datatable": { - "version": "11.3.2", - "resolved": "https://registry.npmjs.org/@swimlane/ngx-datatable/-/ngx-datatable-11.3.2.tgz", - "integrity": "sha512-Fn1RMJ991elSvp+LV2SGzG28ypuLM2DFyXAb7o8p4kzuhqtELwB25doXrLLVrtE2QtKmzoD9fRfbEUNsBKgoWA==" - }, - "@types/file-saver": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-1.3.0.tgz", - "integrity": "sha512-fC12hKtEzVkrV/ZRcrmqvpHG/TMYDZtgpAmgMUA4F7KneDaQeFMwmPz8AfygKKJMqsdTi8bL+E+fciaaMLxUhg==" - }, - "@types/jasmine": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.8.tgz", - "integrity": "sha512-OJSUxLaxXsjjhob2DBzqzgrkLmukM3+JMpRp0r0E4HTdT1nwDCWhaswjYxazPij6uOdzHCJfNbDjmQ1/rnNbCg==", - "dev": true - }, - "@types/jasminewd2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.3.tgz", - "integrity": "sha512-hYDVmQZT5VA2kigd4H4bv7vl/OhlympwREUemqBdOqtrYTo5Ytm12a5W5/nGgGYdanGVxj0x/VhZ7J3hOg/YKg==", + "@webassemblyjs/wasm-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.4.3.tgz", + "integrity": "sha512-KXBjtlwA3BVukR/yWHC9GF+SCzBcgj0a7lm92kTOaa4cbjaTaa47bCjXw6cX4SGQpkncB9PU2hHGYVyyI7wFRg==", "dev": true, "requires": { - "@types/jasmine": "*" + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/leb128": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "webassemblyjs": "1.4.3" } }, - "@types/node": { - "version": "6.0.113", - "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.113.tgz", - "integrity": "sha512-f9XXUWFqryzjkZA1EqFvJHSFyqyasV17fq8zCDIzbRV4ctL7RrJGKvG+lcex86Rjbzd1GrER9h9VmF5sSjV0BQ==", - "dev": true - }, - "@types/q": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", - "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", - "dev": true - }, - "@types/selenium-webdriver": { - "version": "2.53.43", - "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz", - "integrity": "sha512-UBYHWph6P3tutkbXpW6XYg9ZPbTKjw/YC2hGG1/GEvWwTbvezBUv3h+mmUFw79T3RFPnmedpiXdOBbXX+4l0jg==", - "dev": true + "@webassemblyjs/wast-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.4.3.tgz", + "integrity": "sha512-QhCsQzqV0CpsEkRYyTzQDilCNUZ+5j92f+g35bHHNqS22FppNTywNFfHPq8ZWZfYCgbectc+PoghD+xfzVFh1Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/floating-point-hex-parser": "1.4.3", + "@webassemblyjs/helper-code-frame": "1.4.3", + "@webassemblyjs/helper-fsm": "1.4.3", + "long": "^3.2.0", + "webassemblyjs": "1.4.3" + } }, - "@types/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=", - "dev": true + "@webassemblyjs/wast-printer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.4.3.tgz", + "integrity": "sha512-EgXk4anf8jKmuZJsqD8qy5bz2frEQhBvZruv+bqwNoLWUItjNSFygk8ywL3JTEz9KtxTlAmqTXNrdD1d9gNDtg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/wast-parser": "1.4.3", + "long": "^3.2.0" + } }, - "@types/strip-json-comments": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", - "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", - "dev": true + "@webpack-contrib/schema-utils": { + "version": "1.0.0-beta.0", + "resolved": "https://registry.npmjs.org/@webpack-contrib/schema-utils/-/schema-utils-1.0.0-beta.0.tgz", + "integrity": "sha512-LonryJP+FxQQHsjGBi6W786TQB1Oym+agTpY0c+Kj8alnIw+DLUJb6SI8Y1GHGhLCH1yPRrucjObUmxNICQ1pg==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0", + "chalk": "^2.3.2", + "strip-ansi": "^4.0.0", + "text-table": "^0.2.0", + "webpack-log": "^1.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } }, "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", "dev": true }, "accepts": { @@ -443,20 +1011,12 @@ "dev": true }, "acorn-dynamic-import": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", - "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", + "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", "dev": true, "requires": { - "acorn": "^4.0.3" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - } + "acorn": "^5.0.0" } }, "addressparser": { @@ -488,29 +1048,15 @@ } }, "ajv": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.1.tgz", - "integrity": "sha512-pgZos1vgOHDiC7gKNbZW8eKvCnNXARv2oqrGQT7Hzbq5Azp7aZG6DJzADnkuSq7RH6qkXp4J/m68yPX/2uBHyQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.4.0.tgz", + "integrity": "sha1-06/3jpJ3VJdx2vAWTP9ISCt1T8Y=", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", + "fast-deep-equal": "^1.0.0", "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.1" - }, - "dependencies": { - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - } + "json-schema-traverse": "^0.3.0", + "uri-js": "^3.0.2" } }, "ajv-keywords": { @@ -842,16 +1388,16 @@ "dev": true }, "autoprefixer": { - "version": "7.2.6", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.6.tgz", - "integrity": "sha512-Iq8TRIB+/9eQ8rbGhcP7ct5cYb/3qjNYAR2SnzLCEcwF6rvVOax8+9+fccgXk4bEhQGjOZd5TLhsksmAdsbGqQ==", + "version": "8.6.4", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-8.6.4.tgz", + "integrity": "sha512-9D0OoxWCqq9Okp9wD+igaCf6ZaNjYNFSCKxgMLAxAGqXwpapaZ+D0PBv265VHQLgam8a7gld4E6KgJJM6SKfQQ==", "dev": true, "requires": { - "browserslist": "^2.11.3", - "caniuse-lite": "^1.0.30000805", + "browserslist": "^3.2.8", + "caniuse-lite": "^1.0.30000859", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^6.0.17", + "postcss": "^6.0.23", "postcss-value-parser": "^3.2.3" } }, @@ -1393,13 +1939,13 @@ } }, "browserslist": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", - "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000792", - "electron-to-chromium": "^1.3.30" + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" } }, "buffer": { @@ -1474,6 +2020,12 @@ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, + "builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", + "dev": true + }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -1555,9 +2107,9 @@ } }, "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true }, "camelcase-keys": { @@ -1568,12 +2120,20 @@ "requires": { "camelcase": "^2.0.0", "map-obj": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + } } }, "caniuse-lite": { - "version": "1.0.30000856", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000856.tgz", - "integrity": "sha512-x3mYcApHMQemyaHuH/RyqtKCGIYTgEA63fdi+VBvDz8xUSmRiVWTLeyKcoGQCGG6UPR9/+4qG4OKrTa6aSQRKg==", + "version": "1.0.30000861", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000861.tgz", + "integrity": "sha512-aeEQ4kyd41qCl8XFbCjWgVBI3EOd66M9sC43MFn0kuD/vcrNqvoIAlKon4xdp8yMCYvVjdCltI3lgArj8I6cNA==", "dev": true }, "caseless": { @@ -1587,6 +2147,7 @@ "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "dev": true, + "optional": true, "requires": { "align-text": "^0.1.3", "lazy-cache": "^1.0.3" @@ -1601,6 +2162,23 @@ "ansi-styles": "^3.1.0", "escape-string-regexp": "^1.0.5", "supports-color": "^4.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + } + } } }, "chokidar": { @@ -1626,6 +2204,12 @@ "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", "dev": true }, + "chrome-trace-event": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-0.1.3.tgz", + "integrity": "sha512-sjndyZHrrWiu4RY7AkHgjn80GfAM2ZSzUkZLV/Js59Ldmh6JDThf0SUmOHU53rFu2rVxxfCzJ30Ukcfch3Gb/A==", + "dev": true + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -1637,9 +2221,9 @@ } }, "circular-dependency-plugin": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-4.4.0.tgz", - "integrity": "sha512-yEFtUNUYT4jBykEX5ZOHw+5goA3glGZr9wAXIQqoyakjz5H5TeUmScnWRc52douAhb9eYzK3s7V6bXfNnjFdzg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.0.2.tgz", + "integrity": "sha512-oC7/DVAyfcY3UWKm0sN/oVoDedQDQiw/vIiAnuTWTpE5s0zWf7l3WY417Xw/Fbi/QbAjctAkxgMiS9P0s3zkmA==", "dev": true }, "circular-json": { @@ -1691,6 +2275,7 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "dev": true, + "optional": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1", @@ -1813,12 +2398,6 @@ "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", "dev": true }, - "common-tags": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", - "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", - "dev": true - }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -2020,12 +2599,12 @@ "dev": true }, "copy-webpack-plugin": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.4.3.tgz", - "integrity": "sha512-v4THQ24Tks2NkyOvZuFDgZVfDD9YaA9rwYLZTrWg2GHIA8lrH5DboEyeoorh5Skki+PUbgSmnsCwhMWqYrQZrA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.5.2.tgz", + "integrity": "sha512-zmC33E8FFSq3AbflTvqvPvBo621H36Afsxlui91d+QyZxPIuXghfnTsa1CuqiAaCPgJoSUWfTFbKJnadZpKEbQ==", "dev": true, "requires": { - "cacache": "^10.0.1", + "cacache": "^10.0.4", "find-cache-dir": "^1.0.0", "globby": "^7.1.1", "is-glob": "^4.0.0", @@ -2057,15 +2636,6 @@ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==" }, - "core-object": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/core-object/-/core-object-3.1.5.tgz", - "integrity": "sha512-sA2/4+/PZ/KV6CKgjrVrrUVBKCkdDO02CUlQ0YKTQoYUwPYNOtOAcWlbYhd5v/1JqYaA6oZ4sDlOU4ppVw6Wbg==", - "dev": true, - "requires": { - "chalk": "^2.0.0" - } - }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -2324,8 +2894,7 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true, - "optional": true + "dev": true }, "default-require-extensions": { "version": "2.0.0", @@ -2477,12 +3046,6 @@ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true }, - "denodeify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", - "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", - "dev": true - }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -2698,9 +3261,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.49", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.49.tgz", - "integrity": "sha1-ZROEsNgfB4qWY5srNpdRQbeRUAQ=", + "version": "1.3.50", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.50.tgz", + "integrity": "sha1-dDi3b5K0G5GfP73TUPvQdX2s3fc=", "dev": true }, "elliptic": { @@ -2718,12 +3281,6 @@ "minimalistic-crypto-utils": "^1.0.0" } }, - "ember-cli-string-utils": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ember-cli-string-utils/-/ember-cli-string-utils-1.1.0.tgz", - "integrity": "sha1-ObZ3/CgF9VFzc1N2/O8njqpEUqE=", - "dev": true - }, "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", @@ -2815,15 +3372,14 @@ } }, "enhanced-resolve": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", - "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", "dev": true, "requires": { "graceful-fs": "^4.1.2", "memory-fs": "^0.4.0", - "object-assign": "^4.0.1", - "tapable": "^0.2.7" + "tapable": "^1.0.0" } }, "ent": { @@ -2902,20 +3458,6 @@ "es6-symbol": "^3.1.1" } }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-set": "~0.1.5", - "es6-symbol": "~3.1.1", - "event-emitter": "~0.3.5" - } - }, "es6-promise": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", @@ -2931,19 +3473,6 @@ "es6-promise": "^4.0.3" } }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" - } - }, "es6-symbol": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", @@ -2954,18 +3483,6 @@ "es5-ext": "~0.10.14" } }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.14", - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -3008,14 +3525,12 @@ } } }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", "dev": true, "requires": { - "es6-map": "^0.1.3", - "es6-weak-map": "^2.0.1", "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } @@ -3053,16 +3568,6 @@ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", @@ -3284,41 +3789,6 @@ "is-extglob": "^1.0.0" } }, - "extract-text-webpack-plugin": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz", - "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==", - "dev": true, - "requires": { - "async": "^2.4.1", - "loader-utils": "^1.1.0", - "schema-utils": "^0.3.0", - "webpack-sources": "^1.0.1" - }, - "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "schema-utils": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", - "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", - "dev": true, - "requires": { - "ajv": "^5.0.0" - } - } - } - }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -3341,8 +3811,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true, - "optional": true + "dev": true }, "fastparse": { "version": "1.1.1", @@ -3553,17 +4022,6 @@ "null-check": "^1.0.0" } }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", @@ -4496,10 +4954,16 @@ "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", "dev": true }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", "dev": true }, "has-unicode": { @@ -4644,9 +5108,9 @@ } }, "hosted-git-info": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", - "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.1.tgz", + "integrity": "sha512-Ba4+0M4YvIDUUsprMjhVTU1yN9F2/LJSAl69ZpzaLT4l4j5mwTS6jqqW9Ojvj6lKz/veqPzpJBqGbXspOb533A==", "dev": true }, "hpack.js": { @@ -4668,9 +5132,9 @@ "dev": true }, "html-minifier": { - "version": "3.5.16", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.16.tgz", - "integrity": "sha512-zP5EfLSpiLRp0aAgud4CQXPQZm9kXwWjR/cF0PfdOj+jjWnOaCgeZcll4kYXSvIBPeUMmyaSc7mM4IDtA+kboA==", + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.17.tgz", + "integrity": "sha512-O+StuKL0UWfwX5Zv4rFxd60DPcT5DVjGq1AlnP6VQ8wzudft/W4hx5Wl98aSYNwFBHY6XWJreRw/BehX4l+diQ==", "dev": true, "requires": { "camel-case": "3.0.x", @@ -4679,21 +5143,22 @@ "he": "1.1.x", "param-case": "2.1.x", "relateurl": "0.2.x", - "uglify-js": "3.3.x" + "uglify-js": "3.4.x" } }, "html-webpack-plugin": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-2.30.1.tgz", - "integrity": "sha1-f5xCG36pHsRg9WUn1430hO51N9U=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz", + "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=", "dev": true, "requires": { - "bluebird": "^3.4.7", "html-minifier": "^3.2.3", "loader-utils": "^0.2.16", "lodash": "^4.17.3", "pretty-error": "^2.0.2", - "toposort": "^1.0.0" + "tapable": "^1.0.0", + "toposort": "^1.0.0", + "util.promisify": "1.0.0" }, "dependencies": { "loader-utils": { @@ -4728,103 +5193,324 @@ "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", "dev": true, "requires": { - "domelementtype": "1" + "domelementtype": "1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "http-parser-js": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.13.tgz", + "integrity": "sha1-O9bW/ebjFyyTNMOzO2wZPYD+ETc=", + "dev": true + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "dev": true, + "requires": { + "agent-base": "4", + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "http-proxy-middleware": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz", + "integrity": "sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==", + "dev": true, + "requires": { + "http-proxy": "^1.16.2", + "is-glob": "^4.0.0", + "lodash": "^4.17.5", + "micromatch": "^3.1.9" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "kind-of": "^6.0.0" } }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": true - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "http-parser-js": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.13.tgz", - "integrity": "sha1-O9bW/ebjFyyTNMOzO2wZPYD+ETc=", - "dev": true - }, - "http-proxy": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", - "dev": true, - "requires": { - "eventemitter3": "^3.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "dev": true, - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "ms": "2.0.0" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } - } - } - }, - "http-proxy-middleware": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz", - "integrity": "sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM=", - "dev": true, - "requires": { - "http-proxy": "^1.16.2", - "is-glob": "^3.1.0", - "lodash": "^4.17.2", - "micromatch": "^2.3.11" - }, - "dependencies": { + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -4832,12 +5518,65 @@ "dev": true }, "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "is-extglob": "^2.1.0" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } } } @@ -5009,12 +5748,6 @@ "meow": "^3.3.0" } }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -5360,12 +6093,117 @@ "isarray": "1.0.0" } }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", + "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", + "dev": true, + "requires": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": ">=0.0.4" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, "istanbul-api": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.1.tgz", @@ -5581,12 +6419,6 @@ "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", "dev": true }, - "json-loader": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", - "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", - "dev": true - }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -5626,15 +6458,6 @@ "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", "dev": true }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", @@ -6186,7 +7009,8 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true + "dev": true, + "optional": true }, "lcid": { "version": "1.0.0", @@ -6197,20 +7021,147 @@ "invert-kv": "^1.0.0" } }, + "leb": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/leb/-/leb-0.3.0.tgz", + "integrity": "sha1-Mr7p+tFoMo1q6oUi2DP0GA7tHaM=", + "dev": true + }, "less": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/less/-/less-2.7.3.tgz", - "integrity": "sha512-KPdIJKWcEAb02TuJtaLrhue0krtRLoRoo7x6BNJIBelO00t/CCdJQUnHW5V34OnHMWzIktSalJxRO+FvytQlCQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/less/-/less-3.0.4.tgz", + "integrity": "sha512-q3SyEnPKbk9zh4l36PGeW2fgynKu+FpbhiUNx/yaiBUQ3V0CbACCgb9FzYWcRgI2DJlP6eI4jc8XPrCTi55YcQ==", "dev": true, "requires": { "errno": "^0.1.1", "graceful-fs": "^4.1.2", "image-size": "~0.5.0", - "mime": "^1.2.11", + "mime": "^1.4.1", "mkdirp": "^0.5.0", "promise": "^7.1.1", - "request": "2.81.0", - "source-map": "^0.5.3" + "request": "^2.83.0", + "source-map": "~0.6.0" + }, + "dependencies": { + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "optional": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "optional": true + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "dev": true, + "optional": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "1.0.6", + "mime-types": "^2.1.12" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "optional": true + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "dev": true, + "optional": true, + "requires": { + "ajv": "^5.1.0", + "har-schema": "^2.0.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true, + "optional": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "optional": true + }, + "request": { + "version": "2.87.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", + "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.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.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + } } }, "less-loader": { @@ -6229,7 +7180,6 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, - "optional": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -6338,11 +7288,6 @@ "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", "dev": true }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" - }, "lodash.assign": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", @@ -6375,21 +7320,13 @@ "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=", "dev": true }, - "lodash.template": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", - "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", - "requires": { - "lodash._reinterpolate": "~3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", - "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, "requires": { - "lodash._reinterpolate": "~3.0.0" + "chalk": "^2.0.1" } }, "log4js": { @@ -6555,6 +7492,22 @@ "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=", "dev": true }, + "loglevelnext": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.5.tgz", + "integrity": "sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==", + "dev": true, + "requires": { + "es6-symbol": "^3.1.1", + "object.assign": "^4.1.0" + } + }, + "long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", + "dev": true + }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", @@ -6596,15 +7549,6 @@ "yallist": "^2.1.2" } }, - "magic-string": { - "version": "0.22.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", - "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", - "dev": true, - "requires": { - "vlq": "^0.2.2" - } - }, "mailcomposer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-4.0.1.tgz", @@ -6831,6 +7775,17 @@ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, + "mini-css-extract-plugin": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.1.tgz", + "integrity": "sha512-XWuB3G61Rtasq/gLe7cp5cuozehE6hN+E4sxCamRR/WDiHTg+f7ZIAS024r8UJQffY+e2gGELXQZgQoFDfNDCg==", + "dev": true, + "requires": { + "@webpack-contrib/schema-utils": "^1.0.0-beta.0", + "loader-utils": "^1.1.0", + "webpack-sources": "^1.1.0" + } + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -7032,14 +7987,6 @@ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, - "ngx-breadcrumbs": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/ngx-breadcrumbs/-/ngx-breadcrumbs-0.0.3.tgz", - "integrity": "sha512-fa1pg/ZxgLZd4pqbXoBtrkPrYbg2WxWc+QEkJgZ/h/oTXVCwWcYWdGm6ZMny/ib0ywOAqVzO3ZkmnJMD9FHkkw==", - "requires": { - "lodash.template": "^4.4.0" - } - }, "no-case": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", @@ -7076,16 +8023,6 @@ "which": "1" }, "dependencies": { - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "optional": true, - "requires": { - "abbrev": "1" - } - }, "semver": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", @@ -7134,12 +8071,6 @@ } } }, - "node-modules-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/node-modules-path/-/node-modules-path-1.0.1.tgz", - "integrity": "sha1-QAlrCM560OoUaAhjr0ScfHWl0cg=", - "dev": true - }, "node-sass": { "version": "4.9.0", "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.9.0.tgz", @@ -7344,13 +8275,12 @@ "dev": true }, "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { - "abbrev": "1", - "osenv": "^0.1.4" + "abbrev": "1" } }, "normalize-package-data": { @@ -7380,6 +8310,38 @@ "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", "dev": true }, + "npm-package-arg": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.0.tgz", + "integrity": "sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.6.0", + "osenv": "^0.1.5", + "semver": "^5.5.0", + "validate-npm-package-name": "^3.0.0" + } + }, + "npm-registry-client": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/npm-registry-client/-/npm-registry-client-8.5.1.tgz", + "integrity": "sha512-7rjGF2eA7hKDidGyEWmHTiKfXkbrcQAsGL/Rh4Rt3x3YNRNHhwaTzVJfW3aNvvlhg4G62VCluif0sLCb/i51Hg==", + "dev": true, + "requires": { + "concat-stream": "^1.5.2", + "graceful-fs": "^4.1.6", + "normalize-package-data": "~1.0.1 || ^2.0.0", + "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", + "npmlog": "2 || ^3.1.0 || ^4.0.0", + "once": "^1.3.3", + "request": "^2.74.0", + "retry": "^0.10.0", + "safe-buffer": "^5.1.1", + "semver": "2 >=2.2.1 || 3.x || 4 || 5", + "slide": "^1.1.3", + "ssri": "^5.2.4" + } + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -7491,6 +8453,28 @@ } } }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", @@ -7549,9 +8533,9 @@ } }, "opn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz", - "integrity": "sha512-iPNl7SyM8L30Rm1sjGdLLheyHVw5YXVfi3SKWJzBI7efxRwHojfRFjwE/OLM6qp9xJYMgab8WicTU1cPoY+Hpg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", + "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", "dev": true, "requires": { "is-wsl": "^1.1.0" @@ -7572,7 +8556,6 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, - "optional": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.4", @@ -7586,8 +8569,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true, - "optional": true + "dev": true } } }, @@ -7623,6 +8605,7 @@ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, + "optional": true, "requires": { "lcid": "^1.0.0" } @@ -7788,6 +8771,12 @@ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, "parseqs": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", @@ -7969,9 +8958,9 @@ "dev": true }, "postcss": { - "version": "6.0.22", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz", - "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==", + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", "dev": true, "requires": { "chalk": "^2.4.1", @@ -7990,26 +8979,11 @@ "supports-color": "^5.3.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, @@ -8870,11 +9844,18 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, + "retry": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", + "dev": true + }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "dev": true, + "optional": true, "requires": { "align-text": "^0.1.1" } @@ -8908,13 +9889,18 @@ } }, "rxjs": { - "version": "5.6.0-forward-compat.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.6.0-forward-compat.5.tgz", - "integrity": "sha512-CJ9UIV5LlcyGhKWOVvZa4PcVbJJbGNcTunG29cflNo+Y2jAZgvMdZVl4xwYNiYK5gmley/0QuAFVJ0M4GO+GNQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.1.tgz", + "integrity": "sha512-OwMxHxmnmHTUpgO+V7dZChf3Tixf4ih95cmXjzzadULziVl/FKhHScGLj4goEw9weePVOH2Q0+GcCBUhKCZc/g==", "requires": { - "symbol-observable": "1.0.1" + "tslib": "^1.9.0" } }, + "rxjs-compat": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.2.1.tgz", + "integrity": "sha512-Pst0lkAwVodBbBOIZic9aM1vY9asJ2u8GfKN115+goIH83PAlizJDyvixuxPAuQ1UtkmBuro7+0PqKQ3PSkhEg==" + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -8950,9 +9936,9 @@ } }, "sass-loader": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-6.0.7.tgz", - "integrity": "sha512-JoiyD00Yo1o61OJsoP2s2kb19L1/Y2p3QFcCdWdF6oomBGKVYuZyqHWemRBfQ2uGYsk+CH3eCguXNfpjzlcpaA==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.0.3.tgz", + "integrity": "sha512-iaSFtQcGo4SSgDw5Aes5p4VTrA5jCGSA7sGmhPIcOloBlgI1VktM2MUrk2IHHjbNagckXlPz+HWq1vAAPrcYxA==", "dev": true, "requires": { "clone-deep": "^2.0.1", @@ -9256,6 +10242,12 @@ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", "dev": true }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", + "dev": true + }, "smart-buffer": { "version": "1.1.15", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz", @@ -9684,6 +10676,15 @@ } } }, + "stats-webpack-plugin": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/stats-webpack-plugin/-/stats-webpack-plugin-0.6.2.tgz", + "integrity": "sha1-LFlJtTHgf4eojm6k3PrFOqjHWis=", + "dev": true, + "requires": { + "lodash": "^4.17.4" + } + }, "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", @@ -9828,36 +10829,13 @@ "dev": true }, "style-loader": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.1.tgz", - "integrity": "sha512-IRE+ijgojrygQi3rsqT0U4dd+UcPCqcVvauZpCnQrGAlEe+FUIyrK93bUDScamesjP08JlQNsFJU+KmPedP5Og==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.21.0.tgz", + "integrity": "sha512-T+UNsAcl3Yg+BsPKs1vd22Fr8sVT+CJMtzqc6LEw9bbJZb43lm9GoeIfUcDEefBSWC0BhYbcdupV1GtI4DGzxg==", "dev": true, "requires": { - "loader-utils": "^1.0.2", - "schema-utils": "^0.3.0" - }, - "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "schema-utils": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", - "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", - "dev": true, - "requires": { - "ajv": "^5.0.0" - } - } + "loader-utils": "^1.1.0", + "schema-utils": "^0.4.5" } }, "stylus": { @@ -9911,23 +10889,24 @@ } }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "has-flag": "^2.0.0" + "has-flag": "^3.0.0" } }, "symbol-observable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", - "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true }, "tapable": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", - "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.0.0.tgz", + "integrity": "sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg==", "dev": true }, "tar": { @@ -9942,6 +10921,12 @@ "inherits": "2" } }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -9968,13 +10953,7 @@ "thunky": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.2.tgz", - "integrity": "sha1-qGLgGOP7HqLsP85dVWBc9X8kc3E=", - "dev": true - }, - "time-stamp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-2.0.0.tgz", - "integrity": "sha1-lcakRTDhW6jW9KPsuMOj+sRto1c=", + "integrity": "sha1-qGLgGOP7HqLsP85dVWBc9X8kc3E=", "dev": true }, "timers-browserify": { @@ -10218,9 +11197,9 @@ } }, "tsickle": { - "version": "0.27.5", - "resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.27.5.tgz", - "integrity": "sha512-NP+CjM1EXza/M8mOXBLH3vkFEJiu1zfEAlC5WdJxHPn8l96QPz5eooP6uAgYtw1CcKfuSyIiheNUdKxtDWCNeg==", + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.29.0.tgz", + "integrity": "sha512-JpID0Lv8/irRtPmqJJxb5fCwfZhjZeKmav9Zna7UjqVuJoSbI49Wue/c2PPybX1SbRrjl7bbI/JsCl0dSUJygA==", "dev": true, "requires": { "minimist": "^1.2.0", @@ -10370,15 +11349,15 @@ "dev": true }, "typescript": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.5.3.tgz", - "integrity": "sha512-ptLSQs2S4QuS6/OD1eAKG+S5G8QQtrU5RT32JULdZQtM1L3WTi34Wsu48Yndzi8xsObRAB9RPt/KhA9wlpEF6w==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.2.tgz", + "integrity": "sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==", "dev": true }, "uglify-js": { - "version": "3.3.28", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.28.tgz", - "integrity": "sha512-68Rc/aA6cswiaQ5SrE979UJcXX+ADA1z33/ZsPd+fbAiVdjZ16OXdbtGO+rJUUBgK6qdf3SOPhQf3K/ybF5Miw==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.2.tgz", + "integrity": "sha512-/kVQDzwiE9Vy7Y63eMkMozF4jIt0C2+xHctF9YpqNWdE/NLOuMurshkpoYGUlAbeYhACPv0HJPIHJul0Ak4/uw==", "dev": true, "requires": { "commander": "~2.15.0", @@ -10401,9 +11380,9 @@ "optional": true }, "uglifyjs-webpack-plugin": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.6.tgz", - "integrity": "sha512-NDP94ahjW7ZH+qzdjxjIV04n5YGnrYD2jeHgKgnpUKmdAfcXEO5DbVo21fXAm/KPMyX9k21zWFBMYm9m9R2ptg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.7.tgz", + "integrity": "sha512-1VicfKhCYHLS8m1DCApqBhoulnASsEoJ/BvpUpP4zoNAPpKzdH+ghk0olGJMmwX2/jprK2j3hAHdUbczBSy2FA==", "dev": true, "requires": { "cacache": "^10.0.4", @@ -10505,12 +11484,6 @@ "imurmurhash": "^0.1.4" } }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -10576,9 +11549,9 @@ "dev": true }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-3.0.2.tgz", + "integrity": "sha1-+QuFhQf4HepNz7s8TD2/orVX+qo=", "dev": true, "requires": { "punycode": "^2.1.0" @@ -10608,37 +11581,28 @@ } } }, + "url-join": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.0.tgz", + "integrity": "sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=", + "dev": true + }, "url-loader": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.6.2.tgz", - "integrity": "sha512-h3qf9TNn53BpuXTTcpC+UehiRrl0Cv45Yr/xWayApjw6G8Bg2dGke7rIwDQ39piciWCWrC+WiqLjOh3SUp9n0Q==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.0.1.tgz", + "integrity": "sha512-rAonpHy7231fmweBKUFe0bYnlGDty77E+fm53NZdij7j/YOpyGzc7ttqG1nAXl3aRs0k41o0PC3TvGXQiw2Zvw==", "dev": true, "requires": { - "loader-utils": "^1.0.2", - "mime": "^1.4.1", - "schema-utils": "^0.3.0" + "loader-utils": "^1.1.0", + "mime": "^2.0.3", + "schema-utils": "^0.4.3" }, "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "schema-utils": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", - "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", - "dev": true, - "requires": { - "ajv": "^5.0.0" - } + "mime": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", + "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", + "dev": true } } }, @@ -10702,6 +11666,16 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, "utila": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", @@ -10746,6 +11720,15 @@ "spdx-expression-parse": "^3.0.0" } }, + "validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "dev": true, + "requires": { + "builtins": "^1.0.3" + } + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -10771,12 +11754,6 @@ } } }, - "vlq": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", - "dev": true - }, "vm-browserify": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", @@ -11155,6 +12132,19 @@ "minimalistic-assert": "^1.0.0" } }, + "webassemblyjs": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webassemblyjs/-/webassemblyjs-1.4.3.tgz", + "integrity": "sha512-4lOV1Lv6olz0PJkDGQEp82HempAn147e6BXijWDzz9g7/2nSebVP9GVg62Fz5ZAs55mxq13GA0XLyvY8XkyDjg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/validation": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "@webassemblyjs/wast-parser": "1.4.3", + "long": "^3.2.0" + } + }, "webdriver-js-extender": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-1.0.0.tgz", @@ -11219,266 +12209,307 @@ } }, "webpack": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.11.0.tgz", - "integrity": "sha512-3kOFejWqj5ISpJk4Qj/V7w98h9Vl52wak3CLiw/cDOfbVTq7FeoZ0SdoHHY9PYlHr50ZS42OfvzE2vB4nncKQg==", + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.8.3.tgz", + "integrity": "sha512-/hfAjBISycdK597lxONjKEFX7dSIU1PsYwC3XlXUXoykWBlv9QV5HnO+ql3HvrrgfBJ7WXdnjO9iGPR2aAc5sw==", "dev": true, "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/wasm-edit": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", "acorn": "^5.0.0", - "acorn-dynamic-import": "^2.0.0", + "acorn-dynamic-import": "^3.0.0", "ajv": "^6.1.0", "ajv-keywords": "^3.1.0", - "async": "^2.1.2", - "enhanced-resolve": "^3.4.0", - "escope": "^3.6.0", - "interpret": "^1.0.0", - "json-loader": "^0.5.4", - "json5": "^0.5.1", + "chrome-trace-event": "^0.1.1", + "enhanced-resolve": "^4.0.0", + "eslint-scope": "^3.7.1", "loader-runner": "^2.3.0", "loader-utils": "^1.1.0", "memory-fs": "~0.4.1", + "micromatch": "^3.1.8", "mkdirp": "~0.5.0", + "neo-async": "^2.5.0", "node-libs-browser": "^2.0.0", - "source-map": "^0.5.3", - "supports-color": "^4.2.1", - "tapable": "^0.2.7", - "uglifyjs-webpack-plugin": "^0.4.6", - "watchpack": "^1.4.0", - "webpack-sources": "^1.0.1", - "yargs": "^8.0.2" + "schema-utils": "^0.4.4", + "tapable": "^1.0.0", + "uglifyjs-webpack-plugin": "^1.2.4", + "watchpack": "^1.5.0", + "webpack-sources": "^1.0.1" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/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" - } - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "is-extendable": "^0.1.0" } } } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" + "is-extendable": "^0.1.0" } } } }, - "uglifyjs-webpack-plugin": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", - "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "source-map": "^0.5.6", - "uglify-js": "^2.8.29", - "webpack-sources": "^1.0.1" + "kind-of": "^6.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } }, - "yargs": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", - "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "camelcase": "^4.1.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "read-pkg-up": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^7.0.0" + "kind-of": "^3.0.2" }, "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/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" - } - } + "is-buffer": "^1.1.5" } } } }, - "yargs-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "camelcase": "^4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - } + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } } } @@ -11511,22 +12542,32 @@ } }, "webpack-dev-middleware": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz", - "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.1.3.tgz", + "integrity": "sha512-I6Mmy/QjWU/kXwCSFGaiOoL5YEQIVmbb0o45xMoCyQAg/mClqZVTcsX327sPfekDyJWpCxb+04whNyLOIxpJdQ==", "dev": true, "requires": { + "loud-rejection": "^1.6.0", "memory-fs": "~0.4.1", - "mime": "^1.5.0", + "mime": "^2.1.0", "path-is-absolute": "^1.0.0", "range-parser": "^1.0.3", - "time-stamp": "^2.0.0" + "url-join": "^4.0.0", + "webpack-log": "^1.0.1" + }, + "dependencies": { + "mime": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", + "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", + "dev": true + } } }, "webpack-dev-server": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.11.2.tgz", - "integrity": "sha512-zrPoX97bx47vZiAXfDrkw8pe9QjJ+lunQl3dypojyWwWr1M5I2h0VSrMPfTjopHQPRNn+NqfjcMmhoLcUJe2gA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.4.tgz", + "integrity": "sha512-itcIUDFkHuj1/QQxzUFOEXXmxOj5bku2ScLEsOFPapnq2JRTm58gPdtnBphBJOKL2+M3p6+xygL64bI+3eyzzw==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -11539,7 +12580,7 @@ "del": "^3.0.0", "express": "^4.16.2", "html-entities": "^1.2.0", - "http-proxy-middleware": "~0.17.4", + "http-proxy-middleware": "~0.18.0", "import-local": "^1.0.0", "internal-ip": "1.2.0", "ip": "^1.1.5", @@ -11554,10 +12595,17 @@ "spdy": "^3.4.1", "strip-ansi": "^3.0.0", "supports-color": "^5.1.0", - "webpack-dev-middleware": "1.12.2", - "yargs": "6.6.0" + "webpack-dev-middleware": "3.1.3", + "webpack-log": "^1.1.2", + "yargs": "11.0.0" }, "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, "anymatch": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", @@ -11609,12 +12657,6 @@ } } }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, "chokidar": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", @@ -11636,6 +12678,28 @@ "upath": "^1.0.5" } }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", @@ -11826,12 +12890,6 @@ } } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", @@ -11867,6 +12925,12 @@ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, "is-glob": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", @@ -11929,15 +12993,44 @@ "to-regex": "^3.0.2" } }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, "y18n": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", @@ -11945,37 +13038,48 @@ "dev": true }, "yargs": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", - "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", + "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", "dev": true, "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", + "cliui": "^4.0.0", "decamelize": "^1.1.1", + "find-up": "^2.1.0", "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", + "os-locale": "^2.0.0", "require-directory": "^2.1.1", "require-main-filename": "^1.0.1", "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", "y18n": "^3.2.1", - "yargs-parser": "^4.2.0" + "yargs-parser": "^9.0.2" } }, "yargs-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", - "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", "dev": true, "requires": { - "camelcase": "^3.0.0" + "camelcase": "^4.1.0" } } } }, + "webpack-log": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz", + "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==", + "dev": true, + "requires": { + "chalk": "^2.1.0", + "log-symbols": "^2.1.0", + "loglevelnext": "^1.0.1", + "uuid": "^3.1.0" + } + }, "webpack-merge": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.1.3.tgz", @@ -12004,9 +13108,9 @@ } }, "webpack-subresource-integrity": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.0.4.tgz", - "integrity": "sha1-j6yKfo61n8ahZ2ioXJ2U7n+dDts=", + "version": "1.1.0-rc.4", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.1.0-rc.4.tgz", + "integrity": "sha1-xcTj1pD50vZKlVDgeodn+Xlqpdg=", "dev": true, "requires": { "webpack-core": "^0.6.8" @@ -12047,7 +13151,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true + "dev": true, + "optional": true }, "wide-align": { "version": "1.1.3", @@ -12062,7 +13167,8 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true + "dev": true, + "optional": true }, "with-callback": { "version": "1.0.2", @@ -12203,8 +13309,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true, - "optional": true + "dev": true }, "y18n": { "version": "3.2.1", @@ -12212,26 +13317,26 @@ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", "dev": true, "optional": true + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, + "optional": true, + "requires": { + "camelcase": "^3.0.0" + } } } }, "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", "dev": true, - "optional": true, "requires": { - "camelcase": "^3.0.0" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true, - "optional": true - } + "camelcase": "^4.1.0" } }, "yeast": { diff --git a/dmp-frontend/package.json b/dmp-frontend/package.json index 8195c4bd9..cd4e2db50 100644 --- a/dmp-frontend/package.json +++ b/dmp-frontend/package.json @@ -12,32 +12,33 @@ }, "private": true, "dependencies": { - "@angular/animations": "^5.2.0", - "@angular/cdk": "^5.2.4", - "@angular/common": "^5.2.0", - "@angular/compiler": "^5.2.0", - "@angular/core": "^5.2.0", - "@angular/flex-layout": "5.0.0-beta.14", - "@angular/forms": "^5.2.0", - "@angular/http": "^5.2.0", - "@angular/material": "^5.2.4", - "@angular/platform-browser": "^5.2.0", - "@angular/platform-browser-dynamic": "^5.2.0", - "@angular/router": "^5.2.0", - "@covalent/core": "1.0.0", + "@angular/animations": "6.0.7", + "@angular/cdk": "6.1.0", + "@angular/common": "6.0.7", + "@angular/compiler": "6.0.7", + "@angular/core": "6.0.7", + "@angular/flex-layout": "6.0.0-beta.16", + "@angular/forms": "6.0.7", + "@angular/http": "6.0.7", + "@angular/material": "6.1.0", + "@angular/platform-browser": "6.0.7", + "@angular/platform-browser-dynamic": "6.0.7", + "@angular/router": "6.0.7", + "@covalent/core": "2.0.0-beta.2", "@ngx-translate/core": "10.0.1", "@ngx-translate/http-loader": "3.0.1", - "@swimlane/ngx-datatable": "^11.3.2", + "@swimlane/ngx-datatable": "13.0.1", "@types/file-saver": "1.3.0", "core-js": "^2.4.1", "file-saver": "1.3.3", - "rxjs": "^5.6.0-forward-compat.4", - "zone.js": "^0.8.19" + "rxjs": "^6.2.1", + "rxjs-compat": "^6.1.0", + "zone.js": "^0.8.26" }, "devDependencies": { - "@angular/cli": "~1.7.4", - "@angular/compiler-cli": "^5.2.0", - "@angular/language-service": "^5.2.0", + "@angular/cli": "^6.0.8", + "@angular/compiler-cli": "6.0.7", + "@angular/language-service": "6.0.7", "@types/jasmine": "~2.8.3", "@types/jasminewd2": "~2.0.2", "@types/node": "~6.0.60", @@ -52,6 +53,7 @@ "protractor": "^5.3.2", "ts-node": "~4.1.0", "tslint": "~5.9.1", - "typescript": "~2.5.3" + "typescript": "2.7.2", + "@angular-devkit/build-angular": "~0.6.8" } } diff --git a/dmp-frontend/src/app/app.component.html b/dmp-frontend/src/app/app.component.html index d99506849..b80834747 100644 --- a/dmp-frontend/src/app/app.component.html +++ b/dmp-frontend/src/app/app.component.html @@ -1,4 +1,4 @@ - +
diff --git a/dmp-frontend/src/app/app.component.scss b/dmp-frontend/src/app/app.component.scss index d0bcca980..925d219a4 100644 --- a/dmp-frontend/src/app/app.component.scss +++ b/dmp-frontend/src/app/app.component.scss @@ -1,6 +1,3 @@ .example-container { - width: 400px; - height: 200px; - margin: 10px; - border: 1px solid #555; + background: rgb(250, 248, 248); } diff --git a/dmp-frontend/src/app/app.module.ts b/dmp-frontend/src/app/app.module.ts index e038c01f2..7665c11c0 100644 --- a/dmp-frontend/src/app/app.module.ts +++ b/dmp-frontend/src/app/app.module.ts @@ -38,11 +38,10 @@ import { RecentActivityComponent } from './users/activity/recent-activity.compon import { LanguageResolverService } from './services/language-resolver/language-resolver.service'; import { LanguageService } from './services/language/language.service'; import { UsersModule } from './users/users.module'; -import { HelpContentComponent } from './shared/help-content/help-content.component'; +import { HelpContentComponent, AsideHelpContentComponent } from './shared/help-content/help-content.component'; import { AuthGuard } from './shared/guards/auth.guard'; import { UrlUtilities } from './utilities/UrlUtilities'; import { BreadCrumbResolverService } from './services/breadcrumb/breadcrumb-resolver.service'; -import { McBreadcrumbsModule } from 'ngx-breadcrumbs'; @NgModule({ declarations: [ @@ -52,12 +51,12 @@ import { McBreadcrumbsModule } from 'ngx-breadcrumbs'; RecentActivityComponent, WelcomepageComponent, HelpContentComponent, + AsideHelpContentComponent, B2AccessLoginComponent, ], imports: [ BrowserModule, ReactiveFormsModule, - McBreadcrumbsModule.forRoot(), FormsModule, HttpModule, HttpClientModule, diff --git a/dmp-frontend/src/app/dataset-profile-form/field-form/field-form.component.html b/dmp-frontend/src/app/dataset-profile-form/field-form/field-form.component.html index 8fa08ca8a..bb943a32d 100644 --- a/dmp-frontend/src/app/dataset-profile-form/field-form/field-form.component.html +++ b/dmp-frontend/src/app/dataset-profile-form/field-form/field-form.component.html @@ -1,45 +1,45 @@
-
-
- - - -
-
- - - textarea - booleanDecision - combobox - checkBox - freetext - radiobox - - -
-
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
+
+
+ + + +
+
+ + + textarea + booleanDecision + combobox + checkBox + freetext + radiobox + +
- -
-
-
-
Multiplicity
- - - +
+
+
+
Multiplicity
+ + + - - - -
-
- - + + + +
+
+ + + +
+ + + +
+
+
+
+ + + {{option.value}} + -
- - - -
-
-
-
- - - {{option.value}} - - -
-
- -
+
+ +
- Multiplicity - - - {{i + 1}}. Rule {{i + 1}} +
+ Multiplicity + + + {{i + 1}}. Rule {{i + 1}} -
- -
-
- -
- - Add Rule + - +
+ +
+ + + + + Add Rule + + -
\ No newline at end of file +
diff --git a/dmp-frontend/src/app/dataset-profile-form/section-form/section-form.component.html b/dmp-frontend/src/app/dataset-profile-form/section-form/section-form.component.html index 93b5be782..6223d83fd 100644 --- a/dmp-frontend/src/app/dataset-profile-form/section-form/section-form.component.html +++ b/dmp-frontend/src/app/dataset-profile-form/section-form/section-form.component.html @@ -1,78 +1,78 @@ 
-
-
- - - - - - - - - -
-
- - - {{pageGroup.get('title').value}} - - - - - - true - false - - -
+
+
+ + + + + + + + +
+
+ + + {{pageGroup.get('title').value}} + + + + + + true + false + -
- - - {{i + 1}}. {{form.get('sections').get(''+i).get('title').value}} -
- -
-
-
- -
-
+
+ +
+ + + {{i + 1}}. {{form.get('sections').get(''+i).get('title').value}} +
+ +
+
+
+ +
+
+
- -
- - - - {{i + 1}}. Field {{i + 1}} + {{i + 1}}. Field {{i + 1}} -
- -
-
+
+ +
+ - + -
-
+ +
- - - - -
\ No newline at end of file + + +
diff --git a/dmp-frontend/src/app/datasets/dataset-wizard/dataset-wizard.component.html b/dmp-frontend/src/app/datasets/dataset-wizard/dataset-wizard.component.html index 66120e7b9..3ae118597 100644 --- a/dmp-frontend/src/app/datasets/dataset-wizard/dataset-wizard.component.html +++ b/dmp-frontend/src/app/datasets/dataset-wizard/dataset-wizard.component.html @@ -13,15 +13,11 @@
- - - - - + + +
@@ -54,8 +50,9 @@ + [parentTemplate]='dataRepositoriesTemplate' [displayFunction]='dataRepositoryDisplayFunc' [subtitleFunction]='dataRepositoryDisplaySubtitleFunc' + [formGroup]="formGroup.get('dataRepositories')" [autoCompleteConfiguration]="dataRepositoriesAutoCompleteConfiguration" + (onItemChange)="dataRepositoriesOnItemChange($event)"> @@ -86,8 +83,9 @@ + [parentTemplate]='externalDatasetsTemplate' [displayFunction]='externalDatasetDisplayFunc' [subtitleFunction]='dataRepositoryDisplaySubtitleFunc' + [formGroup]="formGroup.get('externalDatasets')" [autoCompleteConfiguration]="externalDatasetAutoCompleteConfiguration" + (onItemChange)="externalDatasetsOnItemChange($event)"> @@ -128,7 +126,8 @@ + [formGroup]="formGroup.get('registries')" [subtitleFunction]='dataRepositoryDisplaySubtitleFunc' [autoCompleteConfiguration]="registriesAutoCompleteConfiguration" + (onItemChange)="registriesOnItemChange($event)"> @@ -154,7 +153,8 @@ + [formGroup]="formGroup.get('services')" [subtitleFunction]='dataRepositoryDisplaySubtitleFunc' [autoCompleteConfiguration]="servicesAutoCompleteConfiguration" + (onItemChange)="servicesOnItemChange($event)"> @@ -172,6 +172,33 @@ + + + + {{'DATASET-EDITOR.FIELDS.TAG' | translate}} + + + + + + + +
+

+ {{i+1}}) {{suggestion.get('name').value}} +

+
+
+ +
+
+
+ diff --git a/dmp-frontend/src/app/dmps/editor/dmp-editor.component.ts b/dmp-frontend/src/app/dmps/editor/dmp-editor.component.ts index bd21fc334..6f841e67a 100644 --- a/dmp-frontend/src/app/dmps/editor/dmp-editor.component.ts +++ b/dmp-frontend/src/app/dmps/editor/dmp-editor.component.ts @@ -154,7 +154,6 @@ export class DataManagementPlanEditorComponent implements AfterViewInit, IBreadC this.snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: this.isNew ? 'GENERAL.SNACK-BAR.SUCCESSFUL-CREATION' : 'GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE', language: this.language }, duration: 3000, - extraClasses: ['snackbar-success'] }) this.router.navigate(['/dmps']); } diff --git a/dmp-frontend/src/app/dmps/wizard/dmp-wizard.component.html b/dmp-frontend/src/app/dmps/wizard/dmp-wizard.component.html index f31392977..93ec8b314 100644 --- a/dmp-frontend/src/app/dmps/wizard/dmp-wizard.component.html +++ b/dmp-frontend/src/app/dmps/wizard/dmp-wizard.component.html @@ -1,19 +1,19 @@
- - - {{'DMP-WIZARD.FIRST-STEP.DMP' | translate}} - - - - - {{'DMP-WIZARD.FIRST-STEP.DATASETS' | translate}} - - - - -
\ No newline at end of file + + + {{'DMP-WIZARD.FIRST-STEP.DMP' | translate}} + + + + + {{'DMP-WIZARD.FIRST-STEP.DATASETS' | translate}} + + + + +
diff --git a/dmp-frontend/src/app/dmps/wizard/dmp-wizard.component.ts b/dmp-frontend/src/app/dmps/wizard/dmp-wizard.component.ts index 46a6a0b42..2b2b8cc42 100644 --- a/dmp-frontend/src/app/dmps/wizard/dmp-wizard.component.ts +++ b/dmp-frontend/src/app/dmps/wizard/dmp-wizard.component.ts @@ -26,10 +26,10 @@ export class DataManagementPlanWizardComponent implements OnInit, IBreadCrumbCom private router: Router ) { } - itemId: string - dataManagementPlan: DataManagementPlanModel; - formGroup: FormGroup - isClone: boolean + public itemId: string + public dataManagementPlan: DataManagementPlanModel; + public formGroup: FormGroup + public isClone: boolean ngOnInit(): void { @@ -65,7 +65,6 @@ export class DataManagementPlanWizardComponent implements OnInit, IBreadCrumbCom this.snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE', language: this.language }, duration: 3000, - extraClasses: ['snackbar-success'] }) this.router.navigate(['/dmps']); } diff --git a/dmp-frontend/src/app/dmps/wizard/editor/dmp-wizard-editor.component.ts b/dmp-frontend/src/app/dmps/wizard/editor/dmp-wizard-editor.component.ts index 4fb6774e9..d33be39f3 100644 --- a/dmp-frontend/src/app/dmps/wizard/editor/dmp-wizard-editor.component.ts +++ b/dmp-frontend/src/app/dmps/wizard/editor/dmp-wizard-editor.component.ts @@ -100,7 +100,6 @@ export class DataManagementPlanWizardEditorComponent implements AfterViewInit { this.snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: this.isNew ? 'GENERAL.SNACK-BAR.SUCCESSFUL-CREATION' : 'GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE', language: this.language }, duration: 3000, - extraClasses: ['snackbar-success'] }) this.router.navigate(['/dmps']); } diff --git a/dmp-frontend/src/app/form/dynamic-fields/dynamic-field-autocomplete/autocomplete-remote.component.ts b/dmp-frontend/src/app/form/dynamic-fields/dynamic-field-autocomplete/autocomplete-remote.component.ts index 30a17d46f..9b097916d 100644 --- a/dmp-frontend/src/app/form/dynamic-fields/dynamic-field-autocomplete/autocomplete-remote.component.ts +++ b/dmp-frontend/src/app/form/dynamic-fields/dynamic-field-autocomplete/autocomplete-remote.component.ts @@ -23,11 +23,11 @@ export class AutocompleteRemoteComponent implements OnInit/* , ControlValueAcces @Input() disabled = false @Input() form: FormGroup; - private autoCompleteConfiguration: AutoCompleteConfiguration; - private loading: boolean; - private datasetId; - values: any[] = new Array(); - typeaheadMS: number = 1400; + public autoCompleteConfiguration: AutoCompleteConfiguration; + public loading: boolean; + public datasetId; + public values: any[] = new Array(); + public typeaheadMS: number = 1400; constructor(private datasetProfileService: DatasetProfileService, route: ActivatedRoute) { this.datasetId = route.snapshot.params['id']; diff --git a/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.html b/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.html index ddfc08b4e..7e5d6a7c1 100644 --- a/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.html +++ b/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.html @@ -11,8 +11,8 @@
- - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
@@ -33,11 +33,12 @@
- + - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + close + + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
@@ -55,7 +56,7 @@ @@ -79,13 +80,13 @@ - + -
- +
+
{{field.label}} is required
@@ -98,7 +99,7 @@ \ No newline at end of file + +
--> diff --git a/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.ts b/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.ts index b9befd157..84e06aa22 100644 --- a/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.ts +++ b/dmp-frontend/src/app/form/dynamic-fields/dynamic-form-field.component.ts @@ -21,7 +21,7 @@ export class DynamicFormFieldComponent implements OnInit { @Input() pathName: string; @Input() path: string; - constructor(private route: ActivatedRoute, private visibilityRulesService: VisibilityRulesService) { } + constructor(private route: ActivatedRoute, public visibilityRulesService: VisibilityRulesService) { } ngOnInit() { this.form.get('value').valueChanges.subscribe(item => { diff --git a/dmp-frontend/src/app/form/dynamic-form-group/dynamic-form-group.component.ts b/dmp-frontend/src/app/form/dynamic-form-group/dynamic-form-group.component.ts index 4e0c0e301..e837706a9 100644 --- a/dmp-frontend/src/app/form/dynamic-form-group/dynamic-form-group.component.ts +++ b/dmp-frontend/src/app/form/dynamic-form-group/dynamic-form-group.component.ts @@ -21,7 +21,7 @@ export class DynamicFormGroupComponent implements OnInit { @Input() path: string; - constructor(private visibilityRulesService: VisibilityRulesService) { + constructor(public visibilityRulesService: VisibilityRulesService) { } ngOnInit() { diff --git a/dmp-frontend/src/app/form/dynamic-form-section/dynamic-form-section.ts b/dmp-frontend/src/app/form/dynamic-form-section/dynamic-form-section.ts index f3075af11..f04828950 100644 --- a/dmp-frontend/src/app/form/dynamic-form-section/dynamic-form-section.ts +++ b/dmp-frontend/src/app/form/dynamic-form-section/dynamic-form-section.ts @@ -19,7 +19,7 @@ export class DynamicFormSectionComponent implements OnInit { @Input() form: FormGroup; @Input() pathName: string; @Input() path: string; - constructor(private visibilityRulesService: VisibilityRulesService) { } + constructor(public visibilityRulesService: VisibilityRulesService) { } ngOnInit() { } diff --git a/dmp-frontend/src/app/form/pprogress-bar/progress-bar.component.html b/dmp-frontend/src/app/form/pprogress-bar/progress-bar.component.html index 07b6bc6d6..bd0007c86 100644 --- a/dmp-frontend/src/app/form/pprogress-bar/progress-bar.component.html +++ b/dmp-frontend/src/app/form/pprogress-bar/progress-bar.component.html @@ -1,5 +1,5 @@ 
- -
\ No newline at end of file + +
diff --git a/dmp-frontend/src/app/form/pprogress-bar/progress-bar.component.ts b/dmp-frontend/src/app/form/pprogress-bar/progress-bar.component.ts index 752fe6d5c..cb4ca2f2e 100644 --- a/dmp-frontend/src/app/form/pprogress-bar/progress-bar.component.ts +++ b/dmp-frontend/src/app/form/pprogress-bar/progress-bar.component.ts @@ -16,7 +16,7 @@ export class ProgressBarComponent implements OnInit { constructor(private visibilityRulesService: VisibilityRulesService) { } - private value: number = 0; + public value: number = 0; ngOnInit() { this.calculateValueForProgressbar() this.formGroup diff --git a/dmp-frontend/src/app/form/tableOfContents/table-of-contents.component.html b/dmp-frontend/src/app/form/tableOfContents/table-of-contents.component.html index 78fa65451..7fb7c520d 100644 --- a/dmp-frontend/src/app/form/tableOfContents/table-of-contents.component.html +++ b/dmp-frontend/src/app/form/tableOfContents/table-of-contents.component.html @@ -1,7 +1,7 @@
    -
  • - - -
  • -
\ No newline at end of file +
  • + + +
  • + diff --git a/dmp-frontend/src/app/form/tableOfContents/table-of-contents.component.ts b/dmp-frontend/src/app/form/tableOfContents/table-of-contents.component.ts index 8ba7249db..aa06c3338 100644 --- a/dmp-frontend/src/app/form/tableOfContents/table-of-contents.component.ts +++ b/dmp-frontend/src/app/form/tableOfContents/table-of-contents.component.ts @@ -9,17 +9,18 @@ import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; selector: 'table-of-content', templateUrl: './table-of-contents.component.html', styleUrls: ['./toc.component.css'], - providers: [] + providers: [] }) -export class TableOfContentsComponent implements OnInit{ +export class TableOfContentsComponent implements OnInit { - @Input() model:DatasetProfileDefinitionModel; - public path:string=""; + @Input() + public model: DatasetProfileDefinitionModel; + public path: string = ""; /* @Output() setPage:EventEmitter = new EventEmitter(); - */ ngOnInit(){ + */ ngOnInit() { - } + } -} \ No newline at end of file +} diff --git a/dmp-frontend/src/app/homepage/homepage.component.ts b/dmp-frontend/src/app/homepage/homepage.component.ts index 80d08027c..f8835c0bc 100644 --- a/dmp-frontend/src/app/homepage/homepage.component.ts +++ b/dmp-frontend/src/app/homepage/homepage.component.ts @@ -12,8 +12,8 @@ import { AuthService } from '../services/auth/auth.service'; }) export class HomepageComponent implements OnInit { - private userInfo: any; - private dashboardStatisticsData: DashboardStatisticsModel = new DashboardStatisticsModel(); + public userInfo: any; + public dashboardStatisticsData: DashboardStatisticsModel = new DashboardStatisticsModel(); constructor( private route: ActivatedRoute, diff --git a/dmp-frontend/src/app/models/criteria/dataset/DatasetCriteria.ts b/dmp-frontend/src/app/models/criteria/dataset/DatasetCriteria.ts index b6e00caec..5a0be0fbe 100644 --- a/dmp-frontend/src/app/models/criteria/dataset/DatasetCriteria.ts +++ b/dmp-frontend/src/app/models/criteria/dataset/DatasetCriteria.ts @@ -1,7 +1,9 @@ import { BaseCriteria } from "../BaseCriteria"; +import { ExternalSourcesItemModel } from "../../external-sources/ExternalSourcesItemModel"; export class DatasetCriteria extends BaseCriteria { - public status: Number; - public dmpIds: String[] = []; - public allVersions: boolean; + public status: Number; + public dmpIds: String[] = []; + public tags: ExternalSourcesItemModel[] = []; + public allVersions: boolean; } diff --git a/dmp-frontend/src/app/models/criteria/tags/TagsCriteria.ts b/dmp-frontend/src/app/models/criteria/tags/TagsCriteria.ts new file mode 100644 index 000000000..59616dd88 --- /dev/null +++ b/dmp-frontend/src/app/models/criteria/tags/TagsCriteria.ts @@ -0,0 +1,6 @@ +import { BaseCriteria } from "../BaseCriteria"; +import { ExternalSourcesItemModel } from "../../external-sources/ExternalSourcesItemModel"; + +export class TagsCriteria extends BaseCriteria { + public type: string; +} diff --git a/dmp-frontend/src/app/models/datasets/DatasetWizardModel.ts b/dmp-frontend/src/app/models/datasets/DatasetWizardModel.ts index 2ffb17721..229d0e5d7 100644 --- a/dmp-frontend/src/app/models/datasets/DatasetWizardModel.ts +++ b/dmp-frontend/src/app/models/datasets/DatasetWizardModel.ts @@ -12,6 +12,7 @@ import { JsonSerializer } from "../../utilities/JsonSerializer"; import { RegisterModel } from "../registers/RegisterModel"; import { DataRepositoryModel } from "../dataRepositories/DataRepositoryModel"; import { ExternalDatasetModel } from '../../models/external-dataset/ExternalDatasetModel'; +import { TagModel } from '../tags/TagModel'; export class DatasetWizardModel implements Serializable { public id: string; @@ -23,6 +24,7 @@ export class DatasetWizardModel implements Serializable { public services: ServiceModel[] = []; public registries: RegisterModel[] = []; public dataRepositories: DataRepositoryModel[] = []; + public tags: TagModel[] = []; public externalDatasets: ExternalDatasetModel[] = []; public dmp: DataManagementPlanModel = new DataManagementPlanModel(); public datasetProfileDefinition; @@ -42,6 +44,7 @@ export class DatasetWizardModel implements Serializable { this.profile = JsonSerializer.fromJSONObject(item.profile, DatasetProfileModel); this.externalDatasets = JsonSerializer.fromJSONArray(item.externalDatasets, ExternalDatasetModel); this.datasetProfileDefinition = JsonSerializer.fromJSONObject(item.datasetProfileDefinition, DatasetProfileDefinitionModel); + this.tags = JsonSerializer.fromJSONArray(item.tags, TagModel); return this; } @@ -54,7 +57,7 @@ export class DatasetWizardModel implements Serializable { uri: [{ value: this.uri, disabled: disabled }, context.getValidation('uri').validators], status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators], description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators], - dmp: [{ value: this.dmp, disabled: disabled }, context.getValidation('dmp').validators] + dmp: [{ value: this.dmp, disabled: disabled }, context.getValidation('dmp').validators], }); const externalDatasetsFormArray = new Array(); @@ -67,6 +70,16 @@ export class DatasetWizardModel implements Serializable { } formGroup.addControl('externalDatasets', formBuilder.array(externalDatasetsFormArray)); + const tagsFormArray = new Array(); + if (this.tags && this.tags.length > 0) { + this.tags.forEach(item => { + tagsFormArray.push(item.buildForm(context.getValidation('tags').descendantValidations, disabled)) + }) + } else { + //externalDatasetsFormArray.push(new ExternalDatasetModel().buildForm(context.getValidation('externalDatasets').descendantValidations, disabled)); + } + formGroup.addControl('tags', formBuilder.array(tagsFormArray)); + const registriesFormArray = new Array(); if (this.registries && this.registries.length > 0) { this.registries.forEach(item => { @@ -116,6 +129,7 @@ export class DatasetWizardModel implements Serializable { baseContext.validation.push({ key: 'externalDatasets', validators: [BackendErrorValidator(this.errorModel, 'externalDatasets')] }); baseContext.validation.push({ key: 'dmp', validators: [BackendErrorValidator(this.errorModel, 'dmp')] }); //TODO baseContext.validation.push({ key: 'datasetProfileDefinition', validators: [BackendErrorValidator(this.errorModel, 'datasetProfileDefinition')] }); //TODO + baseContext.validation.push({ key: 'tags', validators: [BackendErrorValidator(this.errorModel, 'datasetProfileDefinition')] }); //TODO return baseContext; } diff --git a/dmp-frontend/src/app/models/external-sources/ExternalSourcesConfiguration.ts b/dmp-frontend/src/app/models/external-sources/ExternalSourcesConfiguration.ts index 25c0a5d03..7b3ea11f2 100644 --- a/dmp-frontend/src/app/models/external-sources/ExternalSourcesConfiguration.ts +++ b/dmp-frontend/src/app/models/external-sources/ExternalSourcesConfiguration.ts @@ -1,8 +1,9 @@ import { ExternalSourcesUrlModel } from "./ExternalSourcesUrlModel"; export class ExternalSourcesConfiguration { - public registries: Array - public dataRepositories: Array - public services: Array - public externalDatasets: Array -} \ No newline at end of file + public registries: Array + public dataRepositories: Array + public services: Array + public externalDatasets: Array + public tags: Array +} diff --git a/dmp-frontend/src/app/models/tags/TagModel.ts b/dmp-frontend/src/app/models/tags/TagModel.ts new file mode 100644 index 000000000..da3e6fbdc --- /dev/null +++ b/dmp-frontend/src/app/models/tags/TagModel.ts @@ -0,0 +1,27 @@ +import { Serializable } from "../Serializable"; +import { ValidationContext } from "../../utilities/validators/ValidationContext"; +import { FormGroup, FormBuilder } from "@angular/forms"; + +export class TagModel implements Serializable { + + public id: string; + public name: string; + + constructor(id?: string, name?: string) { + this.id = id; + this.name = name; + } + + fromJSONObject(item: any): TagModel { + this.id = item.id; + this.name = item.name; + return this; + } + + buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup { + return new FormBuilder().group({ + id: [this.id], + name: [this.name] + }) + } +} diff --git a/dmp-frontend/src/app/projects/editor/project-editor.component.ts b/dmp-frontend/src/app/projects/editor/project-editor.component.ts index b68ca8f37..751060307 100644 --- a/dmp-frontend/src/app/projects/editor/project-editor.component.ts +++ b/dmp-frontend/src/app/projects/editor/project-editor.component.ts @@ -93,7 +93,6 @@ export class ProjectEditorComponent implements OnInit, IBreadCrumbComponent { this.snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: this.isNew ? 'GENERAL.SNACK-BAR.SUCCESSFUL-CREATION' : 'GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE', language: this.language }, duration: 3000, - extraClasses: ['snackbar-success'] }) this.router.navigate(['/projects']); } diff --git a/dmp-frontend/src/app/projects/listing/project-listing.component.ts b/dmp-frontend/src/app/projects/listing/project-listing.component.ts index cadef224c..68f5e2058 100644 --- a/dmp-frontend/src/app/projects/listing/project-listing.component.ts +++ b/dmp-frontend/src/app/projects/listing/project-listing.component.ts @@ -34,11 +34,11 @@ export class ProjectListingComponent implements OnInit, IBreadCrumbComponent { displayedColumns: String[] = ['avatar', 'name', 'abbreviation', 'start', 'end', "dmps"]; constructor( - private projectService: ProjectService, - private router: Router, - private languageService: TranslateService, + public projectService: ProjectService, + public router: Router, + public languageService: TranslateService, public snackBar: MatSnackBar, - private languageResolverService: LanguageResolverService + public languageResolverService: LanguageResolverService ) { } diff --git a/dmp-frontend/src/app/services/auth/auth.service.ts b/dmp-frontend/src/app/services/auth/auth.service.ts index 6d6561dbf..ab52c0f5f 100644 --- a/dmp-frontend/src/app/services/auth/auth.service.ts +++ b/dmp-frontend/src/app/services/auth/auth.service.ts @@ -133,7 +133,6 @@ export class AuthService { this.snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-LOGOUT', language: this.language }, duration: 3000, - extraClasses: ['snackbar-success'] }) this.router.navigate(['/login']); } @@ -142,7 +141,6 @@ export class AuthService { this.snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: 'GENERAL.SNACK-BAR.UNSUCCESSFUL-LOGOUT', language: this.language }, duration: 3000, - extraClasses: ['snackbar-warning'] }) this.router.navigate(['/login']); } diff --git a/dmp-frontend/src/app/services/external-sources/external-sources.service.ts b/dmp-frontend/src/app/services/external-sources/external-sources.service.ts index 569aa5487..1b8e12523 100644 --- a/dmp-frontend/src/app/services/external-sources/external-sources.service.ts +++ b/dmp-frontend/src/app/services/external-sources/external-sources.service.ts @@ -12,6 +12,7 @@ import { ExternalDatasetCriteria } from '../../models/criteria/external-dataset/ import { RegistryCriteria } from '../../models/criteria/registry/RegistryCriteria'; import { DataRepositoryCriteria } from '../../models/criteria/data-repository/DataRepositoryCriteria'; import { ServicesCriteria } from '../../models/criteria/services/ServicesCriteria'; +import { TagsCriteria } from '../../models/criteria/tags/TagsCriteria'; @Injectable() @@ -41,6 +42,20 @@ export class ExternalSourcesService { return this.http.get(this.actionUrl + "services" + "?query=" + requestItem.criteria.like + "&type=" + requestItem.criteria.type, { headers: this.headers }); } + public searchDatasetTags(requestItem: RequestItem): Observable { + return Observable.of([ + { id: "1", name: "Tag 1", description: "" }, + { id: "2", name: "Tag 2", description: "" }, + { id: "3", name: "Tag 3", description: "" }, + { id: "4", name: "Tag 4", description: "" }, + { id: "5", name: "Tag 5", description: "" }, + { id: "6", name: "Tag 6", description: "" }, + { id: "7", name: "Tag 7", description: "" }, + { id: "8", name: "Tag 8", description: "" }, + ]) + //return this.http.get(this.actionUrl + "tags" + "?query=" + requestItem.criteria.like + "&type=" + requestItem.criteria.type, { headers: this.headers }); + } + public searchDatasetSExternalDatasetservice(requestItem: RequestItem): Observable { return this.http.get(this.actionUrl + "datasets" + "?query=" + requestItem.criteria.like + "&type=" + requestItem.criteria.type, { headers: this.headers }); } diff --git a/dmp-frontend/src/app/shared/components/add-researchers/add-researchers.component.ts b/dmp-frontend/src/app/shared/components/add-researchers/add-researchers.component.ts index db1332d83..bbb50bf56 100644 --- a/dmp-frontend/src/app/shared/components/add-researchers/add-researchers.component.ts +++ b/dmp-frontend/src/app/shared/components/add-researchers/add-researchers.component.ts @@ -14,7 +14,7 @@ import { ResearcherService } from '../../../services/researchers/researchers.ser }) export class AddResearchersComponent implements OnInit { - private formGroup: FormGroup; + public formGroup: FormGroup; constructor( private researcherService: ResearcherService, diff --git a/dmp-frontend/src/app/shared/components/auto-complete/auto-complete.component.html b/dmp-frontend/src/app/shared/components/auto-complete/auto-complete.component.html index 8f255846f..2fbdd576c 100644 --- a/dmp-frontend/src/app/shared/components/auto-complete/auto-complete.component.html +++ b/dmp-frontend/src/app/shared/components/auto-complete/auto-complete.component.html @@ -7,7 +7,9 @@ - {{ this.printText(option) }} + {{ this.printText(option) }} | + {{subtitleFn(option)}} + diff --git a/dmp-frontend/src/app/shared/components/auto-complete/auto-complete.component.ts b/dmp-frontend/src/app/shared/components/auto-complete/auto-complete.component.ts index 9d83979f4..ce290362c 100644 --- a/dmp-frontend/src/app/shared/components/auto-complete/auto-complete.component.ts +++ b/dmp-frontend/src/app/shared/components/auto-complete/auto-complete.component.ts @@ -17,6 +17,8 @@ export class AutoCompleteComponent implements OnInit, ErrorStateMatcher { @Input() formCtrl: FormControl; @Input() required = false; @Input() displayFunction: Function; + @Input() _subtitleFn: Function; + @Input() assignValueFunction: Function; @Input() transformFunction: Function; @Input() inputData: AutoCompleteConfiguration; @@ -86,6 +88,10 @@ export class AutoCompleteComponent implements OnInit, ErrorStateMatcher { else return item; } + subtitleFn(item) { + return this._subtitleFn(item); + } + getValue(item: any): string { if (this.assignValueFunction) { if (this.transformFunction) return this.assignValueFunction(this.transformFunction(item)) diff --git a/dmp-frontend/src/app/shared/components/autocomplete/autocomplete.component.html b/dmp-frontend/src/app/shared/components/autocomplete/autocomplete.component.html index 9cfb0053d..4e0da5da7 100644 --- a/dmp-frontend/src/app/shared/components/autocomplete/autocomplete.component.html +++ b/dmp-frontend/src/app/shared/components/autocomplete/autocomplete.component.html @@ -25,17 +25,16 @@ --> - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - {{errorString}} - - - - {{item[titleKey]}} - {{item[subtitleKey]}} - - - - \ No newline at end of file + + diff --git a/dmp-frontend/src/app/shared/components/autocompleteChips/autocompleteChips.component.html b/dmp-frontend/src/app/shared/components/autocompleteChips/autocompleteChips.component.html index 8803aa35e..45084b772 100644 --- a/dmp-frontend/src/app/shared/components/autocompleteChips/autocompleteChips.component.html +++ b/dmp-frontend/src/app/shared/components/autocompleteChips/autocompleteChips.component.html @@ -1,22 +1,21 @@ - - - {{item.name}} - cancel - - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - {{errorString}} - - - - {{item[titleKey]}} - {{item[subtitleKey]}} - - - - \ No newline at end of file + + diff --git a/dmp-frontend/src/app/shared/components/available-profiles/available-profiles.component.ts b/dmp-frontend/src/app/shared/components/available-profiles/available-profiles.component.ts index 4c1fd5d2d..f89671c10 100644 --- a/dmp-frontend/src/app/shared/components/available-profiles/available-profiles.component.ts +++ b/dmp-frontend/src/app/shared/components/available-profiles/available-profiles.component.ts @@ -15,9 +15,9 @@ import { DatasetProfileModule } from '../../../dataset-profile-form/dataset-prof }) export class AvailableProfilesComponent implements OnInit { - private formGroup: FormGroup; - private profiles: DatasetProfileModel[] = []; - private selectedProfiles: DatasetProfileModel[] = []; + public formGroup: FormGroup; + public profiles: DatasetProfileModel[] = []; + public selectedProfiles: DatasetProfileModel[] = []; constructor( private datasetService: DatasetService, diff --git a/dmp-frontend/src/app/shared/components/breadcrumb/breadcrumb.component.html b/dmp-frontend/src/app/shared/components/breadcrumb/breadcrumb.component.html index 21affeb1f..b5370168f 100644 --- a/dmp-frontend/src/app/shared/components/breadcrumb/breadcrumb.component.html +++ b/dmp-frontend/src/app/shared/components/breadcrumb/breadcrumb.component.html @@ -2,13 +2,13 @@
      -
      -
    1. - +
      +
    2. + {{ breadcrumb.label }}
    3. - chevron_right + chevron_right
    diff --git a/dmp-frontend/src/app/shared/components/criteria/base/base-criteria.component.ts b/dmp-frontend/src/app/shared/components/criteria/base/base-criteria.component.ts index ca7a24d35..4b187e1d1 100644 --- a/dmp-frontend/src/app/shared/components/criteria/base/base-criteria.component.ts +++ b/dmp-frontend/src/app/shared/components/criteria/base/base-criteria.component.ts @@ -3,100 +3,100 @@ import { FormControl, FormGroup, NgForm, FormArray, AbstractControl } from '@ang import { BaseCriteriaErrorModel } from '../../../../models/criteria/BaseCriteriaErrorModel'; @Component({ - selector: 'base-criteria-component', - template: '', - providers: [ + selector: 'base-criteria-component', + template: '', + providers: [ - ] + ] }) export class BaseCriteriaComponent implements OnInit { - public refreshCallback: Function = null; - public formGroup: FormGroup = null; - - constructor( - public baseErrorModel?: BaseCriteriaErrorModel, - ) { - } - - ngOnInit() { - if (this.baseErrorModel == null) { this.baseErrorModel = new BaseCriteriaErrorModel(); } - } - - controlModified(): void { - this.clearErrorModel(); - if (!this.isFormValid()) { return; } - if (this.refreshCallback != null) { this.refreshCallback(); } - } - - public isFormValid(): boolean { - this.touchAllFormFields(this.formGroup); - this.validateAllFormFields(this.formGroup); - return this.formGroup.valid; - } - - public getFormData(): any { - return this.formGroup.value; - } - - public getFormControl(controlName: string): AbstractControl { - return this.formGroup.get(controlName); - } - - public disableFormFields(formControl: AbstractControl) { - formControl.disable(); - } - - public validateAllFormFields(formControl: AbstractControl) { - if (formControl instanceof FormControl) { - formControl.updateValueAndValidity({ emitEvent: false }) - } else if (formControl instanceof FormGroup) { - Object.keys(formControl.controls).forEach(item => { - const control = formControl.get(item); - this.validateAllFormFields(control); - }) - } else if (formControl instanceof FormArray) { - formControl.controls.forEach(item => { - this.validateAllFormFields(item); - }) - } - } - - public touchAllFormFields(formControl: AbstractControl) { - if (formControl instanceof FormControl) { - formControl.markAsTouched(); - } else if (formControl instanceof FormGroup) { - Object.keys(formControl.controls).forEach(item => { - const control = formControl.get(item); - this.touchAllFormFields(control); - }) - } else if (formControl instanceof FormArray) { - formControl.controls.forEach(item => { - this.touchAllFormFields(item); - }) - } - } - - setRefreshCallback(callback: Function): void { - this.refreshCallback = callback; - } - - onCallbackError(error: any) { - this.setErrorModel(error.error); - this.validateAllFormFields(this.formGroup); - } - - public setErrorModel(errorModel: BaseCriteriaErrorModel) { - Object.keys(errorModel).forEach(item => { - (this.baseErrorModel)[item] = (errorModel)[item]; - }) - } - - public clearErrorModel() { - Object.keys(this.baseErrorModel).forEach(item => { - (this.baseErrorModel)[item] = ''; - }) - } + public refreshCallback: Function = null; + public formGroup: FormGroup = null; + + constructor( + public baseErrorModel?: BaseCriteriaErrorModel, + ) { + } + + ngOnInit() { + if (this.baseErrorModel == null) { this.baseErrorModel = new BaseCriteriaErrorModel(); } + } + + controlModified(): void { + this.clearErrorModel(); + if (!this.isFormValid()) { return; } + if (this.refreshCallback != null) { this.refreshCallback(); } + } + + public isFormValid(): boolean { + this.touchAllFormFields(this.formGroup); + this.validateAllFormFields(this.formGroup); + return this.formGroup.valid; + } + + public getFormData(): any { + return this.formGroup.value; + } + + public getFormControl(controlName: string): AbstractControl { + return this.formGroup.get(controlName); + } + + public disableFormFields(formControl: AbstractControl) { + formControl.disable(); + } + + public validateAllFormFields(formControl: AbstractControl) { + if (formControl instanceof FormControl) { + formControl.updateValueAndValidity({ emitEvent: false }) + } else if (formControl instanceof FormGroup) { + Object.keys(formControl.controls).forEach(item => { + const control = formControl.get(item); + this.validateAllFormFields(control); + }) + } else if (formControl instanceof FormArray) { + formControl.controls.forEach(item => { + this.validateAllFormFields(item); + }) + } + } + + public touchAllFormFields(formControl: AbstractControl) { + if (formControl instanceof FormControl) { + formControl.markAsTouched(); + } else if (formControl instanceof FormGroup) { + Object.keys(formControl.controls).forEach(item => { + const control = formControl.get(item); + this.touchAllFormFields(control); + }) + } else if (formControl instanceof FormArray) { + formControl.controls.forEach(item => { + this.touchAllFormFields(item); + }) + } + } + + setRefreshCallback(callback: Function): void { + this.refreshCallback = callback; + } + + onCallbackError(error: any) { + this.setErrorModel(error.error); + this.validateAllFormFields(this.formGroup); + } + + public setErrorModel(errorModel: BaseCriteriaErrorModel) { + Object.keys(errorModel).forEach(item => { + (this.baseErrorModel)[item] = (errorModel)[item]; + }) + } + + public clearErrorModel() { + Object.keys(this.baseErrorModel).forEach(item => { + (this.baseErrorModel)[item] = ''; + }) + } } diff --git a/dmp-frontend/src/app/shared/components/criteria/data-management-plan/dmp-criteria.component.ts b/dmp-frontend/src/app/shared/components/criteria/data-management-plan/dmp-criteria.component.ts index 447982c27..b4a21b435 100644 --- a/dmp-frontend/src/app/shared/components/criteria/data-management-plan/dmp-criteria.component.ts +++ b/dmp-frontend/src/app/shared/components/criteria/data-management-plan/dmp-criteria.component.ts @@ -68,12 +68,7 @@ export class DataManagementPlanCriteriaComponent extends BaseCriteriaComponent i requestItem.criteria = criteria; this.projectService.get(requestItem).subscribe(items => { this.filteredProjects = items; - this.filteringProjectsAsync = false; - - // this.filteredProjects = items.filter((filteredObj: any) => { - // return this.objectsModel ? this.objectsModel.indexOf(filteredObj) < 0 : true; - // }); - + this.filteringProjectsAsync = false; }); } } diff --git a/dmp-frontend/src/app/shared/components/criteria/datasets/datasets-criteria.component.html b/dmp-frontend/src/app/shared/components/criteria/datasets/datasets-criteria.component.html index 87ec2c7d8..fb17aad1a 100644 --- a/dmp-frontend/src/app/shared/components/criteria/datasets/datasets-criteria.component.html +++ b/dmp-frontend/src/app/shared/components/criteria/datasets/datasets-criteria.component.html @@ -20,14 +20,14 @@ --> -
    +
    - {{baseErrorModel['Criteria.like']}} + {{baseErrorModel['Criteria.like']}}
    -
    +
    @@ -35,9 +35,24 @@ {{status.viewValue}} - {{baseErrorModel['Criteria.status']}} + {{baseErrorModel['Criteria.status']}}
    +
    + + +
    {{chip.name.substring(0, 1).toUpperCase()}}
    + {{chip.name}} +
    + +
    + {{option.name}} +
    +
    + +
    +
    diff --git a/dmp-frontend/src/app/shared/components/criteria/datasets/datasets-criteria.component.ts b/dmp-frontend/src/app/shared/components/criteria/datasets/datasets-criteria.component.ts index f25300251..f1e8adf93 100644 --- a/dmp-frontend/src/app/shared/components/criteria/datasets/datasets-criteria.component.ts +++ b/dmp-frontend/src/app/shared/components/criteria/datasets/datasets-criteria.component.ts @@ -6,52 +6,78 @@ import { ValidationContext, Validation } from '../../../../utilities/validators/ import { BackendErrorValidator } from '../../../../utilities/validators/BackendErrorValidator'; import { DatasetCriteriaErrorModel } from '../../../../models/criteria/dataset/DatasetCriteriaErrorModel'; import { DatasetCriteria } from '../../../../models/criteria/dataset/DatasetCriteria'; +import { TagsCriteria } from '../../../../models/criteria/tags/TagsCriteria'; +import { ExternalSourcesService } from '../../../../services/external-sources/external-sources.service'; +import { RequestItem } from '../../../../models/criteria/RequestItem'; +import { TagModel } from '../../../../models/tags/TagModel'; +import { ExternalSourcesItemModel } from '../../../../models/external-sources/ExternalSourcesItemModel'; @Component({ - selector: 'app-datasets-criteria-component', - templateUrl: './datasets-criteria.component.html', - styleUrls: ['./datasets-criteria.component.scss'], - providers: [ - ] + selector: 'app-datasets-criteria-component', + templateUrl: './datasets-criteria.component.html', + styleUrls: ['./datasets-criteria.component.scss'], + providers: [ + ExternalSourcesService + ] }) export class DatasetCriteriaComponent extends BaseCriteriaComponent implements OnInit { - // public form: ProjectType; - // public formStatus: ProjectStatus; - public criteria: DatasetCriteria= new DatasetCriteria(); - - statuses = [ - {value: '0', viewValue: 'Saved'}, - {value: '1', viewValue: 'Finalised'} - ]; - - constructor( - public language: TranslateService, - public formBuilder: FormBuilder - ) { - super(new DatasetCriteriaErrorModel()); - } - - ngOnInit() { - super.ngOnInit(); - if (this.criteria == null) { this.criteria = new DatasetCriteria(); } - } - - setCriteria(criteria: DatasetCriteria): void { - this.criteria = criteria; - } - - onCallbackError(error: any) { - this.setErrorModel(error.error); - } - - controlModified(): void { - this.clearErrorModel(); - if (this.refreshCallback != null && - (this.criteria.like == null || this.criteria.like.length == 0 || this.criteria.like.length > 2) - ) { - this.refreshCallback(); - } - } + // public form: ProjectType; + // public formStatus: ProjectStatus; + public criteria: DatasetCriteria = new DatasetCriteria(); + public filteringTagsAsync: boolean = false; + public filteredTags: ExternalSourcesItemModel[]; + + statuses = [ + { value: '0', viewValue: 'Saved' }, + { value: '1', viewValue: 'Finalised' } + ]; + + constructor( + public language: TranslateService, + public formBuilder: FormBuilder, + public externalSourcesService: ExternalSourcesService + ) { + super(new DatasetCriteriaErrorModel()); + } + + ngOnInit() { + super.ngOnInit(); + if (this.criteria == null) { this.criteria = new DatasetCriteria(); } + } + + setCriteria(criteria: DatasetCriteria): void { + this.criteria = criteria; + } + + onCallbackError(error: any) { + this.setErrorModel(error.error); + } + + controlModified(): void { + this.clearErrorModel(); + if (this.refreshCallback != null && + (this.criteria.like == null || this.criteria.like.length == 0 || this.criteria.like.length > 2) + ) { + this.refreshCallback(); + } + } + + filterTags(value: string): void { + + this.filteredTags = undefined; + if (value) { + this.filteringTagsAsync = true; + + let requestItem: RequestItem = new RequestItem(); + let criteria: TagsCriteria = new TagsCriteria(); + criteria.like = value; + requestItem.criteria = criteria; + this.externalSourcesService.searchDatasetTags(requestItem).subscribe(items => { + this.filteredTags = items; + this.filteringTagsAsync = false; + }); + } + } } diff --git a/dmp-frontend/src/app/shared/components/criteria/projects/projects-criteria.component.html b/dmp-frontend/src/app/shared/components/criteria/projects/projects-criteria.component.html index 351b0accd..6318a3670 100644 --- a/dmp-frontend/src/app/shared/components/criteria/projects/projects-criteria.component.html +++ b/dmp-frontend/src/app/shared/components/criteria/projects/projects-criteria.component.html @@ -27,7 +27,7 @@ - {{baseErrorModel['criteria.periodEnd']}} + {{baseErrorModel['criteria.periodEnd']}} diff --git a/dmp-frontend/src/app/shared/components/external-items/external-item-listing/external-item-listing.component.html b/dmp-frontend/src/app/shared/components/external-items/external-item-listing/external-item-listing.component.html index be040b9ce..1d14236cb 100644 --- a/dmp-frontend/src/app/shared/components/external-items/external-item-listing/external-item-listing.component.html +++ b/dmp-frontend/src/app/shared/components/external-items/external-item-listing/external-item-listing.component.html @@ -9,10 +9,11 @@ + [placeholder]="placeholder" [subtitleFunction]="subtitleFunction" (onItemChange)="this.onItemChangeFunc($event)" [formCtrl]="formControl" + [disabled]="disabled">
    -
    +
    diff --git a/dmp-frontend/src/app/shared/components/external-items/external-item-listing/external-item-listing.component.ts b/dmp-frontend/src/app/shared/components/external-items/external-item-listing/external-item-listing.component.ts index 9568aaa26..c79b4732e 100644 --- a/dmp-frontend/src/app/shared/components/external-items/external-item-listing/external-item-listing.component.ts +++ b/dmp-frontend/src/app/shared/components/external-items/external-item-listing/external-item-listing.component.ts @@ -21,6 +21,9 @@ export class ExternalItemListingComponent implements OnInit { @Input() public displayFunction: Function; + @Input() + public subtitleFunction: Function; + @Input() public disabled = true; diff --git a/dmp-frontend/src/app/shared/components/external-items/external-item/external-item.component.html b/dmp-frontend/src/app/shared/components/external-items/external-item/external-item.component.html index 18cb0553b..564a2d0bc 100644 --- a/dmp-frontend/src/app/shared/components/external-items/external-item/external-item.component.html +++ b/dmp-frontend/src/app/shared/components/external-items/external-item/external-item.component.html @@ -1,4 +1,4 @@ + titleKey="titleKey" [formCtrl]="formCtrl" [_subtitleFn]="subtitleFunction" [displayFunction]="displayFunction" [disabled]="disabled" + (onItemChange)="this.onItemChangeFunc($event)" [clear]="true" [required]="false"> diff --git a/dmp-frontend/src/app/shared/components/external-items/external-item/external-item.component.ts b/dmp-frontend/src/app/shared/components/external-items/external-item/external-item.component.ts index c463e8f36..363450d54 100644 --- a/dmp-frontend/src/app/shared/components/external-items/external-item/external-item.component.ts +++ b/dmp-frontend/src/app/shared/components/external-items/external-item/external-item.component.ts @@ -22,6 +22,9 @@ export class ExternalItemComponent implements OnInit { @Input() public displayFunction: Function; + @Input() + public subtitleFunction: Function; + @Input() public disabled = false; diff --git a/dmp-frontend/src/app/shared/components/file-uploader/file-uploader.component.html b/dmp-frontend/src/app/shared/components/file-uploader/file-uploader.component.html index ce536bf8e..5d9d21af0 100644 --- a/dmp-frontend/src/app/shared/components/file-uploader/file-uploader.component.html +++ b/dmp-frontend/src/app/shared/components/file-uploader/file-uploader.component.html @@ -1,11 +1,11 @@ - file_upload - {{ files?.name }} - - attach_file - - {{label | translate}} - - - \ No newline at end of file + (upload)="uploadEvent($event)" (cancel)="cancelEvent()" accept=".jpg,.png" [disabled]="disabled" multiple> + file_upload + {{ files['name'] }} + + attach_file + + {{label | translate}} + + + diff --git a/dmp-frontend/src/app/shared/components/invitation/invitation.component.ts b/dmp-frontend/src/app/shared/components/invitation/invitation.component.ts index 3eb679241..35b743f67 100644 --- a/dmp-frontend/src/app/shared/components/invitation/invitation.component.ts +++ b/dmp-frontend/src/app/shared/components/invitation/invitation.component.ts @@ -16,15 +16,15 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; }) export class InvitationComponent implements OnInit { - private formGroup: FormGroup; + public formGroup: FormGroup; - private filteredUsersAsync: boolean = false; + public filteredUsersAsync: boolean = false; - private filteredUsers: User[]; + public filteredUsers: User[]; constructor( - private invitationService: InvitationService, - private route: ActivatedRoute, + public invitationService: InvitationService, + public route: ActivatedRoute, public router: Router, public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any diff --git a/dmp-frontend/src/app/shared/components/navigation/navigation.component.html b/dmp-frontend/src/app/shared/components/navigation/navigation.component.html index 4bb2a086d..003ab15ad 100644 --- a/dmp-frontend/src/app/shared/components/navigation/navigation.component.html +++ b/dmp-frontend/src/app/shared/components/navigation/navigation.component.html @@ -16,9 +16,6 @@
    {{this.getPrincipalName()}} - diff --git a/dmp-frontend/src/app/shared/components/navigation/navigation.component.ts b/dmp-frontend/src/app/shared/components/navigation/navigation.component.ts index 16e3556a4..107b94530 100644 --- a/dmp-frontend/src/app/shared/components/navigation/navigation.component.ts +++ b/dmp-frontend/src/app/shared/components/navigation/navigation.component.ts @@ -1,8 +1,9 @@ import { sample } from 'rxjs/operators'; -import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Component, EventEmitter, Input, Output, ElementRef } from '@angular/core'; import { Principal } from '../../../models/login/Principal'; import { AuthService } from '../../../services/auth/auth.service'; import { LanguageResolverService } from '../../../services/language-resolver/language-resolver.service'; +import { MatSidenav } from '@angular/material'; @Component({ selector: 'app-navigation', @@ -26,7 +27,7 @@ export class NavigationComponent { } @Input() - sidenavOpen = false; + sideNav: MatSidenav; @Output() sidenavOpenChanges = new EventEmitter(); @@ -60,7 +61,6 @@ export class NavigationComponent { } onSideNavClick() { - this.sidenavOpen = !this.sidenavOpen; - this.sidenavOpenChanges.emit(this.sidenavOpen); + this.sideNav.toggle(); } } diff --git a/dmp-frontend/src/app/shared/components/url-listing/url-listing.component.ts b/dmp-frontend/src/app/shared/components/url-listing/url-listing.component.ts index 2dacfc038..1d55779c6 100644 --- a/dmp-frontend/src/app/shared/components/url-listing/url-listing.component.ts +++ b/dmp-frontend/src/app/shared/components/url-listing/url-listing.component.ts @@ -25,6 +25,6 @@ export class UrlListingComponent { } navigate(link: string) { - this.router.navigate([link, this.parameters]); + this.router.navigate([link], { queryParams: this.parameters }); } } diff --git a/dmp-frontend/src/app/shared/componentsAdmin/combobox/combobox-component.html b/dmp-frontend/src/app/shared/componentsAdmin/combobox/combobox-component.html index a3eb851a1..4ce4b2d4e 100644 --- a/dmp-frontend/src/app/shared/componentsAdmin/combobox/combobox-component.html +++ b/dmp-frontend/src/app/shared/componentsAdmin/combobox/combobox-component.html @@ -1,16 +1,16 @@
    - - -
    -
    - -
    + + +
    +
    +
    -
    -
    - -
    -
    -
    \ No newline at end of file +
    +
    +
    + +
    +
    +
    diff --git a/dmp-frontend/src/app/shared/componentsAdmin/radiobox/radiobox-component.html b/dmp-frontend/src/app/shared/componentsAdmin/radiobox/radiobox-component.html index f33a91a9d..d0bbe6f72 100644 --- a/dmp-frontend/src/app/shared/componentsAdmin/radiobox/radiobox-component.html +++ b/dmp-frontend/src/app/shared/componentsAdmin/radiobox/radiobox-component.html @@ -1,29 +1,29 @@
    -
    -
    - - -
    +
    +
    + + +
    -
    -
    -
    -
    - - -
    -
    - - -
    -
    -
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    - +
    + -
    \ No newline at end of file +
    diff --git a/dmp-frontend/src/app/shared/componentsAdmin/wordlist/wordlist-component.html b/dmp-frontend/src/app/shared/componentsAdmin/wordlist/wordlist-component.html index 73da25ad7..c6b4c40bc 100644 --- a/dmp-frontend/src/app/shared/componentsAdmin/wordlist/wordlist-component.html +++ b/dmp-frontend/src/app/shared/componentsAdmin/wordlist/wordlist-component.html @@ -1,28 +1,28 @@
    -
    -
    +
    +
    + + +
    +
    +
    +
    +
    - -
    -
    -
    -
    -
    - - -
    -
    - - -
    -
    -
    + +
    +
    + + +
    +
    - +
    + -
    \ No newline at end of file +
    diff --git a/dmp-frontend/src/app/shared/help-content/help-content.component.ts b/dmp-frontend/src/app/shared/help-content/help-content.component.ts index 804f7b185..a3f91373d 100644 --- a/dmp-frontend/src/app/shared/help-content/help-content.component.ts +++ b/dmp-frontend/src/app/shared/help-content/help-content.component.ts @@ -43,6 +43,7 @@ export class HelpContentComponent implements OnInit { this.errorMessage = 'System error retrieving page content (Server responded: ' + error + ')'; } } + @Component({ selector: 'aside-help-content', template: ` diff --git a/dmp-frontend/src/app/user-management/admin-login/admin-login.component.html b/dmp-frontend/src/app/user-management/admin-login/admin-login.component.html index d5453623f..b86b90b27 100644 --- a/dmp-frontend/src/app/user-management/admin-login/admin-login.component.html +++ b/dmp-frontend/src/app/user-management/admin-login/admin-login.component.html @@ -1,34 +1,34 @@
    -
    -
    -
    -
    -
    -

    Login

    - -
    +
    +
    +
    +
    +
    +

    Login

    + +
    +
    -
    \ No newline at end of file +
    +
    diff --git a/dmp-frontend/src/app/user-management/admin-login/admin-login.component.scss b/dmp-frontend/src/app/user-management/admin-login/admin-login.component.scss index ba8db6690..29fc432ef 100644 --- a/dmp-frontend/src/app/user-management/admin-login/admin-login.component.scss +++ b/dmp-frontend/src/app/user-management/admin-login/admin-login.component.scss @@ -1,139 +1,148 @@ -.container{ - padding: 15px 30px; - } - - .card{ - box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.14); - border-radius: 6px; - color: rgba(0,0,0, 0.87); - background: #fff; - } - - .card-raised{ - box-shadow: 0 10px 30px -12px rgba(0, 0, 0, 0.42), 0 4px 25px 0px rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.2); - } - - .page-title{ - margin-top: 40px; - } - - @media (min-width: 1200px) { - .container { - width: 100%; - } - } - - @media (min-width: 992px) { - .container { - width: 100%; - } - } - - @media (min-width: 768px) { - .container { - width: 100%; - } - } - - .container{ - height: 100%; - position: relative; - z-index: 1; - } - - .card{ - position: relative; - padding: 20px; - display: flex; - flex-direction: column; - align-items: center; - margin-top: 90px; - top: -90px; - -webkit-animation-name: card; - -moz-animation-name: card; - -o-animation-name: card; - animation-name: card; - -webkit-animation-duration: 600ms; - -moz-animation-duration: 600ms; - -o-animation-duration: 600ms; - animation-duration: 600ms; - -webkit-animation-fill-mode: forwards; - -moz-animation-fill-mode: forwards; - -o-animation-fill-mode: forwards; - animation-fill-mode: forwards; - } - - @-webkit-keyframes card { - from {top: -40px;} - to {top: 0;} - } - - @keyframes card { - from {top: -40px;} - to {top: 0;} - } - - .card-header{ - position: relative; - overflow: hidden; - top: -40px; +.container { + padding: 15px 30px; +} + +.card { + box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.14); + border-radius: 6px; + color: rgba(0, 0, 0, 0.87); + background: #fff; +} + +.card-raised { + box-shadow: 0 10px 30px -12px rgba(0, 0, 0, 0.42), 0 4px 25px 0px rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.2); +} + +.page-title { + margin-top: 40px; +} + +@media (min-width: 1200px) { + .container { width: 100%; - padding: 25px; - border-radius: 3px; - background: linear-gradient(60deg, #aeb5b4, #9d9799); - box-shadow: 0 4px 20px 0px rgba(0, 0, 0, 0.14), 0 7px 10px -5px rgba(49, 46, 47, 0.4); - display: flex; - flex-direction: column; - align-items: center; - } - - .card-header h4{ - font-weight: 400; - color: #fff; - margin-bottom: 25px; - margin-top: 5px; - } - - .social-btns i{ - font-size: 21px; - color: #fff; - } - - .social-btns button{ - margin: 0 8px; } - - .tip{ - margin-top: -20px; - } - - .form-row, .card-form, .mat-input-container{ +} + +@media (min-width: 992px) { + .container { width: 100%; } - - .card-form{ - padding: 5px; - } - - .form-row{ - position: relative; - display: flex; - align-items: center; - margin-top: 13px; +} + +@media (min-width: 768px) { + .container { + width: 100%; } - - .form-row i{ - position: relative; - top: -5px; - margin-right: 15px; - color: #555; +} + +.container { + height: 100%; + position: relative; + z-index: 1; +} + +.card { + position: relative; + padding: 20px; + display: flex; + flex-direction: column; + align-items: center; + margin-top: 90px; + top: -90px; + -webkit-animation-name: card; + -moz-animation-name: card; + -o-animation-name: card; + animation-name: card; + -webkit-animation-duration: 600ms; + -moz-animation-duration: 600ms; + -o-animation-duration: 600ms; + animation-duration: 600ms; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + -o-animation-fill-mode: forwards; + animation-fill-mode: forwards; +} + +@-webkit-keyframes card { + from { + top: -40px; } - - .card-footer{ - margin: 10px; + to { + top: 0; } - - .card-footer button{ - color: #0c0b0b; +} + +@keyframes card { + from { + top: -40px; } - \ No newline at end of file + to { + top: 0; + } +} + +.card-header { + position: relative; + overflow: hidden; + top: -40px; + width: 100%; + padding: 25px; + border-radius: 3px; + background: linear-gradient(60deg, #aeb5b4, #9d9799); + box-shadow: 0 4px 20px 0px rgba(0, 0, 0, 0.14), 0 7px 10px -5px rgba(49, 46, 47, 0.4); + display: flex; + flex-direction: column; + align-items: center; +} + +.card-header h4 { + font-weight: 400; + color: #fff; + margin-bottom: 25px; + margin-top: 5px; +} + +.social-btns i { + font-size: 21px; + color: #fff; +} + +.social-btns button { + margin: 0 8px; +} + +.tip { + margin-top: -20px; +} + +.form-row, +.card-form, +.mat-form-field { + width: 100%; +} + +.card-form { + padding: 5px; +} + +.form-row { + position: relative; + display: flex; + align-items: center; + margin-top: 13px; +} + +.form-row i { + position: relative; + top: -5px; + margin-right: 15px; + color: #555; +} + +.card-footer { + margin: 10px; +} + +.card-footer button { + color: #0c0b0b; +} diff --git a/dmp-frontend/src/app/user-management/login/login.component.html b/dmp-frontend/src/app/user-management/login/login.component.html index 7b7d630e8..43287c763 100644 --- a/dmp-frontend/src/app/user-management/login/login.component.html +++ b/dmp-frontend/src/app/user-management/login/login.component.html @@ -19,22 +19,25 @@
    - +
    email - + - +
    lock_outline - + - +
    -
    \ No newline at end of file +
    diff --git a/dmp-frontend/src/app/user-management/login/login.component.scss b/dmp-frontend/src/app/user-management/login/login.component.scss index e0e8af094..e2acfe0ae 100644 --- a/dmp-frontend/src/app/user-management/login/login.component.scss +++ b/dmp-frontend/src/app/user-management/login/login.component.scss @@ -1,19 +1,19 @@ -.container{ +.container { padding: 15px 30px; } -.card{ +.card { box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.14); border-radius: 6px; - color: rgba(0,0,0, 0.87); + color: rgba(0, 0, 0, 0.87); background: #fff; } -.card-raised{ +.card-raised { box-shadow: 0 10px 30px -12px rgba(0, 0, 0, 0.42), 0 4px 25px 0px rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.2); } -.page-title{ +.page-title { margin-top: 40px; } @@ -35,13 +35,13 @@ } } -.container{ +.container { height: 100%; position: relative; z-index: 1; } -.card{ +.card { position: relative; padding: 20px; display: flex; @@ -64,16 +64,24 @@ } @-webkit-keyframes card { - from {top: -40px;} - to {top: 0;} + from { + top: -40px; + } + to { + top: 0; + } } @keyframes card { - from {top: -40px;} - to {top: 0;} + from { + top: -40px; + } + to { + top: 0; + } } -.card-header{ +.card-header { position: relative; overflow: hidden; top: -40px; @@ -87,53 +95,55 @@ align-items: center; } -.card-header h4{ +.card-header h4 { font-weight: 400; color: #fff; margin-bottom: 25px; margin-top: 5px; } -.social-btns i{ +.social-btns i { font-size: 21px; color: #fff; } -.social-btns button{ +.social-btns button { margin: 0 8px; } -.tip{ +.tip { margin-top: -20px; } -.form-row, .card-form, .mat-input-container{ +.form-row, +.card-form, +.mat-form-field { width: 100%; } -.card-form{ +.card-form { padding: 5px; } -.form-row{ +.form-row { position: relative; display: flex; align-items: center; margin-top: 13px; } -.form-row i{ +.form-row i { position: relative; top: -5px; margin-right: 15px; color: #555; } -.card-footer{ +.card-footer { margin: 10px; } -.card-footer button{ +.card-footer button { color: #e91e63; } @@ -143,9 +153,10 @@ width: 45px; height: 25px; } + span.iconmedium { background: url(img/b2access_medium.png) no-repeat; float: left; width: 100px; height: 56px; -} \ No newline at end of file +} diff --git a/dmp-frontend/src/app/user-management/utilties/login-service.ts b/dmp-frontend/src/app/user-management/utilties/login-service.ts index d1d0cd646..f8cb479c7 100644 --- a/dmp-frontend/src/app/user-management/utilties/login-service.ts +++ b/dmp-frontend/src/app/user-management/utilties/login-service.ts @@ -20,215 +20,213 @@ declare const IN: any; @Injectable() export class LoginService { - private providers: LoginOptions[] - private auth2: any; - constructor( - private router: Router, - public authService: AuthService, - public route: ActivatedRoute, - public snackBar: MatSnackBar, - public language: TranslateService, - private zone: NgZone, - private httpClient: HttpClient, - @Optional() private config: LoginServiceConfiguration - ) { - if (config) { - this.providers = config.loginProviders; - } - else this.providers = [LoginOptions.nativeLogin]; - } - - public initProviders() { - if (this.hasProvider(LoginOptions.googleOauth)) this.initialiseGoogleOauth(); - if (this.hasProvider(LoginOptions.facebookOauth)) this.initialiseFacebookOauth(); - } - - public hasProvider(provider: LoginOptions) { - for (let i = 0; i < this.providers.length; i++) { - if (provider === this.providers[i]) return this.isProviderProperlyConfigured(provider) - } - return false; - } - - private isProviderProperlyConfigured(provider: LoginOptions) { - switch (provider) { - case LoginOptions.facebookOauth: return this.hasAllRequiredFieldsConfigured(this.config.facebookConfiguration); - case LoginOptions.googleOauth: return this.hasAllRequiredFieldsConfigured(this.config.googleConfiguration) - case LoginOptions.linkedInOauth: return this.hasAllRequiredFieldsConfigured(this.config.linkedInConfiguration); - case LoginOptions.twitterOauth: return this.hasAllRequiredFieldsConfigured(this.config.twitterConfiguration); - case LoginOptions.b2Access: return this.hasAllRequiredFieldsConfigured(this.config.b2accessConfiguration); - case LoginOptions.nativeLogin: return true; - default: throw new Error("Unsupported Provider Type") - } - } - - private hasAllRequiredFieldsConfigured(configuration: LoginProviderConfiguration) { - if (configuration != null && configuration.clientId != null) return true - return false; - } - - /* - * GOOGLE SIGN IN - */ - - private initialiseGoogleOauth(): void { - gapi.load('auth2', () => { - this.auth2 = gapi.auth2.init({ - client_id: this.config.googleConfiguration.clientId, - cookiepolicy: 'single_host_origin', - scope: 'profile email' - }); - this.attachGoogleSignin(document.getElementById('googleSignInButton')); - }); - } - - public attachGoogleSignin(element) { - if (!element) return - this.auth2.attachClickHandler(element, {}, - (googleUser) => { - var id_token = googleUser.getAuthResponse().id_token; - if (id_token) { - this.authService.login({ ticket: id_token, provider: LoginProviders.Google }).subscribe( - res => this.onLogInSuccess(res), - error => this.onLogInError(error) - ) - } - }, (error) => { - alert(JSON.stringify(error, undefined, 2)); - }); - } - - - - /* - * FACEBOOK SIGN IN - */ - - - private initialiseFacebookOauth(): void { - FB.init({ - appId: this.config.facebookConfiguration.clientId, - cookie: false, - xfbml: true, - version: 'v2.8' - }); - } - - - - - public facebookLogin() { - FB.login((response: any) => { - if (response.status === 'connected' || 'not_authorized') { - this.authService.login({ ticket: response.authResponse.accessToken, provider: LoginProviders.Facebook }).subscribe( - res => this.onLogInSuccess(res), - error => this.onLogInError(error) - ) - } - }, { scope: 'user_friends,email' }); - } - - /* - * LINKEDIN SIGN IN - */ - - public linkedinAuthorize() { - window.location.href = this.config.linkedInConfiguration.oauthUrl + "?response_type=code&client_id=" + this.config.linkedInConfiguration.clientId + "&redirect_uri=" + this.config.linkedInConfiguration.redirectUri + "&state=987654321" - } - - public linkedInInitialiseLogin() { - this.router.navigate(["/login/linkedin"]) - } + private providers: LoginOptions[] + private auth2: any; + constructor( + private router: Router, + public authService: AuthService, + public route: ActivatedRoute, + public snackBar: MatSnackBar, + public language: TranslateService, + private zone: NgZone, + private httpClient: HttpClient, + @Optional() private config: LoginServiceConfiguration + ) { + if (config) { + this.providers = config.loginProviders; + } + else this.providers = [LoginOptions.nativeLogin]; + } + + public initProviders() { + if (this.hasProvider(LoginOptions.googleOauth)) this.initialiseGoogleOauth(); + if (this.hasProvider(LoginOptions.facebookOauth)) this.initialiseFacebookOauth(); + } + + public hasProvider(provider: LoginOptions) { + for (let i = 0; i < this.providers.length; i++) { + if (provider === this.providers[i]) return this.isProviderProperlyConfigured(provider) + } + return false; + } + + private isProviderProperlyConfigured(provider: LoginOptions) { + switch (provider) { + case LoginOptions.facebookOauth: return this.hasAllRequiredFieldsConfigured(this.config.facebookConfiguration); + case LoginOptions.googleOauth: return this.hasAllRequiredFieldsConfigured(this.config.googleConfiguration) + case LoginOptions.linkedInOauth: return this.hasAllRequiredFieldsConfigured(this.config.linkedInConfiguration); + case LoginOptions.twitterOauth: return this.hasAllRequiredFieldsConfigured(this.config.twitterConfiguration); + case LoginOptions.b2Access: return this.hasAllRequiredFieldsConfigured(this.config.b2accessConfiguration); + case LoginOptions.nativeLogin: return true; + default: throw new Error("Unsupported Provider Type") + } + } + + private hasAllRequiredFieldsConfigured(configuration: LoginProviderConfiguration) { + if (configuration != null && configuration.clientId != null) return true + return false; + } + + /* + * GOOGLE SIGN IN + */ - public linkedInloginUser(code: string) { - this.authService.login({ ticket: code, provider: LoginProviders.LinkedIn }).subscribe( + private initialiseGoogleOauth(): void { + gapi.load('auth2', () => { + this.auth2 = gapi.auth2.init({ + client_id: this.config.googleConfiguration.clientId, + cookiepolicy: 'single_host_origin', + scope: 'profile email' + }); + this.attachGoogleSignin(document.getElementById('googleSignInButton')); + }); + } + + public attachGoogleSignin(element) { + if (!element) return + this.auth2.attachClickHandler(element, {}, + (googleUser) => { + var id_token = googleUser.getAuthResponse().id_token; + if (id_token) { + this.authService.login({ ticket: id_token, provider: LoginProviders.Google }).subscribe( res => this.onLogInSuccess(res), error => this.onLogInError(error) - ) - } - - /* - * TWITTER SIGN IN - */ - public twitterInitialiseLogin() { - this.router.navigate(["/login/twitter"]) - } + ) + } + }, (error) => { + alert(JSON.stringify(error, undefined, 2)); + }); + } - public twitterAuthorize() { - let headers = new HttpHeaders(); - headers = headers.set('Content-Type', 'application/json'); - headers = headers.set('Accept', 'application/json'); - this.httpClient.get(HostConfiguration.Server + 'auth/twitterRequestToken', { headers: headers }).subscribe((data: any) => { - window.location.href = this.config.twitterConfiguration.oauthUrl + "?oauth_token=" + data.payload.value - }) - } - public twitterLogin(token: string, verifier: string) { - this.authService.login({ ticket: token, provider: LoginProviders.Twitter, data: verifier }).subscribe( - res => this.onLogInSuccess(res), - error => this.onLogInError(error) - ) - } - /* - * B2ACCESS LOG IN + /* + * FACEBOOK SIGN IN */ - public b2AccessInitialiseLogin() { - this.router.navigate(["/api/oauth/authorized/b2access"]) - } - public b2AccessGetAuthCode() { - window.location.href = this.config.b2accessConfiguration.oauthUrl + "?response_type=code&client_id=" + this.config.b2accessConfiguration.clientId + "&redirect_uri=" + this.config.b2accessConfiguration.redirectUri + "&state=987654321&scope=USER_PROFILE" - } + private initialiseFacebookOauth(): void { + FB.init({ + appId: this.config.facebookConfiguration.clientId, + cookie: false, + xfbml: true, + version: 'v2.8' + }); + } - public b2AccessLogin(code: String) { - let headers = new HttpHeaders(); - headers = headers.set('Content-Type', 'application/json'); - headers = headers.set('Accept', 'application/json'); - this.httpClient.post(HostConfiguration.Server + "auth/b2AccessRequestToken", { code: code }, { headers: headers }) - .subscribe((data: any) => { - this.authService.login({ ticket: data.payload.accessToken, provider: LoginProviders.B2Accesss, data: null }).subscribe( - res => this.onLogInSuccess(res), - error => this.onLogInError(error) - ) - }) - } - /* - * NATIVE LOGIN - */ - public nativeLogin(credentials: Credential) { - this.authService.nativeLogin(credentials).subscribe( - res => this.onLogInSuccess(res), - error => this.onLogInError(error) + public facebookLogin() { + FB.login((response: any) => { + if (response.status === 'connected' || 'not_authorized') { + this.authService.login({ ticket: response.authResponse.accessToken, provider: LoginProviders.Facebook }).subscribe( + res => this.onLogInSuccess(res), + error => this.onLogInError(error) ) - } - - - /* - * LOGIN HANDLERS - */ - - - public onLogInSuccess(logoutMessage: any) { - this.snackBar.openFromComponent(SnackBarNotificationComponent, { - data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-LOGIN', language: this.language }, - duration: 3000, - extraClasses: ['snackbar-success'] - }); - let params = this.router["rawUrlTree"].queryParams; - let redirectUrl = params['returnUrl'] ? params['returnUrl'] : '/'; - this.zone.run(() => this.router.navigate([redirectUrl])); - } - - public onLogInError(errorMessage: string) { - this.snackBar.openFromComponent(SnackBarNotificationComponent, { - data: { message: 'GENERAL.SNACK-BAR.UNSUCCESSFUL-LOGIN', language: this.language }, - duration: 3000, - extraClasses: ['snackbar-warning'] - }) - } -} \ No newline at end of file + } + }, { scope: 'user_friends,email' }); + } + + /* + * LINKEDIN SIGN IN + */ + + public linkedinAuthorize() { + window.location.href = this.config.linkedInConfiguration.oauthUrl + "?response_type=code&client_id=" + this.config.linkedInConfiguration.clientId + "&redirect_uri=" + this.config.linkedInConfiguration.redirectUri + "&state=987654321" + } + + public linkedInInitialiseLogin() { + this.router.navigate(["/login/linkedin"]) + } + + public linkedInloginUser(code: string) { + this.authService.login({ ticket: code, provider: LoginProviders.LinkedIn }).subscribe( + res => this.onLogInSuccess(res), + error => this.onLogInError(error) + ) + } + + /* + * TWITTER SIGN IN + */ + public twitterInitialiseLogin() { + this.router.navigate(["/login/twitter"]) + } + + public twitterAuthorize() { + let headers = new HttpHeaders(); + headers = headers.set('Content-Type', 'application/json'); + headers = headers.set('Accept', 'application/json'); + this.httpClient.get(HostConfiguration.Server + 'auth/twitterRequestToken', { headers: headers }).subscribe((data: any) => { + window.location.href = this.config.twitterConfiguration.oauthUrl + "?oauth_token=" + data.payload.value + }) + } + + public twitterLogin(token: string, verifier: string) { + this.authService.login({ ticket: token, provider: LoginProviders.Twitter, data: verifier }).subscribe( + res => this.onLogInSuccess(res), + error => this.onLogInError(error) + ) + } + + /* +* B2ACCESS LOG IN +*/ + + public b2AccessInitialiseLogin() { + this.router.navigate(["/api/oauth/authorized/b2access"]) + } + + public b2AccessGetAuthCode() { + window.location.href = this.config.b2accessConfiguration.oauthUrl + "?response_type=code&client_id=" + this.config.b2accessConfiguration.clientId + "&redirect_uri=" + this.config.b2accessConfiguration.redirectUri + "&state=987654321&scope=USER_PROFILE" + } + + public b2AccessLogin(code: String) { + let headers = new HttpHeaders(); + headers = headers.set('Content-Type', 'application/json'); + headers = headers.set('Accept', 'application/json'); + this.httpClient.post(HostConfiguration.Server + "auth/b2AccessRequestToken", { code: code }, { headers: headers }) + .subscribe((data: any) => { + this.authService.login({ ticket: data.payload.accessToken, provider: LoginProviders.B2Accesss, data: null }).subscribe( + res => this.onLogInSuccess(res), + error => this.onLogInError(error) + ) + }) + } + + + /* + * NATIVE LOGIN + */ + + public nativeLogin(credentials: Credential) { + this.authService.nativeLogin(credentials).subscribe( + res => this.onLogInSuccess(res), + error => this.onLogInError(error) + ) + } + + + /* + * LOGIN HANDLERS + */ + + + public onLogInSuccess(logoutMessage: any) { + this.snackBar.openFromComponent(SnackBarNotificationComponent, { + data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-LOGIN', language: this.language }, + duration: 3000, + }); + let params = this.router["rawUrlTree"].queryParams; + let redirectUrl = params['returnUrl'] ? params['returnUrl'] : '/'; + this.zone.run(() => this.router.navigate([redirectUrl])); + } + + public onLogInError(errorMessage: string) { + this.snackBar.openFromComponent(SnackBarNotificationComponent, { + data: { message: 'GENERAL.SNACK-BAR.UNSUCCESSFUL-LOGIN', language: this.language }, + duration: 3000, + }) + } +} diff --git a/dmp-frontend/src/app/users/components/roles/user-role-editor.component.ts b/dmp-frontend/src/app/users/components/roles/user-role-editor.component.ts index f1fcbaf5e..d5e06bb1c 100644 --- a/dmp-frontend/src/app/users/components/roles/user-role-editor.component.ts +++ b/dmp-frontend/src/app/users/components/roles/user-role-editor.component.ts @@ -19,14 +19,14 @@ import { MatSnackBar } from '@angular/material'; export class UserRoleEditorComponent implements OnInit { @Input() public item: UserListingModel; - private formGroup: FormGroup = null; - private nowEditing = false; - private errorModel: UserErrorModel; + public formGroup: FormGroup = null; + public nowEditing = false; + public errorModel: UserErrorModel; constructor( - private language: TranslateService, - private userService: UserReferenceService, - private formBuilder: FormBuilder, - private snackBar: MatSnackBar + public language: TranslateService, + public userService: UserReferenceService, + public formBuilder: FormBuilder, + public snackBar: MatSnackBar ) { } @@ -133,7 +133,6 @@ export class UserRoleEditorComponent implements OnInit { this.snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE', language: this.language }, duration: 3000, - extraClasses: ['snackbar-success'] }); } onCallbackError(error: any) { @@ -142,7 +141,6 @@ export class UserRoleEditorComponent implements OnInit { this.snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: 'GENERAL.SNACK-BAR.UNSUCCESSFUL-UPDATE', language: this.language }, duration: 3000, - extraClasses: ['snackbar-warning'] }); } diff --git a/dmp-frontend/src/app/users/components/users.component.ts b/dmp-frontend/src/app/users/components/users.component.ts index 256259f96..aad27d8cb 100644 --- a/dmp-frontend/src/app/users/components/users.component.ts +++ b/dmp-frontend/src/app/users/components/users.component.ts @@ -63,7 +63,6 @@ export class UsersDataSource extends DataSource { this._snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: 'GENERAL.SNACK-BAR.FORMS-BAD-REQUEST', language: this._languageService }, duration: 3000, - extraClasses: ['snackbar-warning'] }); this._criteria.onCallbackError(error); return Observable.of(null); diff --git a/dmp-frontend/src/app/utilities/cite-http-service-module/base-http.service.ts b/dmp-frontend/src/app/utilities/cite-http-service-module/base-http.service.ts index 13b61ec56..7f9182cab 100644 --- a/dmp-frontend/src/app/utilities/cite-http-service-module/base-http.service.ts +++ b/dmp-frontend/src/app/utilities/cite-http-service-module/base-http.service.ts @@ -75,7 +75,6 @@ export class BaseHttpService { this.snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-LOGOUT', language: this.language }, duration: 3000, - extraClasses: ['snackbar-success'] }) let currentPage = this.router.url; this.router.navigate(['/unauthorized'], { queryParams: { returnUrl: currentPage } }); @@ -87,7 +86,6 @@ export class BaseHttpService { this.snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: error.message, language: null }, duration: 3000, - extraClasses: ['snackbar-warning'] }) return Observable.throw(errorResponse); } @@ -98,7 +96,6 @@ export class BaseHttpService { this.snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: 'GENERAL.ERRORS.HTTP-REQUEST-ERROR', language: this.language }, duration: 3000, - extraClasses: ['snackbar-warning'] }) return Observable.throw(errorResponse); } @@ -106,21 +103,20 @@ export class BaseHttpService { }) .map(response => { if (response instanceof Blob) return response - if (response.statusCode == ApiMessageCode.SUCCESS_MESSAGE) { + if (response["statusCode"] == ApiMessageCode.SUCCESS_MESSAGE) { //throw new Error('Request failed'); this.snackBar.openFromComponent(SnackBarNotificationComponent, { - data: { message: response.message, language: null }, + data: { message: response["message"], language: null }, duration: 3000, - extraClasses: ['snackbar-success'] }) - return response.payload; + return response["payload"]; } - else if (response.statusCode == ApiMessageCode.NO_MESSAGE) { - return response.payload; + else if (response["statusCode"] == ApiMessageCode.NO_MESSAGE) { + return response["payload"]; } else { - return response.payload; + return response["payload"]; } }); } diff --git a/dmp-frontend/src/app/welcomepage/welcomepage.component.ts b/dmp-frontend/src/app/welcomepage/welcomepage.component.ts index c3a86acd2..89bce9cc9 100644 --- a/dmp-frontend/src/app/welcomepage/welcomepage.component.ts +++ b/dmp-frontend/src/app/welcomepage/welcomepage.component.ts @@ -4,7 +4,6 @@ import { DashboardService } from '../../app/services/dashboard/dashboard.service import { DashboardStatisticsModel } from '../models/dashboard/DashboardStatisticsModel'; import { JsonSerializer } from '../utilities/JsonSerializer'; import { HomepageComponent } from '../homepage/homepage.component' -import { IBreadcrumb } from 'ngx-breadcrumbs'; import { IBreadCrumbComponent } from '../shared/components/breadcrumb/definition/IBreadCrumbComponent'; import { Observable } from 'rxjs/Observable'; import { BreadcrumbItem } from '../shared/components/breadcrumb/definition/breadcrumb-item'; diff --git a/dmp-frontend/src/assets/lang/en.json b/dmp-frontend/src/assets/lang/en.json index 3ce0c2cba..c84aade7e 100644 --- a/dmp-frontend/src/assets/lang/en.json +++ b/dmp-frontend/src/assets/lang/en.json @@ -185,7 +185,8 @@ "LIKE": "Search", "PERIOD-FROM": "Start", "PERIOD-TO": "End", - "STATUS": "Status" + "STATUS": "Status", + "TAGS": "Tags" }, "DMP": { "LIKE": "Search", diff --git a/dmp-frontend/src/environments/environment.ts b/dmp-frontend/src/environments/environment.ts index 05a577f68..b60755433 100644 --- a/dmp-frontend/src/environments/environment.ts +++ b/dmp-frontend/src/environments/environment.ts @@ -5,7 +5,7 @@ export const environment = { production: false, - Server: 'http://devel-21.local.cite.gr:8080/api/', + Server: 'http://localhost:8080/api/', App: 'http://localhost:4200/', HelpServiceUrl: 'localhost:5000/' }; diff --git a/dmp-frontend/tslint.json b/dmp-frontend/tslint.json index 9963d6c39..d8d395663 100644 --- a/dmp-frontend/tslint.json +++ b/dmp-frontend/tslint.json @@ -18,7 +18,6 @@ "forin": true, "import-blacklist": [ true, - "rxjs", "rxjs/Rx" ], "import-spacing": true, diff --git a/docker-compose.yml b/docker-compose.yml index 8c3a4baa2..42fcd5682 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,6 +17,9 @@ services: # # ELASTIC_VERSION=6.0.0-beta1 TAG=6.0.0-beta1-3eab5b40 docker-compose up # + +##########################DMP###################################################################### + dmp-backend: build: context: ./dmp-backend @@ -25,8 +28,9 @@ services: container_name: dmp-backend ports: ['0.0.0.0:8080:8080'] links: - - logstash - networks: ['stack'] + - logstash:logstash + - elasticsearch-dmp:elasticsearch-dmp + networks: ['stack','elasticsearch-dmp'] dmp-frontend: build: @@ -38,12 +42,28 @@ services: ports: ['0.0.0.0:80:80'] networks: ['stack'] +##########################ELASTIC###################################################################### + elasticsearch-dmp: + image: docker.elastic.co/elasticsearch/elasticsearch:${TAG} + container_name: elasticsearch-dmp + volumes: + - ./elastic-config/elasticsearch-custom.yml:/usr/share/elasticsearch/config/elasticsearch.yml + environment: ['http.host=0.0.0.0','transport.host=0.0.0.0'] + ports: ['0.0.0.0:9201:9200','0.0.0.0:9301:9300'] + networks: ['elasticsearch-dmp'] + volumes: + - esdata-dmp:/usr/share/elasticsearch/data + +##########################ELK-STACK###################################################################### + elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:${TAG} container_name: elasticsearch environment: ['http.host=0.0.0.0', 'transport.host=127.0.0.1', 'ELASTIC_PASSWORD=${ELASTIC_PASSWORD}'] ports: ['0.0.0.0:9200:9200'] networks: ['stack'] + volumes: + - esdata:/usr/share/elasticsearch/data kibana: image: docker.elastic.co/kibana/kibana:${TAG} @@ -62,27 +82,25 @@ services: networks: ['stack'] depends_on: ['elasticsearch', 'setup_logstash'] - filebeat: - image: docker.elastic.co/beats/filebeat:${TAG} - container_name: filebeat - command: -e -E 'output.elasticsearch.password=${ELASTIC_PASSWORD}' - networks: ['stack'] - depends_on: ['elasticsearch', 'setup_filebeat'] + #filebeat: + # image: docker.elastic.co/beats/filebeat:${TAG} + # container_name: filebeat + # command: -e -E 'output.elasticsearch.password=${ELASTIC_PASSWORD}' + # networks: ['stack'] + # depends_on: ['elasticsearch', 'setup_filebeat'] - heartbeat: - image: docker.elastic.co/beats/heartbeat:${TAG} - container_name: heartbeat - command: -e -E 'output.elasticsearch.password=${ELASTIC_PASSWORD}' - networks: ['stack'] - depends_on: ['elasticsearch', 'setup_heartbeat'] + #heartbeat: + # image: docker.elastic.co/beats/heartbeat:${TAG} + # container_name: heartbeat + # command: -e -E 'output.elasticsearch.password=${ELASTIC_PASSWORD}' + # networks: ['stack'] + # depends_on: ['elasticsearch', 'setup_heartbeat'] # Run a short-lived container to set up Logstash. setup_logstash: image: centos:7 container_name: setup_logstash volumes: ['./ELK.Docker/scripts/setup-logstash.sh:/usr/local/bin/setup-logstash.sh:ro'] - # The script may have CR/LF line endings if using Docker for Windows, so - # make sure that they don't confuse Bash. command: ['/bin/bash', '-c', 'cat /usr/local/bin/setup-logstash.sh | tr -d "\r" | bash'] environment: ['ELASTIC_PASSWORD=${ELASTIC_PASSWORD}'] networks: ['stack'] @@ -97,25 +115,95 @@ services: networks: ['stack'] depends_on: ['elasticsearch'] - setup_filebeat: - image: docker.elastic.co/beats/filebeat:${TAG} - container_name: setup_filebeat - volumes: ['./ELK.Docker/scripts/setup-beat.sh:/usr/local/bin/setup-beat.sh:ro'] - command: ['/bin/bash', '-c', 'cat /usr/local/bin/setup-beat.sh | tr -d "\r" | bash -s filebeat'] - environment: ['ELASTIC_PASSWORD=${ELASTIC_PASSWORD}'] - networks: ['stack'] - depends_on: ['kibana'] + #setup_filebeat: + # image: docker.elastic.co/beats/filebeat:${TAG} + # container_name: setup_filebeat + # volumes: ['./ELK.Docker/scripts/setup-beat.sh:/usr/local/bin/setup-beat.sh:ro'] + # command: ['/bin/bash', '-c', 'cat /usr/local/bin/setup-beat.sh | tr -d "\r" | bash -s filebeat'] + # environment: ['ELASTIC_PASSWORD=${ELASTIC_PASSWORD}'] + # networks: ['stack'] + # depends_on: ['kibana'] + + #setup_heartbeat: + # image: docker.elastic.co/beats/heartbeat:${TAG} + # container_name: setup_heartbeat + # volumes: ['./ELK.Docker/scripts/setup-beat.sh:/usr/local/bin/setup-beat.sh:ro'] + # command: ['/bin/bash', '-c', 'cat /usr/local/bin/setup-beat.sh | tr -d "\r" | bash -s heartbeat'] + # environment: ['ELASTIC_PASSWORD=${ELASTIC_PASSWORD}'] + # networks: ['stack'] + # depends_on: ['kibana'] + +##########################DOCSBOX###################################################################### + # web: + # restart: always + # build: ./docsbox-master/docsbox + # expose: + # - "8000" + # links: + # - redis:redis + # volumes: + # - docsbox:/home/docsbox + # - media:/home/docsbox/media + # command: gunicorn -b :8000 docsbox:app + # networks: ['stack'] + + # rqworker: + # restart: always + # build: ./docsbox-master/docsbox + # links: + # - redis:redis + # volumes: + # - web + # command: rq worker -c docsbox.settings + # networks: ['stack'] + + # rqscheduler: + # restart: always + # build: ./docsbox-master/docsbox + # links: + # - redis:redis + # volumes: + # - web + # command: rqscheduler -H redis -p 6379 -d 0 + # networks: ['stack'] + + # nginx: + # restart: always + # build: ./docsbox-master/nginx/ + # ports: + # - "81:80" + # volumes: + # - web + # links: + # - web:web + # networks: ['stack'] + + # redis: + # restart: always + # image: redis:latest + # expose: + # - "6379" + # volumes: + # - redisdata:/data + # networks: ['stack'] + + +##########################SETTINGS###################################################################### + +volumes: + esdata: + driver: local + esdata-dmp: + driver: local + #redisdata: + # driver: local + # docsbox: + # driver: local + # media: + # driver: local +networks: + stack: {} + elasticsearch-dmp: {} + - setup_heartbeat: - image: docker.elastic.co/beats/heartbeat:${TAG} - container_name: setup_heartbeat - volumes: ['./ELK.Docker/scripts/setup-beat.sh:/usr/local/bin/setup-beat.sh:ro'] - command: ['/bin/bash', '-c', 'cat /usr/local/bin/setup-beat.sh | tr -d "\r" | bash -s heartbeat'] - environment: ['ELASTIC_PASSWORD=${ELASTIC_PASSWORD}'] - networks: ['stack'] - depends_on: ['kibana'] -#volumes: - #esdata: - # driver: local -networks: {stack: {}} diff --git a/docsbox-master/.gitignore b/docsbox-master/.gitignore new file mode 100644 index 000000000..4acaba3a2 --- /dev/null +++ b/docsbox-master/.gitignore @@ -0,0 +1,48 @@ +*.py[cod] + +# C extensions +*.so + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg +lib +lib64 + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox +nosetests.xml + +# Translations +*.mo + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject + +# Complexity +output/*.html +output/*/index.html + +# Sphinx +docs/_build + +/todo.txt +/.ropeproject +/example.db +/_ +/.cache diff --git a/docsbox-master/.travis.yml b/docsbox-master/.travis.yml new file mode 100644 index 000000000..348bd2212 --- /dev/null +++ b/docsbox-master/.travis.yml @@ -0,0 +1,7 @@ +sudo: required +language: python +services: + - docker + +script: + - docker-compose run web nosetests diff --git a/docsbox-master/LICENSE b/docsbox-master/LICENSE new file mode 100644 index 000000000..e04e227f5 --- /dev/null +++ b/docsbox-master/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Dmitry Veselov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/docsbox-master/README.md b/docsbox-master/README.md new file mode 100644 index 000000000..fda98191d --- /dev/null +++ b/docsbox-master/README.md @@ -0,0 +1,134 @@ +# docsbox [![Build Status](https://travis-ci.org/dveselov/docsbox.svg?branch=master)](https://travis-ci.org/dveselov/docsbox) + +`docsbox` is a standalone service that allows you convert office documents, like .docx and .pptx, into more useful filetypes like PDF, for viewing it in browser with PDF.js, or HTML for organizing full-text search of document content. +`docsbox` uses **LibreOffice** (via **LibreOfficeKit**) for document converting. + +```bash +$ curl -F "file=@kittens.docx" http://localhost/api/v1/ + +{ + "id": "9b643d78-d0c8-4552-a0c5-111a89896176", + "status": "queued" +} + +$ curl http://localhost/api/v1/9b643d78-d0c8-4552-a0c5-111a89896176 + +{ + "id": "9b643d78-d0c8-4552-a0c5-111a89896176", + "result_url": "/media/9b643d78-d0c8-4552-a0c5-111a89896176.zip", + "status": "finished" +} + +$ curl -O http://localhost/media/9b643d78-d0c8-4552-a0c5-111a89896176.zip + +$ unzip -l 9b643d78-d0c8-4552-a0c5-111a89896176.zip + +Archive: 9b643d78-d0c8-4552-a0c5-111a89896176.zip + Length Date Time Name +--------- ---------- ----- ---- + 11135 2016-07-08 05:31 txt + 373984 2016-07-08 05:31 pdf + 147050 2016-07-08 05:31 html +--------- ------- + 532169 3 files +``` + +```bash +$ cat options.json +{ + "formats": ["pdf"], + "thumbnails": { + "size": "640x480", + } +} + +$ curl -i -F "file=@kittens.ppt" -F "options=80/tcp docsbox_nginx_1 +f6b55773c71d docsbox_rqworker "rq worker -c docsbox" 15 minutes ago Up 8 minutes docsbox_rqworker_1 +662b08daefea docsbox_rqscheduler "rqscheduler -H redis" 15 minutes ago Up 8 minutes docsbox_rqscheduler_1 +0364df126b36 docsbox_web "gunicorn -b :8000 do" 15 minutes ago Up 8 minutes 8000/tcp docsbox_web_1 +5e8c8481e288 redis:latest "docker-entrypoint.sh" 9 hours ago Up 8 minutes 0.0.0.0:6379->6379/tcp docsbox_redis_1 +``` + +# Settings (env) + +``` +REDIS_URL - redis-server url (default: redis://redis:6379/0) +REDIS_JOB_TIMEOUT - job timeout (default: 10 minutes) +ORIGINAL_FILE_TTL - TTL for uploaded file in seconds (default: 10 minutes) +RESULT_FILE_TTL - TTL for result file in seconds (default: 24 hours) +THUMBNAILS_DPI - thumbnails dpi, for bigger thumbnails choice bigger values (default: 90) +LIBREOFFICE_PATH - path to libreoffice (default: /usr/lib/libreoffice/program/) +``` + +# Scaling +Within a single physical server, docsbox can be scaled by docker-compose: +```bash +$ docker-compose scale web=4 rqworker=8 +``` +For multi-host deployment you'll need to create global syncronized volume (e.g. with flocker), global redis-server and mount it at `docker-compose.yml` file. + +# Supported filetypes + +| Input | Output | Thumbnails | +| ---------------------------------- | ------------------- | ---------- | +| Document `doc` `docx` `odt` `rtf` | `pdf` `txt` `html` | `yes` | +| Presentation `ppt` `pptx` `odp` | `pdf` `html` | `yes` | +| Spreadsheet `xls` `xlsx` `ods` | `pdf` `csv` `html` | `yes` | diff --git a/docsbox-master/docker-compose.yml b/docsbox-master/docker-compose.yml new file mode 100644 index 000000000..60dca2149 --- /dev/null +++ b/docsbox-master/docker-compose.yml @@ -0,0 +1,67 @@ +--- +version: '3' +services: + web: + restart: always + build: ./docsbox-master/docsbox + expose: + - "8000" + links: + - redis:redis + volumes: + - docsbox:/home/docsbox + - media:/home/docsbox/media + command: gunicorn -b :8000 docsbox:app + networks: ['stack'] + + rqworker: + restart: always + build: ./docsbox-master/docsbox + links: + - redis:redis + volumes: + - web + command: rq worker -c docsbox.settings + networks: ['stack'] + + rqscheduler: + restart: always + build: ./docsbox-master/docsbox + links: + - redis:redis + volumes: + - web + command: rqscheduler -H redis -p 6379 -d 0 + networks: ['stack'] + + nginx: + restart: always + build: ./docsbox-master/nginx/ + ports: + - "81:80" + volumes: + - web + links: + - web:web + networks: ['stack'] + + redis: + restart: always + image: redis:latest + expose: + - "6379" + volumes: + - redisdata:/data + networks: ['stack'] + +volumes: + esdata: + driver: local + redisdata: + driver: local + docsbox: + driver: local + media: + driver: local + +networks: {stack: {}} diff --git a/docsbox-master/docsbox/Dockerfile b/docsbox-master/docsbox/Dockerfile new file mode 100644 index 000000000..4cbd1352f --- /dev/null +++ b/docsbox-master/docsbox/Dockerfile @@ -0,0 +1,17 @@ +FROM ubuntu:16.04 +MAINTAINER Dmitry Veselov + +RUN apt-get update && apt-get upgrade -y +RUN apt-get install -y libffi-dev libmagic-dev libmagickwand-dev +RUN apt-get install -y libreoffice libreofficekit-dev +RUN apt-get install -y python3-dev python3-pip git + +RUN apt-get clean && apt-get -y update && apt-get install -y locales && locale-gen en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +ADD . /home/docsbox +WORKDIR /home/ +RUN pip3 install --upgrade pip +RUN pip3 install -r docsbox/requirements.txt diff --git a/docsbox-master/docsbox/__init__.py b/docsbox-master/docsbox/__init__.py new file mode 100644 index 000000000..67ea852a9 --- /dev/null +++ b/docsbox-master/docsbox/__init__.py @@ -0,0 +1,32 @@ +from flask import Flask +from flask.ext.rq2 import RQ +from flask_restful import Api +from flask_env_settings import Settings + + +app = Flask(__name__) +app.config.from_object("docsbox.settings") + +Settings(app, rules={ + "REDIS_JOB_TIMEOUT": (int, 60 * 10), + "ORIGINAL_FILE_TTL": (int, 60 * 10), + "RESULT_FILE_TTL": (int, 60 * 60 * 24), + + "LIBREOFFICE_PATH": (str, "/usr/lib/libreoffice/program/"), + + "THUMBNAILS_DPI": (int, 90), + "THUMBNAILS_QUANTIZE": (bool, False), + "THUMBNAILS_QUANTIZE_COLORS": (int, 128), + "THUMBNAILS_QUANTIZE_COLORSPACE": (str, "rgb"), +}) + +api = Api(app) +rq = RQ(app) + +from docsbox.docs.views import DocumentView, DocumentCreateView + +api.add_resource(DocumentView, "/api/v1/") +api.add_resource(DocumentCreateView, "/api/v1/") + +if __name__ == "__main__": + app.run() diff --git a/docsbox-master/docsbox/docs/__init__.py b/docsbox-master/docsbox/docs/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/docsbox-master/docsbox/docs/tasks.py b/docsbox-master/docsbox/docs/tasks.py new file mode 100644 index 000000000..22c9b3f49 --- /dev/null +++ b/docsbox-master/docsbox/docs/tasks.py @@ -0,0 +1,56 @@ +import os +import shutil +import datetime + +from pylokit import Office +from wand.image import Image +from tempfile import NamedTemporaryFile, TemporaryDirectory + +from rq import get_current_job + +from docsbox import app, rq +from docsbox.docs.utils import make_zip_archive, make_thumbnails + + + +@rq.job(timeout=app.config["REDIS_JOB_TIMEOUT"]) +def remove_file(path): + """ + Just removes a file. + Used for deleting original files (uploaded by user) and result files (result of converting) + """ + return os.remove(path) + + +@rq.job(timeout=app.config["REDIS_JOB_TIMEOUT"]) +def process_document(path, options, meta): + current_task = get_current_job() + with Office(app.config["LIBREOFFICE_PATH"]) as office: # acquire libreoffice lock + with office.documentLoad(path) as original_document: # open original document + with TemporaryDirectory() as tmp_dir: # create temp dir where output'll be stored + for fmt in options["formats"]: # iterate over requested formats + current_format = app.config["SUPPORTED_FORMATS"][fmt] + output_path = os.path.join(tmp_dir, current_format["path"]) + original_document.saveAs(output_path, fmt=current_format["fmt"]) + if options.get("thumbnails", None): + is_created = False + if meta["mimetype"] == "application/pdf": + pdf_path = path + elif "pdf" in options["formats"]: + pdf_path = os.path.join(tmp_dir, "pdf") + else: + pdf_tmp_file = NamedTemporaryFile() + pdf_path = pdf_tmp_file.name + original_document.saveAs(pdf_tmp_file.name, fmt="pdf") + is_created = True + image = Image(filename=pdf_path, + resolution=app.config["THUMBNAILS_DPI"]) + if is_created: + pdf_tmp_file.close() + thumbnails = make_thumbnails(image, tmp_dir, options["thumbnails"]["size"]) + result_path, result_url = make_zip_archive(current_task.id, tmp_dir) + remove_file.schedule( + datetime.timedelta(seconds=app.config["RESULT_FILE_TTL"]), + result_path + ) + return result_url diff --git a/docsbox-master/docsbox/docs/tests/samples/sample.docx b/docsbox-master/docsbox/docs/tests/samples/sample.docx new file mode 100644 index 0000000000000000000000000000000000000000..8d78118f90e0fae3dd28cba99aeb2a88c5cc1b9c GIT binary patch literal 215696 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