diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 00000000..aaf40731 --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,28 @@ +--- +name: Build to Docker Hub + +on: + push: + branches: [master] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout the repository + uses: actions/checkout@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + - name: Build & publish the project + run: mvn compile jib:build -X -DjibSerialize=true diff --git a/.github/workflows/maven-build.yml b/.github/workflows/maven-build.yml new file mode 100644 index 00000000..3651346b --- /dev/null +++ b/.github/workflows/maven-build.yml @@ -0,0 +1,23 @@ +name: Java CI with Maven + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 17 + uses: actions/setup-java@v2 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + - name: Build with Maven + run: mvn -B install --file pom.xml -Djacoco.skip=true -DdisableXmlReport=true diff --git a/.gitignore b/.gitignore index 3ab8ef2c..ad07b8f6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ target/* .idea *.iml /target -npm-debug.log -/bin/ -client/* \ No newline at end of file + +generated/ + +# Easier branch switching +springboot-petclinic-client/ +springboot-petclinic-server/ diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 00000000..b901097f --- /dev/null +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,117 @@ +/* + * Copyright 2007-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + private static final String WRAPPER_VERSION = "0.5.6"; + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { + String username = System.getenv("MVNW_USERNAME"); + char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + } + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar index c6feb8bb..2cc7d4a5 100644 Binary files a/.mvn/wrapper/maven-wrapper.jar and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 25cc8af3..642d572c 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1 +1,2 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/client/package-lock.json b/client/package-lock.json new file mode 100644 index 00000000..ada191e5 --- /dev/null +++ b/client/package-lock.json @@ -0,0 +1,13231 @@ +{ + "name": "spring-petclinic-reactjs", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "spring-petclinic-reactjs", + "version": "0.0.1", + "hasInstallScript": true, + "license": "ISC", + "dependencies": { + "@types/moment": "^2.13.0", + "bootstrap": "^3.3.7", + "classnames": "^2.2.5", + "moment": "^2.15.1", + "react": "^15.0.0", + "react-datepicker": "^0.29.0", + "react-dom": "^15.0.0", + "react-router": "^2.7.0", + "redbox-react": "^1.2.3", + "whatwg-fetch": "^1.0.0" + }, + "devDependencies": { + "babel-core": "^6.4.0", + "babel-loader": "^6.2.1", + "babel-preset-es2015": "^6.3.13", + "babel-preset-react": "^6.3.13", + "babel-preset-stage-0": "^6.3.13", + "chalk": "^1.1.3", + "cross-env": "^1.0.7", + "css-loader": "^0.23.1", + "enzyme": "^2.5.1", + "extract-text-webpack-plugin": "^1.0.1", + "file-loader": "^0.9.0", + "jest": "^16.0.1", + "jest-fetch-mock": "^1.0.6", + "less": "^2.7.1", + "less-loader": "^2.2.3", + "react-addons-test-utils": "^15.3.2", + "react-hot-loader": "^3.0.0-beta.0", + "rimraf": "^2.5.0", + "style-loader": "^0.13.0", + "ts-jest": "^0.1.8", + "ts-loader": "^0.8.2", + "tslint": "^3.15.1", + "tslint-loader": "^2.1.5", + "typescript": "~2.0.2", + "typings": "^1.3.2", + "url-loader": "^0.5.7", + "webpack": "^1.12.10", + "webpack-dev-server": "^1.14.1" + } + }, + "node_modules/@types/moment": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@types/moment/-/moment-2.13.0.tgz", + "integrity": "sha512-DyuyYGpV6r+4Z1bUznLi/Y7HpGn4iQ4IVcGn8zrr1P4KotKLdH0sbK1TFR6RGyX6B+G8u83wCzL+bpawKU/hdQ==", + "deprecated": "This is a stub types definition for Moment (https://github.com/moment/moment). Moment provides its own type definitions, so you don't need @types/moment installed!", + "dependencies": { + "moment": "*" + } + }, + "node_modules/abab": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", + "integrity": "sha512-I+Wi+qiE2kUXyrRhNsWv6XsjUTBJjSoVSctKNBfLG5zG/Xe7Rjbxf13+vqYHNTwHaFU+FtSlVxOCTiMEVtPv0A==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha512-fu2ygVGuMmlzG8ZeRJ0bvR41nsAkxxhbyk8bZ1SS521Z7vmgJFTQQlfz/Mp/nJexGBz+v8sC9bM6+lNgskt4Ug==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", + "integrity": "sha512-uWttZCk96+7itPxK8xCzY86PnxKTMrReKDqrHzv42VQY0K30PUO8WY13WMOuI+cOdX4EIdzdvQ8k6jkuGRFMYw==", + "dev": true, + "dependencies": { + "acorn": "^4.0.4" + } + }, + "node_modules/agent-base": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", + "integrity": "sha512-oDtZV740o3fr5oJtPLOsgH2hl2TRPscNXIx4VzzBwVlXVkv8RHm7XXqGAYg8t20+Gwu6LNDnx8HRMGqVGPZ8Vw==", + "dev": true, + "dependencies": { + "extend": "~3.0.0", + "semver": "~5.0.1" + } + }, + "node_modules/agent-base/node_modules/semver": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", + "integrity": "sha512-5OkOBiw69xqmxOFIXwXsiY1HlE+om8nNptg1ZIf95fzcnfgOv2fLm7pmmGbRJsjJIqPpW5Kwy4wpDBTz5wQlUw==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha512-GrTZLRpmp6wIC2ztrWW9MjjTgSKccffgFagbNDOX95/dcjEcYZibYTeaOntySQLcdw1ztBoFkviiUvTMbb9MYg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==", + "dev": true + }, + "node_modules/amdefine": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz", + "integrity": "sha512-AhIk36FIyH9lsHdzXxwo/aWm1QQIChd1cewUHtC2E4hczLKgT/WpVJMZGxKwkvW07p1Bn2gxwRFPeeguHocrQA==", + "dev": true, + "engines": { + "node": ">=0.4.2" + } + }, + "node_modules/ansi-align": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-1.1.0.tgz", + "integrity": "sha512-ncgIO/ZeFcsh3cye0NgGPb5h/3vCiKJxp6HvPtqsFvEL/4b/G2tNgrr8EOYN5RSVnGx69k8dFYSBG/w1yKX58Q==", + "dev": true, + "dependencies": { + "string-width": "^1.0.1" + } + }, + "node_modules/ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha512-wiXutNjDUlNEDWHcYH3jtZUhd3c4/VojassD8zHdHCY13xbZy2XbW+NKQwA0tWGBVzDA9qEzYwfoSsWmviidhw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==", + "dev": true, + "dependencies": { + "ansi-wrap": "0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "node_modules/anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "dependencies": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "node_modules/append-transform": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", + "integrity": "sha512-Yisb7ew0ZEyDtRYQ+b+26o9KbiYPFxwcsxKzbssigzRRMJ9LpExPVUg6Fos7eP7yP3q7///tzze4nm4lTptPBw==", + "dev": true, + "dependencies": { + "default-require-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha512-dtXTVMkh6VkEEA7OhXnN1Ecb8aAGFdZ1LFxtOCoqj4qkyOJMt7+qs6Ahdy6p/NQCPYsRSXXivhSB/J5E9jmYKA==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha512-LeZY+DZDRnvP7eMuQ6LHfCzUGxAAIViUBliK24P3hWXL6y4SortgR6Nim6xrkfSLlmH0+k+9NYNwVC2s53ZrYQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-equal": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.2.tgz", + "integrity": "sha512-gUHx76KtnhEgB3HOuFYiCm3FIdEs6ocM2asHvNTkfu/Y09qQVrrVVaOKENmS2KkSaGoxgXNqC+ZVtR/n0MOkSA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha512-G2n5bG5fSUCpnsXz4+8FUkYsGPkNfLn9YvS66U5qbTIXI2Ynnlo4Bi42bWv+omKUCqz+ejzfClwne0alJWJPhg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.1.tgz", + "integrity": "sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==", + "dev": true, + "dependencies": { + "object.assign": "^4.1.4", + "util": "^0.10.4" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "dev": true + }, + "node_modules/async-each": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", + "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/autoprefixer": { + "version": "6.7.7", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", + "integrity": "sha512-WKExI/eSGgGAkWAO+wMVdFObZV7hQen54UpD1kCCTN3tvlL3W1jL4+lPP/M7MwoP7Q4RHzKtO3JQ4HxYEcd+xQ==", + "dev": true, + "dependencies": { + "browserslist": "^1.7.6", + "caniuse-db": "^1.0.30000634", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^5.2.16", + "postcss-value-parser": "^3.2.3" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true + }, + "node_modules/babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "node_modules/babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "dependencies": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + } + }, + "node_modules/babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dev": true, + "dependencies": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + } + }, + "node_modules/babel-helper-bindify-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", + "integrity": "sha512-TYX2QQATKA6Wssp6j7jqlw4QLmABDN1olRdEHndYvBXdaXM5dcx6j5rN0+nd+aVL+Th40fAEYvvw/Xxd/LETuQ==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q==", + "dev": true, + "dependencies": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-builder-react-jsx": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz", + "integrity": "sha512-02I9jDjnVEuGy2BR3LRm9nPRb/+Ja0pvZVLr1eI5TYAA/dB0Xoc+WBo50+aDfhGDLhlBY1+QURjn9uvcFd8gzg==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "esutils": "^2.0.2" + } + }, + "node_modules/babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ==", + "dev": true, + "dependencies": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA==", + "dev": true, + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-explode-class": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", + "integrity": "sha512-SFbWewr0/0U4AiRzsHqwsbOQeLXVa9T1ELdqEa2efcQB5KopTnunAqoj07TuHlN2lfTQNPGO/rJR4FMln5fVcA==", + "dev": true, + "dependencies": { + "babel-helper-bindify-decorators": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==", + "dev": true, + "dependencies": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg==", + "dev": true, + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw==", + "dev": true, + "dependencies": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-jest": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-16.0.0.tgz", + "integrity": "sha512-OidQkHIpI7gxMG+8UAPPutQFY5EwlNOqDOWH6wA5l6nr+Vd0O8TQvei0MoU/1HbE+qeFoqEofyZ/vcTsYfmhnA==", + "dev": true, + "dependencies": { + "babel-core": "^6.0.0", + "babel-plugin-istanbul": "^2.0.0", + "babel-preset-jest": "^16.0.0" + } + }, + "node_modules/babel-loader": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-6.4.1.tgz", + "integrity": "sha512-hHvbCsXtwKIznu5Qmqfe/IwZ4O5frqe+j04fN/5u/9Rg48dpWIKyYqAN68N1wwqGSMToo4FhU9/MrH+QZlFdkQ==", + "dev": true, + "dependencies": { + "find-cache-dir": "^0.1.1", + "loader-utils": "^0.2.16", + "mkdirp": "^0.5.1", + "object-assign": "^4.0.1" + }, + "peerDependencies": { + "babel-core": "^6.0.0", + "webpack": "1 || 2 || ^2.1.0-beta || ^2.2.0-rc" + } + }, + "node_modules/babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-2.0.3.tgz", + "integrity": "sha512-JGofIg9i4uReQiYzEZuFUcHIheHG6FTEqaewpfa9+NbPmuVrGoDdLJR0u/fp7oJ0V9eRSRRAXM9ZFCdnXJgjWw==", + "dev": true, + "dependencies": { + "find-up": "^1.1.2", + "istanbul-lib-instrument": "^1.1.4", + "object-assign": "^4.1.0", + "test-exclude": "^2.1.1" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-16.0.0.tgz", + "integrity": "sha512-Kcg63kNYotzS1/S1dv8OSEwLq8t2sQqAQ7bvoFMkAWgp4xQ3lmmC745sxv7c5a0BvbJkFTmKKzlnkJSsmNQCHw==", + "dev": true + }, + "node_modules/babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw==", + "dev": true + }, + "node_modules/babel-plugin-syntax-async-generators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", + "integrity": "sha512-EbciFN5Jb9iqU9bqaLmmFLx2G8pAUsvpWJ6OzOWBNrSY9qTohXj+7YfZx6Ug1Qqh7tCb1EA7Jvn9bMC1HBiucg==", + "dev": true + }, + "node_modules/babel-plugin-syntax-class-constructor-call": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz", + "integrity": "sha512-EEuBcXz/wZ81Jaac0LnMHtD4Mfz9XWn2oH2Xj+CHwz2SZWUqqdtR2BgWPSdTGMmxN/5KLSh4PImt9+9ZedDarA==", + "dev": true + }, + "node_modules/babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "integrity": "sha512-chI3Rt9T1AbrQD1s+vxw3KcwC9yHtF621/MacuItITfZX344uhQoANjpoSJZleAmW2tjlolqB/f+h7jIqXa7pA==", + "dev": true + }, + "node_modules/babel-plugin-syntax-decorators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", + "integrity": "sha512-AWj19x2aDm8qFQ5O2JcD6pwJDW1YdcnO+1b81t7gxrGjz5VHiUqeYWAR4h7zueWMalRelrQDXprv2FrY1dbpbw==", + "dev": true + }, + "node_modules/babel-plugin-syntax-do-expressions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz", + "integrity": "sha512-HD/5qJB9oSXzl0caxM+aRD7ENICXqcc3Up/8toDQk7zNIDE7TzsqtxC5f4t9Rwhu2Ya8l9l4j6b3vOsy+a6qxg==", + "dev": true + }, + "node_modules/babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha512-MioUE+LfjCEz65Wf7Z/Rm4XCP5k2c+TbMd2Z2JKc7U9uwjBhAfNPE48KC4GTGKhppMeYVepwDBNO/nGY6NYHBA==", + "dev": true + }, + "node_modules/babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ==", + "dev": true + }, + "node_modules/babel-plugin-syntax-export-extensions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz", + "integrity": "sha512-Eo0rcRaIDMld/W6mVhePiudIuLW+Cr/8eveW3mBREfZORScZgx4rh6BAPyvzdEc/JZvQ+LkC80t0VGFs6FX+lg==", + "dev": true + }, + "node_modules/babel-plugin-syntax-flow": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", + "integrity": "sha512-HbTDIoG1A1op7Tl/wIFQPULIBA61tsJ8Ntq2FAhLwuijrzosM/92kAfgU1Q3Kc7DH/cprJg5vDfuTY4QUL4rDA==", + "dev": true + }, + "node_modules/babel-plugin-syntax-function-bind": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz", + "integrity": "sha512-m8yMoh9LIiNyeLdQs5I9G+3YXo4nqVsKQkk7YplrG4qAFbNi9hkZlow8HDHxhH9QOVFPHmy8+03NzRCdyChIKw==", + "dev": true + }, + "node_modules/babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==", + "dev": true + }, + "node_modules/babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha512-C4Aq+GaAj83pRQ0EFgTvw5YO6T3Qz2KGrNRwIj9mSoNHVvdZY4KO2uA6HNtNXCw993iSZnckY1aLW8nOi8i4+w==", + "dev": true + }, + "node_modules/babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ==", + "dev": true + }, + "node_modules/babel-plugin-transform-async-generator-functions": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", + "integrity": "sha512-uT7eovUxtXe8Q2ufcjRuJIOL0hg6VAUJhiWJBLxH/evYAw+aqoJLcYTR8hqx13iOx/FfbCMHgBmXWZjukbkyPg==", + "dev": true, + "dependencies": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-generators": "^6.5.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw==", + "dev": true, + "dependencies": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-class-constructor-call": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz", + "integrity": "sha512-RvYukT1Nh7njz8P8326ztpQUGCKwmjgu6aRIx1lkvylWITYcskg29vy1Kp8WXIq7FvhXsz0Crf2kS94bjB690A==", + "dev": true, + "dependencies": { + "babel-plugin-syntax-class-constructor-call": "^6.18.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-class-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", + "integrity": "sha512-n4jtBA3OYBdvG5PRMKsMXJXHfLYw/ZOmtxCLOOwz6Ro5XlrColkStLnz1AS1L2yfPA9BKJ1ZNlmVCLjAL9DSIg==", + "dev": true, + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-plugin-syntax-class-properties": "^6.8.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", + "integrity": "sha512-skQ2CImwDkCHu0mkWvCOlBCpBIHW4/49IZWVwV4A/EnWjL9bB6UBvLyMNe3Td5XDStSZNhe69j4bfEW8dvUbew==", + "dev": true, + "dependencies": { + "babel-helper-explode-class": "^6.24.1", + "babel-plugin-syntax-decorators": "^6.13.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-do-expressions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz", + "integrity": "sha512-yQwYqYg+Tnj1InA8W1rsItsZVhkv1Euc4KVua9ledtPz5PDWYz7LVyy6rDBpVYUWFZj5k6GUm3YZpCbIm8Tqew==", + "dev": true, + "dependencies": { + "babel-plugin-syntax-do-expressions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag==", + "dev": true, + "dependencies": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg==", + "dev": true, + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA==", + "dev": true, + "dependencies": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "dev": true, + "dependencies": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "node_modules/babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg==", + "dev": true, + "dependencies": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw==", + "dev": true, + "dependencies": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA==", + "dev": true, + "dependencies": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ==", + "dev": true, + "dependencies": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ==", + "dev": true, + "dependencies": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ==", + "dev": true, + "dependencies": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "node_modules/babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ==", + "dev": true, + "dependencies": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-export-extensions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz", + "integrity": "sha512-mtzELzINaYqdVglyZrDDVwkcFRuE7s6QUFWXxwffKAHB/NkfbJ2NJSytugB43ytIC8UVt30Ereyx+7gNyTkDLg==", + "dev": true, + "dependencies": { + "babel-plugin-syntax-export-extensions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-flow-strip-types": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", + "integrity": "sha512-TxIM0ZWNw9oYsoTthL3lvAK3+eTujzktoXJg4ubGvICGbVuXVYv5hHv0XXpz8fbqlJaGYY4q5SVzaSmsg3t4Fg==", + "dev": true, + "dependencies": { + "babel-plugin-syntax-flow": "^6.18.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-function-bind": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz", + "integrity": "sha512-9Ec4KYf1GurT39mlUjDSlN7HWSlB3u3mWRMogQbb+Y88lO0ZM3rJ0ADhPnQwWK9TbO6e/4E+Et1rrfGY9mFimA==", + "dev": true, + "dependencies": { + "babel-plugin-syntax-function-bind": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha512-ocgA9VJvyxwt+qJB0ncxV8kb/CjfTcECUY4tQ5VT7nP6Aohzobm8CDFaQ5FHdvZQzLmf0sgDxB8iRXZXxwZcyA==", + "dev": true, + "dependencies": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "node_modules/babel-plugin-transform-react-display-name": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", + "integrity": "sha512-QLYkLiZeeED2PKd4LuXGg5y9fCgPB5ohF8olWUuETE2ryHNRqqnXlEVP7RPuef89+HTfd3syptMGVHeoAu0Wig==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-react-jsx": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", + "integrity": "sha512-s+q/Y2u2OgDPHRuod3t6zyLoV8pUHc64i/O7ZNgIOEdYTq+ChPeybcKBi/xk9VI60VriILzFPW+dUxAEbTxh2w==", + "dev": true, + "dependencies": { + "babel-helper-builder-react-jsx": "^6.24.1", + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-react-jsx-self": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz", + "integrity": "sha512-Y3ZHP1nunv0U1+ysTNwLK39pabHj6cPVsfN4TRC7BDBfbgbyF4RifP5kd6LnbuMV9wcfedQMe7hn1fyKc7IzTQ==", + "dev": true, + "dependencies": { + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-react-jsx-source": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz", + "integrity": "sha512-pcDNDsZ9q/6LJmujQ/OhjeoIlp5Nl546HJ2yiFIJK3mYpgNXhI5/S9mXfVxu5yqWAi7HdI7e/q6a9xtzwL69Vw==", + "dev": true, + "dependencies": { + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg==", + "dev": true, + "dependencies": { + "regenerator-transform": "^0.10.0" + } + }, + "node_modules/babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-preset-es2015": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", + "integrity": "sha512-XfwUqG1Ry6R43m4Wfob+vHbIVBIqTg/TJY4Snku1iIzeH7mUnwHA8Vagmv+ZQbPwhS8HgsdQvy28Py3k5zpoFQ==", + "deprecated": "🙌 Thanks for using Babel: we recommend using babel-preset-env now: please read https://babeljs.io/env to update!", + "dev": true, + "dependencies": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.24.1", + "babel-plugin-transform-es2015-classes": "^6.24.1", + "babel-plugin-transform-es2015-computed-properties": "^6.24.1", + "babel-plugin-transform-es2015-destructuring": "^6.22.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", + "babel-plugin-transform-es2015-for-of": "^6.22.0", + "babel-plugin-transform-es2015-function-name": "^6.24.1", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-umd": "^6.24.1", + "babel-plugin-transform-es2015-object-super": "^6.24.1", + "babel-plugin-transform-es2015-parameters": "^6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", + "babel-plugin-transform-regenerator": "^6.24.1" + } + }, + "node_modules/babel-preset-flow": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", + "integrity": "sha512-PQZFJXnM3d80Vq4O67OE6EMVKIw2Vmzy8UXovqulNogCtblWU8rzP7Sm5YgHiCg4uejUxzCkHfNXQ4Z6GI+Dhw==", + "dev": true, + "dependencies": { + "babel-plugin-transform-flow-strip-types": "^6.22.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-16.0.0.tgz", + "integrity": "sha512-ZpQDoNEsWMOMBdQVXjhD224zq+9SfFlA72oj+PwBPiAaX900jdEiDnnW3mG88KqGHvsVI30WV2qmhpkkoMa1Hg==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^16.0.0" + } + }, + "node_modules/babel-preset-react": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", + "integrity": "sha512-phQe3bElbgF887UM0Dhz55d22ob8czTL1kbhZFwpCE6+R/X9kHktfwmx9JZb+bBSVRGphP5tZ9oWhVhlgjrX3Q==", + "dev": true, + "dependencies": { + "babel-plugin-syntax-jsx": "^6.3.13", + "babel-plugin-transform-react-display-name": "^6.23.0", + "babel-plugin-transform-react-jsx": "^6.24.1", + "babel-plugin-transform-react-jsx-self": "^6.22.0", + "babel-plugin-transform-react-jsx-source": "^6.22.0", + "babel-preset-flow": "^6.23.0" + } + }, + "node_modules/babel-preset-stage-0": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz", + "integrity": "sha512-MJD+xBbpsApbKlzAX0sOBF+VeFaUmv5s8FSOO7SSZpes1QgphCjq/UIGRFWSmQ/0i5bqQjLGCTXGGXqcLQ9JDA==", + "dev": true, + "dependencies": { + "babel-plugin-transform-do-expressions": "^6.22.0", + "babel-plugin-transform-function-bind": "^6.22.0", + "babel-preset-stage-1": "^6.24.1" + } + }, + "node_modules/babel-preset-stage-1": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz", + "integrity": "sha512-rn+UOcd7BHDniq1SVxv2/AVVSVI1NK+hfS0I/iR6m6KbOi/aeBRcqBilqO73pd9VUpRXF2HFtlDuC9F2BEQqmg==", + "dev": true, + "dependencies": { + "babel-plugin-transform-class-constructor-call": "^6.24.1", + "babel-plugin-transform-export-extensions": "^6.22.0", + "babel-preset-stage-2": "^6.24.1" + } + }, + "node_modules/babel-preset-stage-2": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", + "integrity": "sha512-9F+nquz+37PrlTSBdpeQBKnQfAMNBnryXw+m4qBh35FNbJPfzZz+sjN2G5Uf1CRedU9PH7fJkTbYijxmkLX8Og==", + "dev": true, + "dependencies": { + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-decorators": "^6.24.1", + "babel-preset-stage-3": "^6.24.1" + } + }, + "node_modules/babel-preset-stage-3": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", + "integrity": "sha512-eCbEOF8uN0KypFXJmZXn2sTk7bPV9uM5xov7G/7BM08TbQEObsVs0cEWfy6NQySlfk7JBi/t+XJP1JkruYfthA==", + "dev": true, + "dependencies": { + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-generator-functions": "^6.24.1", + "babel-plugin-transform-async-to-generator": "^6.24.1", + "babel-plugin-transform-exponentiation-operator": "^6.24.1", + "babel-plugin-transform-object-rest-spread": "^6.22.0" + } + }, + "node_modules/babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==", + "dev": true, + "dependencies": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + } + }, + "node_modules/babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "dev": true, + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", + "dev": true, + "dependencies": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "node_modules/babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true, + "bin": { + "babylon": "bin/babylon.js" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha512-3vqtKL1N45I5dV0RdssXZG7X6pCqQrWPNOlBPZPrd+QkE2HEhR57Z04m0KtpbsZH73j+a3F8UD1TQnn+ExTvIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha512-KbiZEa9/vofNcVJXGwdWWn25reQ3V3dHBWbS07FTF3/TOehLnm9GEhJV4T6ZvGPkShRpmUqYwnaCrkj0mRnP6Q==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dev": true, + "optional": true, + "dependencies": { + "hoek": "2.x.x" + }, + "engines": { + "node": ">=0.10.40" + } + }, + "node_modules/bootstrap": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz", + "integrity": "sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/boxen": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-0.6.0.tgz", + "integrity": "sha512-yL8sYzt0avlYGOY6LqtECkGrJOY3cCLAbFPaNfgE+4fD45ZrdYqLdY8yF4bqyTkpfW9e6W0YqBkN7dIn/PrZoA==", + "dev": true, + "dependencies": { + "ansi-align": "^1.1.0", + "camelcase": "^2.1.0", + "chalk": "^1.1.1", + "cli-boxes": "^1.0.0", + "filled-array": "^1.0.0", + "object-assign": "^4.0.1", + "repeating": "^2.0.0", + "string-width": "^1.0.1", + "widest-line": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha512-xU7bpz2ytJl1bH9cgIurjpg/n8Gohy9GTw81heDYLJQ4RU60dlyJsa+atVF2pI0yMMvKxI9HkKwjePCj5XI1hw==", + "dev": true, + "dependencies": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "dependencies": { + "resolve": "1.1.7" + } + }, + "node_modules/browserify-aes": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-0.4.0.tgz", + "integrity": "sha512-hnvbMhZ/Ete34qnoKKyjikiYQfZbl89d5UZ29cz3EG13cv/8VRyM8Zs84luB/O7BRzC3qSng9dVovJ6jghcAvg==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1" + } + }, + "node_modules/browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==", + "dev": true, + "dependencies": { + "pako": "~0.2.0" + } + }, + "node_modules/browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha512-qHJblDE2bXVRYzuDetv/wAeHOJyO97+9wxC1cdCtyzgNuSozOyRCiiLaCR1f71AN66lQdVVBipWm63V+a7bPOw==", + "deprecated": "Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.", + "dev": true, + "dependencies": { + "caniuse-db": "^1.0.30000639", + "electron-to-chromium": "^1.2.7" + }, + "bin": { + "browserslist": "cli.js" + } + }, + "node_modules/bser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bser/-/bser-1.0.2.tgz", + "integrity": "sha512-kKi2swDowbCsnwsYyJnMkz3N1utuJfnWcvzxVX45nWuumTNEkig97rvLVN60+8OWgAWuJdIyEfTPTZqyPoklwA==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/buffer/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cache-base/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ==", + "dev": true, + "dependencies": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/caniuse-api": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", + "integrity": "sha512-SBTl70K0PkDUIebbkXrxWqZlHNs0wRgRD6QZ8guctShjbh63gEPfF+Wj0Yw+75f5Y8tSzqAI/NcisYv/cCah2Q==", + "dev": true, + "dependencies": { + "browserslist": "^1.3.6", + "caniuse-db": "^1.0.30000529", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-db": { + "version": "1.0.30001596", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30001596.tgz", + "integrity": "sha512-cMrDbhsAuEClQVtJLAZN7DjsQDlbtWktRImpyEHpOtWly152rk0TMXw6CAy3aB056JiQs3FUAnOjVVlw3S0gnQ==", + "dev": true + }, + "node_modules/capture-stack-trace": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.2.tgz", + "integrity": "sha512-X/WM2UQs6VMHUtjUDnZTRI+i1crWteJySFzr9UpGoQa4WQffXVTTXuekjl7TjZRlcF2XfjgITT0HxZ9RnxeT0w==", + "dev": true, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dev": true, + "dependencies": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + }, + "bin": { + "cdl": "bin/cdl.js" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "node_modules/center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha512-Baz3aNe2gd2LP2qk5U+sDk/m4oSuwSDcBfayTCTBoWpfIGO5XFxPmjILQII4NGiZjD6DoDI6kf7gKaxkf7s3VQ==", + "dev": true, + "dependencies": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cheerio": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA==", + "dev": true, + "dependencies": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha512-mk8fAWcRUOxY7btlLtitj3A45jOwSAxH4tOFOoEGbVsl6cL6pPMWUy7dwZ/canfj3QEdP6FHSnf/l1c6/WkzVg==", + "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", + "dev": true, + "dependencies": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + }, + "optionalDependencies": { + "fsevents": "^1.0.0" + } + }, + "node_modules/ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "node_modules/clap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz", + "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/class-utils/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + }, + "node_modules/cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha512-3Fo5wu8Ytle8q9iCzS4D2MWVL2X7JVWRiS1BnXbTFDhS9c/REkM9vd1AmabsoZoY5/dGi5TT9iKL8Kb6DeBRQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha512-25tABq090YNKkF6JH7lcwO0zFJTRke4Jcq9iX2nr/Sz0Cjjv4gckmwlW6Ty/aoyFd6z3ysR2hMGC2GFugmBo6A==", + "dev": true, + "dependencies": { + "restore-cursor": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-table": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz", + "integrity": "sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==", + "dev": true, + "dependencies": { + "colors": "1.0.3" + }, + "engines": { + "node": ">= 0.2.0" + } + }, + "node_modules/cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha512-f4r4yJnbT++qUPI9NR4XLDLq41gQ+uqnPItWG0F5ZkehuNiTTa3EY0S4AqTSUOeJ7/zU41oWPQSNkW5BqPL9bg==", + "dev": true, + "dependencies": { + "slice-ansi": "0.0.4", + "string-width": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-usage": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/cli-usage/-/cli-usage-0.1.10.tgz", + "integrity": "sha512-Q/s1S4Jz5LYI0LQ+XiFQCXkhMzn244ddyIffni8JIq/kL95DvQomVQ0cJC41c76hH9/FmZGY7rZB53y/bXHtRA==", + "dev": true, + "dependencies": { + "marked": "^0.7.0", + "marked-terminal": "^3.3.0" + } + }, + "node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha512-dhUqc57gSMCo6TX85FLfe51eC/s+Im2MLkAgJwfaRRexR2tA4dd3eLEW4L6efzHc2iNorrRRXITifnDLlRrhaA==", + "dev": true + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "optional": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/coa": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", + "integrity": "sha512-KAGck/eNAmCL0dcT3BiuYwLbExK6lduR8DxM3C1TyDzaXhZHyZ8ooX5I5+na2e3dPFuibfxrGdorr0/Lr7RYCQ==", + "dev": true, + "dependencies": { + "q": "^1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", + "integrity": "sha512-Ajpjd8asqZ6EdxQeqGzU5WBhhTfJ/0cA4Wlbre7e5vXfmDSmda7Ov6jeKoru+b0vHcb1CqvuroTHp5zIWzhVMA==", + "dev": true, + "dependencies": { + "clone": "^1.0.2", + "color-convert": "^1.3.0", + "color-string": "^0.3.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/color-string": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz", + "integrity": "sha512-sz29j1bmSDfoAxKIEU6zwoIZXN6BrFbAMIhfYCNyiZXBDuU/aiHlN84lp/xDzL2ubyFhLDobHIlU1X70XRrMDA==", + "dev": true, + "dependencies": { + "color-name": "^1.0.0" + } + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/colormin": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", + "integrity": "sha512-XSEQUUQUR/lXqGyddiNH3XYFUPYlYr1vXy9rTFMsSOw+J7Q6EQkdlQIrTlYn4TccpsOaUE1PYQNjBn20gwCdgQ==", + "dev": true, + "dependencies": { + "color": "^0.11.0", + "css-color-names": "0.0.4", + "has": "^1.0.1" + } + }, + "node_modules/colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/columnify": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz", + "integrity": "sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==", + "dev": true, + "dependencies": { + "strip-ansi": "^6.0.1", + "wcwidth": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/columnify/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/columnify/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/configstore": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-2.1.0.tgz", + "integrity": "sha512-BOCxwwxF5WPspp1OBq9j0JLyL5JgJOTssz9PdOHr8VWjFijaC3PpjU48vFEX3uxx8sTusnVQckLbNzBq6fmkGw==", + "dev": true, + "dependencies": { + "dot-prop": "^3.0.0", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "object-assign": "^4.0.1", + "os-tmpdir": "^1.0.0", + "osenv": "^0.1.0", + "uuid": "^2.0.1", + "write-file-atomic": "^1.1.2", + "xdg-basedir": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/configstore/node_modules/uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha512-FULf7fayPdpASncVy4DLh3xydlXEJJpvIELjYjNeQWYUZ9pclcpvCZSr2gkmN2FrrGcI7G/cJsIEwk5/8vfXpg==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true + }, + "node_modules/connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type-parser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz", + "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "dev": true, + "hasInstallScript": true + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, + "node_modules/create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha512-gYTKKexFO3kh200H1Nit76sRwRtOY32vQd3jpAQKpLtZqyNsSQNfI4N7o3eP2wUjV35pTWKRYqFUDBvUha/Pkw==", + "dev": true, + "dependencies": { + "capture-stack-trace": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/create-react-class": { + "version": "15.7.0", + "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.7.0.tgz", + "integrity": "sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng==", + "dependencies": { + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" + } + }, + "node_modules/cross-env": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-1.0.8.tgz", + "integrity": "sha512-wh0Rw3oDAUoyf5iih0B9tqKhgXcDnWcXVA6nzNjwwwtzWktjjKRvL6WxjaJe9LX3PJGMMO+jtlOWawHn4wvJTg==", + "dev": true, + "dependencies": { + "cross-spawn": "^3.0.1", + "lodash.assign": "^3.2.0" + }, + "bin": { + "cross-env": "bin/cross-env.js" + } + }, + "node_modules/cross-fetch": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.6.tgz", + "integrity": "sha512-9JZz+vXCmfKUZ68zAptS7k4Nu8e2qcibe7WVZYps7sAgk5R8GYTc+T1WR0v1rlP9HxgARmOX1UTIJZFytajpNA==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.7", + "whatwg-fetch": "^2.0.4" + } + }, + "node_modules/cross-fetch/node_modules/whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha512-eZ+m1WNhSZutOa/uRblAc9Ut5MQfukFrFMtPSm3bZCA888NmMd5AWXWdgRZ80zd+pTk1P2JrGjg9pUPTvl2PWQ==", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "node_modules/cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha512-FFN5KwpvvQTTS5hWPxrU8/QE4kQUc6uwZcrnlMBN82t1MgAtq8mnoDwINBly9Tdr02seeIIhtdF+UH1feBYGog==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dev": true, + "optional": true, + "dependencies": { + "boom": "2.x.x" + }, + "engines": { + "node": ">=0.10.40" + } + }, + "node_modules/crypto-browserify": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.3.0.tgz", + "integrity": "sha512-9n5nGl6D8zb29Ui8Ji8pVdUIE3RUe6A9zQf2iLPjFKftnkkkJBCGb7TkYAFNjt9nfsvZTLL52CwxzS9Tw7Bujw==", + "dev": true, + "dependencies": { + "browserify-aes": "0.4.0", + "pbkdf2-compat": "2.0.1", + "ripemd160": "0.2.0", + "sha.js": "2.2.6" + }, + "engines": { + "node": "*" + } + }, + "node_modules/css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha512-zj5D7X1U2h2zsXOAM8EyUREBnnts6H+Jm+d1M2DbiQQcUtnqgQsMrdo8JW9R80YFUmIdBZeMu5wvYM7hcgWP/Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/css-loader": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.23.1.tgz", + "integrity": "sha512-626EYKVoY9Jf61On3M6uZHeu2CddHqc4F/C3b7Ingc6Z9YYeCr2QF9aVhSY3GO0SlLX48y4/m4rLkyY7BnkGnw==", + "dev": true, + "dependencies": { + "css-selector-tokenizer": "^0.5.1", + "cssnano": ">=2.6.1 <4", + "loader-utils": "~0.2.2", + "lodash.camelcase": "^3.0.1", + "object-assign": "^4.0.1", + "postcss": "^5.0.6", + "postcss-modules-extract-imports": "^1.0.0", + "postcss-modules-local-by-default": "^1.0.1", + "postcss-modules-scope": "^1.0.0", + "postcss-modules-values": "^1.1.0", + "source-list-map": "^0.1.4" + } + }, + "node_modules/css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "node_modules/css-selector-tokenizer": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.5.4.tgz", + "integrity": "sha512-4KF0VPHT7x/rSPnmUJ/wSzx1AVRnQAUVcuHJnlR2vo8ZKKp1oSh77iD7S/0PSwvMlBIdre0cTeFwWKvq7pn3KA==", + "dev": true, + "dependencies": { + "cssesc": "^0.1.0", + "fastparse": "^1.1.1" + } + }, + "node_modules/css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/cssesc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", + "integrity": "sha512-72avb2vCIsNDBlSMYuxt2Cmg6Z4TTGqifblGs7IXGihhuEzghCb9Pu1Y6vzVPLC03OTXnAKsTm92ChZd4uzVBQ==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + } + }, + "node_modules/cssnano": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "integrity": "sha512-0o0IMQE0Ezo4b41Yrm8U6Rp9/Ag81vNXY1gZMnT1XhO4DpjEf2utKERqWJbOoz3g1Wdc1d3QSta/cIuJ1wSTEg==", + "dev": true, + "dependencies": { + "autoprefixer": "^6.3.1", + "decamelize": "^1.1.2", + "defined": "^1.0.0", + "has": "^1.0.1", + "object-assign": "^4.0.1", + "postcss": "^5.0.14", + "postcss-calc": "^5.2.0", + "postcss-colormin": "^2.1.8", + "postcss-convert-values": "^2.3.4", + "postcss-discard-comments": "^2.0.4", + "postcss-discard-duplicates": "^2.0.1", + "postcss-discard-empty": "^2.0.1", + "postcss-discard-overridden": "^0.1.1", + "postcss-discard-unused": "^2.2.1", + "postcss-filter-plugins": "^2.0.0", + "postcss-merge-idents": "^2.1.5", + "postcss-merge-longhand": "^2.0.1", + "postcss-merge-rules": "^2.0.3", + "postcss-minify-font-values": "^1.0.2", + "postcss-minify-gradients": "^1.0.1", + "postcss-minify-params": "^1.0.4", + "postcss-minify-selectors": "^2.0.4", + "postcss-normalize-charset": "^1.1.0", + "postcss-normalize-url": "^3.0.7", + "postcss-ordered-values": "^2.1.0", + "postcss-reduce-idents": "^2.2.2", + "postcss-reduce-initial": "^1.0.0", + "postcss-reduce-transforms": "^1.0.3", + "postcss-svgo": "^2.1.1", + "postcss-unique-selectors": "^2.0.2", + "postcss-value-parser": "^3.2.3", + "postcss-zindex": "^2.0.1" + } + }, + "node_modules/csso": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", + "integrity": "sha512-FmCI/hmqDeHHLaIQckMhMZneS84yzUZdrWDAvJVVxOwcKE1P1LF9FGmzr1ktIQSxOw6fl3PaQsmfg+GN+VvR3w==", + "dev": true, + "dependencies": { + "clap": "^1.0.9", + "source-map": "^0.5.3" + }, + "bin": { + "csso": "bin/csso" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "0.2.37", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", + "integrity": "sha512-FUpKc+1FNBsHUr9IsfSGCovr8VuGOiiuzlgCyppKBjJi2jYTOFLN3oiiNRMIvYqbFzF38mqKj4BgcevzU5/kIA==", + "dev": true, + "dependencies": { + "cssom": "0.3.x" + } + }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dateformat": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", + "integrity": "sha512-5sFRfAAmbHdIts+eKjR9kYJoF0ViCMVX9yqLu5A7S/v+nd077KgCITOMiirmyCBiZpKLDXbBOkYm6tu7rX/TKg==", + "dev": true, + "dependencies": { + "get-stdin": "^4.0.1", + "meow": "^3.3.0" + }, + "bin": { + "dateformat": "bin/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/deep-equal": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz", + "integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==", + "dependencies": { + "is-arguments": "^1.1.1", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.5.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/default-require-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", + "integrity": "sha512-Dn2eAftOqXhNXs5f/Xjn7QTZ6kDYkx7u0EXQInN1oyYwsZysu11q7oTtaKcbzLxZRJiDHa8VmwpWmb4lY5FqgA==", + "dev": true, + "dependencies": { + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defined": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A==", + "dev": true, + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "dev": true, + "dependencies": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "node_modules/dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", + "dev": true + }, + "node_modules/domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true, + "engines": { + "node": ">=0.4", + "npm": ">=1.2" + } + }, + "node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/dot-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", + "integrity": "sha512-k4ELWeEU3uCcwub7+dWydqQBRjAjkV9L33HjVRG5Xo2QybI6ja/v+4W73SRi8ubCqJz0l9XsTP1NbewfyqaSlw==", + "dev": true, + "dependencies": { + "is-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha512-+AWBwjGadtksxjOQSFDhPNQbed7icNXApT4+2BNpsXzcCBiInq2H9XW0O8sfHFaPmnQRs7cg/P0fAr2IWQSW0g==", + "dev": true, + "dependencies": { + "readable-stream": "~1.1.9" + } + }, + "node_modules/duplexer2/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.699", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.699.tgz", + "integrity": "sha512-I7q3BbQi6e4tJJN5CRcyvxhK0iJb34TV8eJQcgh+fR2fQ8miMgZcEInckCo1U9exDHbfz7DLDnFn8oqH/VcRKw==", + "dev": true + }, + "node_modules/elegant-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha512-B+ZM+RXvRqQaAmkMlO/oSe5nMUOaUnyfGYCEHoR8wrXsZR2mA0XVibsxV1bvTwxdRWah1PkQqso2EzhILGHtEQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", + "integrity": "sha512-kxpoMgrdtkXZ5h0SeraBS1iRntpTpQ3R8ussdb38+UAFnMGX5DDyJXePm+OCHOcoXvHDw7mc2erbJBpDnl7TPw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.2.0", + "tapable": "^0.1.8" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "node_modules/enzyme": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-2.9.1.tgz", + "integrity": "sha512-64Gr+ozwW9LNQ9YetJ6qHZpLQ9RCYZyVqnuE7XAEfgRsTNTB72v//E9Lp6iNeclXRU0FHywzFRb9kLXMfRyotw==", + "dev": true, + "dependencies": { + "cheerio": "^0.22.0", + "function.prototype.name": "^1.0.0", + "is-subset": "^0.1.1", + "lodash": "^4.17.4", + "object-is": "^1.0.1", + "object.assign": "^4.0.4", + "object.entries": "^1.0.4", + "object.values": "^1.0.4", + "prop-types": "^15.5.10", + "uuid": "^3.0.1" + }, + "peerDependencies": { + "react": "0.13.x || 0.14.x || ^15.0.0-0 || 15.x" + } + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-stack-parser": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-1.3.6.tgz", + "integrity": "sha512-xhuSYd8wLgOXwNgjcPeXMPL/IiiA1Huck+OPvClpJViVNNlJVtM41o+1emp7bPvlCJwCatFX2DWc05/DgfbWzA==", + "dependencies": { + "stackframe": "^0.3.1" + } + }, + "node_modules/es-abstract": { + "version": "1.22.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz", + "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.1", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.0", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.5", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", + "dev": true, + "dependencies": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=0.12.0" + }, + "optionalDependencies": { + "source-map": "~0.2.0" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", + "dev": true, + "optional": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/eventsource": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", + "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/exec-sh": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.2.tgz", + "integrity": "sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw==", + "dev": true, + "dependencies": { + "merge": "^1.2.0" + } + }, + "node_modules/exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha512-MsG3prOVw1WtLXAZbM3KiYtooKR1LvxHh3VHsVtIy0uiUu8usxgB/94DP2HxtD/661lLdB6yzQ09lGJSQr6nkg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha512-hxx03P2dJxss6ceIeri9cmYOT4SRs3Zk3afZwWpOsRqLqprhTR8u++SlC+sFGsQr7WGFPdMF7Gjc1njDLDK6UA==", + "dev": true, + "dependencies": { + "is-posix-bracket": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha512-AFASGfIlnIbkKPQwX1yHaDjFvh/1gyKJODme52V6IORh69uEYgZp0o9C+qsIGNVEiuuhQU0CSSl++Rlegg1qvA==", + "dev": true, + "dependencies": { + "fill-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/express": { + "version": "4.18.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz", + "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha512-1FOj1LOwn42TMrruOHGt18HemVnbwAmAak7krWk+wa93KXxGbK+2jpezm+ytJYDaBX0/SPLZFHKM7m+tKobWGg==", + "dev": true, + "dependencies": { + "is-extglob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extract-text-webpack-plugin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-1.0.1.tgz", + "integrity": "sha512-cl5NaZf1uB2ijZsLmoaPaaDMDBkd4ll5fv0b9BUmNADAg537ArDwvcvUY46KR+GI4uWwF7aF3MEo4GKKWv/+vg==", + "deprecated": "Deprecated. Please use https://github.com/webpack-contrib/mini-css-extract-plugin", + "dev": true, + "dependencies": { + "async": "^1.5.0", + "loader-utils": "^0.2.3", + "webpack-sources": "^0.1.0" + }, + "peerDependencies": { + "webpack": "^1.9.11" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "dev": true, + "dependencies": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "dev": true + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fb-watchman": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-1.9.2.tgz", + "integrity": "sha512-XgitQpaII7LkblC9X8HhfnfuDpyOYSB/Xw8h3Q/gXfMtyL7UICDS1axIlafhwfvKxPjrqnu7EfO7i3A1kH+Rfg==", + "dev": true, + "dependencies": { + "bser": "1.0.2" + } + }, + "node_modules/fbjs": { + "version": "0.8.18", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.18.tgz", + "integrity": "sha512-EQaWFK+fEPSoibjNy8IxUtaFOMXcWsY0JaVrQoZR9zC8N2Ygf9iDITPWjUTVIax95b6I742JFLqASHfsag/vKA==", + "dependencies": { + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.30" + } + }, + "node_modules/fbjs/node_modules/core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha512-ZiPp9pZlgxpWRu0M+YWbm6+aQ84XEfH1JRXvfOc/fILWI0VKhLC2LX13X1NYq4fULzLMq7Hfh43CSo2/aIaUPA==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js." + }, + "node_modules/file-loader": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-0.9.0.tgz", + "integrity": "sha512-Zi8JbkzqIv7uYncY4yHtzMJAM09/t0uXzDXfOkdKl0vIRsQxxnjZXriiY9aKdzDic/I4Zit5uM+zY5gbVxcZ4A==", + "dev": true, + "dependencies": { + "loader-utils": "~0.2.5" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "node_modules/filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha512-BTCqyBaWBTsauvnHiE8i562+EdJj+oUpkqWp2R1iCoR8f6oo8STRu3of7WJJ0TqWtxN50a5YFpzYK4Jj9esYfQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha512-UxowFKnAFIwtmSxgKjWAVgjE3Fk7MQJT0ZIyl0NwIFZTrx4913rLaonGJ84V+x/2+w/pe4ULHRns+GZPs1TVuw==", + "dev": true, + "dependencies": { + "glob": "^7.0.3", + "minimatch": "^3.0.3" + } + }, + "node_modules/fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "dev": true, + "dependencies": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/filled-array": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filled-array/-/filled-array-1.1.0.tgz", + "integrity": "sha512-4XwZ1k4rgoF3Yap59MyXFmiUh2zu9fht32NYPSRYwLv4o8BWHxi60I1VH5kHje14qGMoS3qyfHQUsN16ROOugQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-cache-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", + "integrity": "sha512-Z9XSBoNE7xQiV6MSgPuCfyMokH2K7JdpRkOYE1+mu3d4BFJtx3GW+f6Bo4q8IX6rlf5MYbLBKW0pjl2cWdkm2A==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "mkdirp": "^0.5.1", + "pkg-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "dev": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/findup-sync": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", + "integrity": "sha512-z8Nrwhi6wzxNMIbxlrTzuUW6KWuKkogZ/7OdDVq+0+kxn77KUH1nipx8iU6suqkHqc4y6n7a9A8IpmxY/pTjWg==", + "dev": true, + "dependencies": { + "glob": "~5.0.0" + }, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/findup-sync/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", + "dev": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/flatten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", + "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", + "deprecated": "flatten is deprecated in favor of utility frameworks such as lodash.", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha512-SKmowqGTJoPzLO1T0BBJpkfp3EMacCMOuH40hOUbrbzElVktk4DioXVM99QkLCyKoiuOmyjgcWMpVz2xjE7LZw==", + "dev": true, + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-all": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/glob-all/-/glob-all-3.3.1.tgz", + "integrity": "sha512-Y+ESjdI7ZgMwfzanHZYQ87C59jOO0i+Hd+QYtVt9PhLi6d8wlOpzQnfBxWUlaTuAoR3TkybLqqbIoWveU4Ji7Q==", + "dev": true, + "dependencies": { + "glob": "^7.2.3", + "yargs": "^15.3.1" + }, + "bin": { + "glob-all": "bin/glob-all" + } + }, + "node_modules/glob-all/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/glob-all/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/glob-all/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/glob-all/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/glob-all/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/glob-all/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/glob-all/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/glob-all/node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob-all/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/glob-all/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/glob-all/node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/glob-all/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/glob-all/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/glob-all/node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, + "node_modules/glob-all/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/glob-all/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/glob-all/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/glob-all/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha512-ab1S1g1EbO7YzauaJLkgLp7DZVAqj9M/dvKlTt8DkXA2tiOIcSMrlVI2J1RZyB5iJVccEscjGn+kpOG9788MHA==", + "dev": true, + "dependencies": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha512-JDYOvfxio/t42HKdxkAYaCiBN7oYiuxykOxKxdaUW5Qn0zaYN3gRQWolrwdnf0shM9/EP0ebuuTmyoXNr1cC5w==", + "dev": true, + "dependencies": { + "is-glob": "^2.0.0" + } + }, + "node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dev": true, + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glogg": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", + "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", + "dev": true, + "dependencies": { + "sparkles": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-5.6.0.tgz", + "integrity": "sha512-MnypzkaW8dldA8AbJFjMs7y14+ykd2V8JCLKSvX1Gmzx1alH3Y+3LArywHDoAF2wS3pnZp4gacoYtvqBeF6drQ==", + "dev": true, + "dependencies": { + "create-error-class": "^3.0.1", + "duplexer2": "^0.1.4", + "is-plain-obj": "^1.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "node-status-codes": "^1.0.0", + "object-assign": "^4.0.1", + "parse-json": "^2.1.0", + "pinkie-promise": "^2.0.0", + "read-all-stream": "^3.0.0", + "readable-stream": "^2.0.5", + "timed-out": "^2.0.0", + "unzip-response": "^1.0.0", + "url-parse-lax": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/got/node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/got/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/got/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/got/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/got/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==", + "dev": true + }, + "node_modules/gulp-util": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.7.tgz", + "integrity": "sha512-Hw0BEAQGwMCCqflSPbWGNuep+/N6m/wLCwzovnuTJ1P7pvfDvUky5v3UisvLCnWSDzbh25dH81AP0l0YOBzW4g==", + "deprecated": "gulp-util is deprecated - replace it, following the guidelines at https://medium.com/gulpjs/gulp-util-ca3b1f9f9ac5", + "dev": true, + "dependencies": { + "array-differ": "^1.0.0", + "array-uniq": "^1.0.2", + "beeper": "^1.0.0", + "chalk": "^1.0.0", + "dateformat": "^1.0.11", + "fancy-log": "^1.1.0", + "gulplog": "^1.0.0", + "has-gulplog": "^0.1.0", + "lodash._reescape": "^3.0.0", + "lodash._reevaluate": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.template": "^3.0.0", + "minimist": "^1.1.0", + "multipipe": "^0.1.2", + "object-assign": "^3.0.0", + "replace-ext": "0.0.1", + "through2": "^2.0.0", + "vinyl": "^0.5.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/gulp-util/node_modules/object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw==", + "dev": true, + "dependencies": { + "glogg": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha512-+F4GzLjwHNNDEAJW2DC1xXfEoPkRDmUdJ7CBYw4MpqtDwOnqdImJl7GWlpqx+Wko6//J8uKTnIe4wZSv7yCqmw==", + "dev": true, + "dependencies": { + "sparkles": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-value/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hasown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha512-X8xbmTc1cbPXcQV4WkLcRMALuyoxhfpFATmyuCxJPOAvrDS4DNnsTAOmKUxMTOWU6TzrTOkxPKwIx5ZOpJVSrg==", + "deprecated": "This module moved to @hapi/hawk. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.", + "dev": true, + "optional": true, + "dependencies": { + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" + }, + "engines": { + "node": ">=0.10.32" + } + }, + "node_modules/history": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/history/-/history-2.1.2.tgz", + "integrity": "sha512-s8D90YFieskA7uRglWmvbI17SehPP+ZHN2eiNrg1xUZjUHIeMcTu8paxjpzC7RfU0wptwQMXdezifG/UTkzC2w==", + "dependencies": { + "deep-equal": "^1.0.0", + "invariant": "^2.0.0", + "query-string": "^3.0.0", + "warning": "^2.0.0" + } + }, + "node_modules/history/node_modules/query-string": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-3.0.3.tgz", + "integrity": "sha512-51caZjRlfBSfcCvFT5OKJqY7az8z05qAHx1nHydQyEYIxOThv1BLTYt+T+usyJpPCsoGQDQxCdDzZ7BbIZtitw==", + "dependencies": { + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/history/node_modules/warning": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-2.1.0.tgz", + "integrity": "sha512-O9pvum8nlCqIT5pRGo2WRQJPRG2bW/ZBeCzl7/8CWREjUW693juZpGup7zbRtuVcSKyGiRAIZLYsh3C0vq7FAg==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha512-V6Yw1rIcYV/4JsnggjBU0l4Kr+EXhpwqXRusENU1Xx6ro00IHPHYNynCuBTOZAPlr3AAmLvchH9I7N/VUdvOwQ==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.40" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz", + "integrity": "sha512-r8huvKK+m+VraiRipdZYc+U4XW43j6OFG/oIafe7GfDbRpCduRoX9JI/DRxqgtBSCeL+et6N6ibZoedHS2NyOQ==" + }, + "node_modules/home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/html-comment-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", + "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", + "dev": true + }, + "node_modules/html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^1.0.1" + } + }, + "node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-1.0.0.tgz", + "integrity": "sha512-6YMslTZtuupu4irnNBi1bM6dG0UqHBHqObHQn3awavmNXe9CGkmw7KZ68EyAnJk3yBlLpbLwux5+bY1lneDFmg==", + "dev": true, + "dependencies": { + "agent-base": "2", + "debug": "2", + "extend": "3" + } + }, + "node_modules/http-proxy-middleware": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz", + "integrity": "sha512-JtH3UZju4oXDdca28/kknbm/CFmt35vy0YV0PNOMWWWpn3rT9WV95IXN451xwBGSjy9L0Cah1O9TCMytboLdfw==", + "dev": true, + "dependencies": { + "http-proxy": "^1.16.2", + "is-glob": "^3.1.0", + "lodash": "^4.17.2", + "micromatch": "^2.3.11" + } + }, + "node_modules/http-proxy-middleware/node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", + "integrity": "sha512-EjDQFbgJr1vDD/175UJeSX3ncQ3+RUnCL5NkthQGHvF4VNHlzTy8ifJfTqz47qiPRqaFH58+CbuG3x51WuB1XQ==", + "dev": true + }, + "node_modules/https-proxy-agent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", + "integrity": "sha512-OZhm7//JDnQthMVqlPAfkZyPO2fMhfHY6gY+jZcX8rLfFiGtHiIQrfD80WvCDHNMQ77Ak3r5CiPRDD2rNzo2OQ==", + "dev": true, + "dependencies": { + "agent-base": "2", + "debug": "2", + "extend": "3" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==", + "dev": true + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "dev": true, + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg==", + "dev": true, + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==", + "dev": true + }, + "node_modules/indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-0.6.6.tgz", + "integrity": "sha512-Vg6X07U0AOZb4HF6CWHa+jnJU8j71buKQ9Pc0C75qBXgvCYbxWBkGo4jnTS3O0MIc9FZtt0mB7h+uclojqdw1Q==", + "dev": true + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-absolute": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", + "integrity": "sha512-7Kr05z5LkcOpoMvxHN1PC11WbPabdNFmMYYo0eZvWu3BfVS0T03yoqYDczoCBx17xqk2x1XAZrcKiFVL88jxlQ==", + "dev": true, + "dependencies": { + "is-relative": "^0.2.1", + "is-windows": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha512-vOx7VprsKyllwjSkLV79NIhpyLfr3jAp7VaTCMXOJHu4m0Ew1CZ2fcjASwmV1jI3BWuWHB013M48eyeldk9gYg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", + "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "dev": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "dependencies": { + "ci-info": "^1.5.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", + "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha512-9YclgOGtN/f8zx0Pr4FQYMdibBiTaH3sn52vjYip4ZSf6C4/6RfTEZ+MR4GvKhCxdPh21Bg42/WL55f6KSnKpg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha512-0EygVC5qPvIyb+gSz7zdD5/AAoS6Qrx1e//6N4yv4oNm30kqvdmG66oZFWVlQHUWe5OjP08FuTw2IdT0EOTcYA==", + "dev": true, + "dependencies": { + "is-primitive": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "dev": true, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==", + "dev": true, + "dependencies": { + "is-extglob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha512-9r39FIr3d+KD9SbX0sfMsHzb5PP3uimOiwr3YupUaUFG4W0l1U57Rx3utpttV7qz5U3jmrO5auUa04LU9pyHsg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha512-QUzH43Gfb9+5yckcrSA0VBDwEtDUchrk4F6tfJZQuNzDJbEDB9cZNzSfXGQ1jqmdDY/kl41lUOWM9syA8z8jlg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha512-Yu68oeXJ7LeWNmZ3Zov/xg/oDBnBK2RNxwYY1ilNJX+tKKZqgPK+qOn/Gs9jEu66KDY9Netf5XLKNGzas/vPfQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha512-N3w1tFaRfk3UrPfqeRyD+GYDASU3W5VinKhlORy8EWVf/sIdDL9GAcew85XmktCfH+ngG7SRXEVDoO18WMdB/Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-relative": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", + "integrity": "sha512-9AMzjRmLqcue629b4ezEVSK6kJsYJlUIhMcygmYORUgwUNJiavHcC3HkaGx0XYpyVKQSOqFbMEZmW42cY87sYw==", + "dev": true, + "dependencies": { + "is-unc-path": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-subset": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", + "integrity": "sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==", + "dev": true + }, + "node_modules/is-svg": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", + "integrity": "sha512-Ya1giYJUkcL/94quj0+XGcmts6cETPBW1MiFz1ReJrnDJ680F52qpAEGAEGU0nq96FRGIGPx6Yo1CyPXcOoyGw==", + "dev": true, + "dependencies": { + "html-comment-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-unc-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", + "integrity": "sha512-HhLc5VDMH4pu3oMtIuunz/DFQUIoR561kMME3U3Afhj8b7vH085vkIkemrz1kLXCEIuoMAmO3yVmafWdSbGW8w==", + "dev": true, + "dependencies": { + "unc-path-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", + "dev": true + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha512-n67eJYmXbniZB7RF4I/FTjK1s6RPOCTxhYrVYLRaCt3lF0mpWZPKr3T2LSZAqyjQsxR2qMmGYXXzK0YWwcPM1Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isobject/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha512-9c4TNAKYXM5PRyVcwUZrF3W09nQ+sO7+jydgs4ZGW9dhsLG2VOlISJABombdQqQRXCwuYG3sYV/puGf5rp0qmA==", + "dependencies": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + } + }, + "node_modules/isomorphic-fetch/node_modules/node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "dependencies": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "node_modules/istanbul": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", + "integrity": "sha512-nMtdn4hvK0HjUlzr1DrKSUY8ychprt8dzHOgY2KXsIhHu5PuQQEOTM27gV9Xblyon7aUH/TSFIjRHEODF/FRPg==", + "deprecated": "This module is no longer maintained, try this instead:\n npm i nyc\nVisit https://istanbul.js.org/integrations for other alternatives.", + "dev": true, + "dependencies": { + "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" + }, + "bin": { + "istanbul": "lib/cli.js" + } + }, + "node_modules/istanbul-api": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.7.tgz", + "integrity": "sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA==", + "dev": true, + "dependencies": { + "async": "^2.1.4", + "fileset": "^2.0.2", + "istanbul-lib-coverage": "^1.2.1", + "istanbul-lib-hook": "^1.2.2", + "istanbul-lib-instrument": "^1.10.2", + "istanbul-lib-report": "^1.1.5", + "istanbul-lib-source-maps": "^1.2.6", + "istanbul-reports": "^1.5.1", + "js-yaml": "^3.7.0", + "mkdirp": "^0.5.1", + "once": "^1.4.0" + } + }, + "node_modules/istanbul-api/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", + "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==", + "dev": true + }, + "node_modules/istanbul-lib-hook": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz", + "integrity": "sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw==", + "dev": true, + "dependencies": { + "append-transform": "^0.4.0" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz", + "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==", + "dev": true, + "dependencies": { + "babel-generator": "^6.18.0", + "babel-template": "^6.16.0", + "babel-traverse": "^6.18.0", + "babel-types": "^6.18.0", + "babylon": "^6.18.0", + "istanbul-lib-coverage": "^1.2.1", + "semver": "^5.3.0" + } + }, + "node_modules/istanbul-lib-report": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz", + "integrity": "sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^1.2.1", + "mkdirp": "^0.5.1", + "path-parse": "^1.0.5", + "supports-color": "^3.1.2" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz", + "integrity": "sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "istanbul-lib-coverage": "^1.2.1", + "mkdirp": "^0.5.1", + "rimraf": "^2.6.1", + "source-map": "^0.5.3" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/istanbul-reports": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.5.1.tgz", + "integrity": "sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw==", + "dev": true, + "dependencies": { + "handlebars": "^4.0.3" + } + }, + "node_modules/istanbul/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", + "dev": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/istanbul/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jasmine-check": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/jasmine-check/-/jasmine-check-0.1.5.tgz", + "integrity": "sha512-iI5m7mfQ0pLZPHQzsh9nGjhnZ7PnCNsn1464J8uX6dGFbc7kK5eGQctgdyOkf9/ofqwz74ek6iz+TswzG6dVfQ==", + "dev": true, + "dependencies": { + "testcheck": "^0.1.0" + } + }, + "node_modules/jest": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-16.0.2.tgz", + "integrity": "sha512-zzITjg4NKTJVMWZgujWH9Rb7sK6JwLTDBQ27PY4StD0cVkeTEjMO9j5XlIILHKVBQIZsThnoHUjY/aEJ1qE29Q==", + "dev": true, + "dependencies": { + "jest-cli": "^16.0.2" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/jest-changed-files": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-16.0.0.tgz", + "integrity": "sha512-AIvr3J3Oq3Mu/uQc1RlfsStQFbmCD6lCKrrpktxg0mftdeKrtN6pUz3mBW3/gS6bCqK00BMi+87DZToqv/c8TQ==", + "dev": true + }, + "node_modules/jest-cli": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-16.0.2.tgz", + "integrity": "sha512-pM9Ze6CWX2b2Rj06zLbrval4jc2bwnMdZEVj9huEwtPHo34VpdxSxpxqrx5hMKKdPTKNnwq+hYbt5b/t4G5osw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^1.4.0", + "callsites": "^2.0.0", + "chalk": "^1.1.1", + "graceful-fs": "^4.1.6", + "is-ci": "^1.0.9", + "istanbul-api": "^1.0.0-aplha.10", + "istanbul-lib-coverage": "^1.0.0", + "istanbul-lib-instrument": "^1.1.1", + "jest-changed-files": "^16.0.0", + "jest-config": "^16.0.2", + "jest-environment-jsdom": "^16.0.2", + "jest-file-exists": "^15.0.0", + "jest-haste-map": "^16.0.2", + "jest-jasmine2": "^16.0.2", + "jest-mock": "^16.0.2", + "jest-resolve": "^16.0.2", + "jest-resolve-dependencies": "^16.0.2", + "jest-runtime": "^16.0.2", + "jest-snapshot": "^16.0.2", + "jest-util": "^16.0.2", + "json-stable-stringify": "^1.0.0", + "node-notifier": "^4.6.1", + "sane": "~1.4.1", + "strip-ansi": "^3.0.1", + "throat": "^3.0.0", + "which": "^1.1.1", + "worker-farm": "^1.3.1", + "yargs": "^5.0.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/jest-config": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-16.0.2.tgz", + "integrity": "sha512-TEZwoZiXNqu2j/8jStqWTVUobw38ZNSUdEChXh6x4LKapiMTMsQbxK9LFhBOLD70c0AK8ILfNDyf8LmpYA0wYw==", + "dev": true, + "dependencies": { + "chalk": "^1.1.1", + "istanbul": "^0.4.5", + "jest-environment-jsdom": "^16.0.2", + "jest-environment-node": "^16.0.2", + "jest-jasmine2": "^16.0.2", + "jest-mock": "^16.0.2", + "jest-resolve": "^16.0.2", + "jest-util": "^16.0.2", + "json-stable-stringify": "^1.0.0" + } + }, + "node_modules/jest-diff": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-16.0.0.tgz", + "integrity": "sha512-SW8bPpT/xG+ZEheA6jl09RxLZm5TIEriMpdMbAD3zWxAk9QD4mPb2XiLg/on7idSCxEA2NWa0svwlR1DaSoRYA==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "diff": "^3.0.0", + "jest-matcher-utils": "^16.0.0", + "pretty-format": "~4.2.1" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-16.0.2.tgz", + "integrity": "sha512-fKmXeE1Nd+8puTwvtdCKDSf2rEUguXxfO5Ft5rWePOEkUNYTOTJes1teUvRzRWeDxPJ4Vr/kEZsiZ+qvabphow==", + "dev": true, + "dependencies": { + "jest-mock": "^16.0.2", + "jest-util": "^16.0.2", + "jsdom": "^9.8.0" + } + }, + "node_modules/jest-environment-node": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-16.0.2.tgz", + "integrity": "sha512-mY+pojJx58ijDG0YQ4xT5wPR3x2e/L4loXi6j3dcTSLPU0aSCSyOunu+Qkx84D3/41omK0lwUKVliEt5EuQ5iw==", + "dev": true, + "dependencies": { + "jest-mock": "^16.0.2", + "jest-util": "^16.0.2" + } + }, + "node_modules/jest-fetch-mock": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/jest-fetch-mock/-/jest-fetch-mock-1.7.5.tgz", + "integrity": "sha512-fP0CXb24z5oyvHiqakvDiDqEik1LPmIgRqsrqLhXkMNqSfibfsDkP5VJzm9/rmVsT9WSGQGNZ4iD2f1/Sm0qmg==", + "dev": true, + "dependencies": { + "cross-fetch": "^2.2.2", + "promise-polyfill": "^7.1.1" + } + }, + "node_modules/jest-file-exists": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/jest-file-exists/-/jest-file-exists-15.0.0.tgz", + "integrity": "sha512-WVCb13ni8h8A2vOZ1sYrqyquOPnKTgQnpCggucbhyq6r+5UK1hgZQF2RAmR+pVYb8TlRJRBjUDA4LHjAhDtauw==", + "dev": true + }, + "node_modules/jest-haste-map": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-16.0.2.tgz", + "integrity": "sha512-MOgnjLJ56YnlxJW3asEjBZ0TvAUkekXHXarz4kkugjK3SrTTGIfbEtJfAREMD9yJoS7fMIM/fw+Lr+m+Nf4rjA==", + "dev": true, + "dependencies": { + "fb-watchman": "^1.9.0", + "graceful-fs": "^4.1.6", + "multimatch": "^2.1.0", + "worker-farm": "^1.3.1" + } + }, + "node_modules/jest-jasmine2": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-16.0.2.tgz", + "integrity": "sha512-hQY+2yb06RJrwADnAlYmhylso4l51aXzJZ3nDV82TlZTSJlB67yMUy1bx9BYlKu7YslUv8k8xh0HpcTp77YyOw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.6", + "jasmine-check": "^0.1.4", + "jest-matchers": "^16.0.2", + "jest-snapshot": "^16.0.2", + "jest-util": "^16.0.2" + } + }, + "node_modules/jest-matcher-utils": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-16.0.0.tgz", + "integrity": "sha512-KmmEFVPF4r6aOO/sSZL39gJL+QCUbG0m8wHJgodCgKJT9bshG24cW3aRB9AmHAVITzf5uI5xEQCqcB9QNvizdw==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "pretty-format": "~4.2.1" + } + }, + "node_modules/jest-matchers": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/jest-matchers/-/jest-matchers-16.0.2.tgz", + "integrity": "sha512-k6ewFXKE5AK0hh0JVy0H3Vt99HLXhSeGz0eZ8VeIgCeo+S03rYw3bCE8JK+kMNMOh3C4f/lc/ln0ilNcCQRJdQ==", + "dev": true, + "dependencies": { + "jest-diff": "^16.0.0", + "jest-matcher-utils": "^16.0.0", + "jest-util": "^16.0.2" + } + }, + "node_modules/jest-mock": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-16.0.2.tgz", + "integrity": "sha512-se8ss/uL1TkBujO1pMTdFsousax+FsIFY5P7vFzOFMt8ySoglEo7DFqeqryBNz43iAD+12AX0YQfcOg4J97uqw==", + "dev": true + }, + "node_modules/jest-resolve": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-16.0.2.tgz", + "integrity": "sha512-IoA7E3zNv7ipeg1Po21luMmrghlEi9duYDdlLR/3b8K6eg+0Rp/rhrGE5gtWDVTnkgFKz03wldPBu6XXvrDRLg==", + "dev": true, + "dependencies": { + "browser-resolve": "^1.11.2", + "jest-file-exists": "^15.0.0", + "jest-haste-map": "^16.0.2", + "resolve": "^1.1.6" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-16.0.2.tgz", + "integrity": "sha512-V2lE37SG4Ym4RtYNWEal7EyWAmr1ImRmSKAmUd8hYFJh8X7QpXUkCNL+HdzSU4aMStgDj01iwQozi6qIQDn7Tg==", + "dev": true, + "dependencies": { + "jest-file-exists": "^15.0.0", + "jest-resolve": "^16.0.2" + } + }, + "node_modules/jest-runtime": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-16.0.2.tgz", + "integrity": "sha512-CBZs4iBeGb3tI0pMX5P3LQ0GHbeJtG77SDmDa/aGMs+3oJZGmx9zOtN4QTk0cnOwlIZvQdLcsBi+82h+dVcl7w==", + "dev": true, + "dependencies": { + "babel-core": "^6.11.4", + "babel-jest": "^16.0.0", + "babel-plugin-istanbul": "^2.0.0", + "chalk": "^1.1.3", + "graceful-fs": "^4.1.6", + "jest-config": "^16.0.2", + "jest-file-exists": "^15.0.0", + "jest-haste-map": "^16.0.2", + "jest-mock": "^16.0.2", + "jest-resolve": "^16.0.2", + "jest-snapshot": "^16.0.2", + "jest-util": "^16.0.2", + "json-stable-stringify": "^1.0.0", + "multimatch": "^2.1.0", + "yargs": "^5.0.0" + }, + "bin": { + "jest-runtime": "bin/jest-runtime.js" + } + }, + "node_modules/jest-snapshot": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-16.0.2.tgz", + "integrity": "sha512-tNKqNHQOUnX4cfQQj48F3wv4JPisEVYYiFmbtnEW3uCD7WE1JbASelYVRSFWkAlKZbUKJdDoRYXfF78fi1Jh4A==", + "dev": true, + "dependencies": { + "jest-diff": "^16.0.0", + "jest-file-exists": "^15.0.0", + "jest-matcher-utils": "^16.0.0", + "jest-util": "^16.0.2", + "natural-compare": "^1.4.0", + "pretty-format": "~4.2.1" + } + }, + "node_modules/jest-util": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-16.0.2.tgz", + "integrity": "sha512-8T0+4EDp7cnnivEyDBLS0NFxzTEXdUFzf7dBHDg/ZwZxVxeXJijCcGm7g+6vs9jM9+H6MS3w8Po5qSR1rwVDBQ==", + "dev": true, + "dependencies": { + "chalk": "^1.1.1", + "diff": "^3.0.0", + "graceful-fs": "^4.1.6", + "jest-file-exists": "^15.0.0", + "jest-mock": "^16.0.2", + "mkdirp": "^0.5.1" + } + }, + "node_modules/js-base64": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/js-yaml/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, + "node_modules/jsdom": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz", + "integrity": "sha512-Qw4oqNxo4LyzkSqVIyCnEltTc4xV3g1GBaI88AvYTesWzmWHUSoMNmhBjUBa+6ldXIBJS9xoeLNJPfUAykTyxw==", + "dev": true, + "dependencies": { + "abab": "^1.0.3", + "acorn": "^4.0.4", + "acorn-globals": "^3.1.0", + "array-equal": "^1.0.0", + "content-type-parser": "^1.0.1", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": ">= 0.2.37 < 0.3.0", + "escodegen": "^1.6.1", + "html-encoding-sniffer": "^1.0.1", + "nwmatcher": ">= 1.3.9 < 2.0.0", + "parse5": "^1.5.1", + "request": "^2.79.0", + "sax": "^1.2.1", + "symbol-tree": "^3.2.1", + "tough-cookie": "^2.3.2", + "webidl-conversions": "^4.0.0", + "whatwg-encoding": "^1.0.1", + "whatwg-url": "^4.3.0", + "xml-name-validator": "^2.0.1" + } + }, + "node_modules/jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz", + "integrity": "sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "isarray": "^2.0.5", + "jsonify": "^0.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "node_modules/json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/latest-version": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-2.0.0.tgz", + "integrity": "sha512-8925wFYLfWBciewimt0VmDyYw0GFCRcbFSTrZGt4JgQ7lh5jb/kodMlUt0uMaxXdRKVi+7F3ib30N7fTv83ikw==", + "dev": true, + "dependencies": { + "package-json": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lazy-req": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/lazy-req/-/lazy-req-1.1.0.tgz", + "integrity": "sha512-Vn/JuGaYykbelAVNAhfVJxuwHQCOSNE6mqMtD+gnd+QORlAHwWVmVFqQga3yWt84G5vAwEwpT6sAsZ+tgJ88/Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", + "dev": true, + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/less": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/less/-/less-2.7.3.tgz", + "integrity": "sha512-KPdIJKWcEAb02TuJtaLrhue0krtRLoRoo7x6BNJIBelO00t/CCdJQUnHW5V34OnHMWzIktSalJxRO+FvytQlCQ==", + "dev": true, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=0.12" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "mime": "^1.2.11", + "mkdirp": "^0.5.0", + "promise": "^7.1.1", + "request": "2.81.0", + "source-map": "^0.5.3" + } + }, + "node_modules/less-loader": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-2.2.3.tgz", + "integrity": "sha512-U7lgRusyqTj1TUB6OBlmow6GigLk0n5ADuTSGblCp0nkXOk+lFq/lHTDXCHkm3WydZha2FVNZivEjCEZNFJCiw==", + "dev": true, + "dependencies": { + "loader-utils": "^0.2.5" + }, + "peerDependencies": { + "less": "^2.3.1" + } + }, + "node_modules/less/node_modules/ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha512-I/bSHSNEcFFqXLf91nchoNB9D1Kie3QKcWdchYUaoIg1+1bdWDkdfdlvdIOJbi9U8xR0y+MWc5D+won9v95WlQ==", + "dev": true, + "optional": true, + "dependencies": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + } + }, + "node_modules/less/node_modules/assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha512-u1L0ZLywRziOVjUhRxI0Qg9G+4RnFB9H/Rq40YWn0dieDgO7vAYeJz6jKAO6t/aruzlDFLAPkQTT87e+f8Imaw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/less/node_modules/aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha512-JnJpAS0p9RmixkOvW2XwDxxzs1bd4/VAGIl6Q0EC5YOo+p+hqIhtDhn/nmFnB/xUNXbLkpE2mOjgVIBRKD4xYw==", + "dev": true, + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/less/node_modules/form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha512-8HWGSLAPr+AG0hBpsqi5Ob8HrLStN/LWeqhpFl14d7FJgHK48TmgLoALPz69XSUR65YJzDfLUX/BM8+MLJLghQ==", + "dev": true, + "optional": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/less/node_modules/har-schema": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha512-f8xf2GOR6Rgwc9FPTLNzgwB+JQ2/zMauYXSWmX5YV5acex6VomT0ocSuwR7BfXo5MpHi+jL+saaux2fwsGJDKQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/node_modules/har-validator": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha512-5Gbp6RAftMYYV3UEI4c4Vv3+a4dQ7taVyvHt+/L6kRt+f4HX1GweAk5UDWN0SvdVnRBzGQ6OG89pGaD9uSFnVw==", + "deprecated": "this library is no longer supported", + "dev": true, + "optional": true, + "dependencies": { + "ajv": "^4.9.1", + "har-schema": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/node_modules/http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha512-iUn0NcRULlDGtqNLN1Jxmzayk8ogm7NToldASyZBpM2qggbphjXzNOiw3piN8tgz+e/DRs6X5gAzFwTI6BCRcg==", + "dev": true, + "optional": true, + "dependencies": { + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/less/node_modules/oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha512-VlF07iu3VV3+BTXj43Nmp6Irt/G7j/NgEctUS6IweH1RGhURjjCc2NWtzXFPXXWWfc7hgbXQdtiQu2LGp6MxUg==", + "dev": true, + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/less/node_modules/performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha512-YHk5ez1hmMR5LOkb9iJkLKqoBlL7WD5M8ljC75ZfzXriuBIVNuecaXuU7e+hOwyqf24Wxhh7Vxgt7Hnw9288Tg==", + "dev": true, + "optional": true + }, + "node_modules/less/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true, + "optional": true + }, + "node_modules/less/node_modules/qs": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.1.tgz", + "integrity": "sha512-LQy1Q1fcva/UsnP/6Iaa4lVeM49WiOitu2T4hZCyA/elLKu37L99qcBJk4VCCk+rdLvnMzfKyiN3SZTqdAZGSQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/less/node_modules/request": { + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha512-IZnsR7voF0miGSu29EXPRgPTuEsI/+aibNSBbN1pplrfartF5wDYGADz3iD9vmBVf2r00rckWZf8BtS5kk7Niw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "optional": true, + "dependencies": { + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~4.2.1", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "performance-now": "^0.2.0", + "qs": "~6.4.0", + "safe-buffer": "^5.0.1", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.0.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/less/node_modules/tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "dev": true, + "optional": true, + "dependencies": { + "punycode": "^1.4.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/listify": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.3.tgz", + "integrity": "sha512-083swF7iH7bx8666zdzBColpgEuy46HjN3r1isD4zV6Ix7FuHfb/2/WVnl4CH8hjuoWeFF7P5KkKNXUnJCFEJg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha512-tiv66G0SmiOx+pLWMtGEkfSEejxvb6N6uRrQjfWJIT79W9GMpgKeCAmm9aVBKtd4WEgntciI8CsGqjpDoCWJug==", + "dev": true, + "dependencies": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lockfile": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz", + "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==", + "dev": true, + "dependencies": { + "signal-exit": "^3.0.2" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash._arraycopy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz", + "integrity": "sha512-RHShTDnPKP7aWxlvXKiDT6IX2jCs6YZLCtNhOru/OX2Q/tzX295vVBK5oX1ECtN+2r86S0Ogy8ykP1sgCZAN0A==", + "dev": true + }, + "node_modules/lodash._arrayeach": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._arrayeach/-/lodash._arrayeach-3.0.0.tgz", + "integrity": "sha512-Mn7HidOVcl3mkQtbPsuKR0Fj0N6Q6DQB77CtYncZcJc0bx5qv2q4Gl6a0LC1AN+GSxpnBDNnK3CKEm9XNA4zqQ==", + "dev": true + }, + "node_modules/lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha512-t3N26QR2IdSN+gqSy9Ds9pBu/J1EAFEshKlUHpJG3rvyJOYgcELIxcIeKKfZk7sjOz11cFfzJRsyFry/JyabJQ==", + "dev": true, + "dependencies": { + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "node_modules/lodash._baseclone": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lodash._baseclone/-/lodash._baseclone-3.3.0.tgz", + "integrity": "sha512-1K0dntf2dFQ5my0WoGKkduewR6+pTNaqX03kvs45y7G5bzl4B3kTR4hDfJIc2aCQDeLyQHhS280tc814m1QC1Q==", + "dev": true, + "dependencies": { + "lodash._arraycopy": "^3.0.0", + "lodash._arrayeach": "^3.0.0", + "lodash._baseassign": "^3.0.0", + "lodash._basefor": "^3.0.0", + "lodash.isarray": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "node_modules/lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha512-rFR6Vpm4HeCK1WPGvjZSJ+7yik8d8PVUdCJx5rT2pogG4Ve/2ZS7kfmO5l5T2o5V2mqlNIfSF5MZlr1+xOoYQQ==", + "dev": true + }, + "node_modules/lodash._basefor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basefor/-/lodash._basefor-3.0.3.tgz", + "integrity": "sha512-6bc3b8grkpMgDcVJv9JYZAk/mHgcqMljzm7OsbmcE2FGUMmmLQTPHlh/dFqR8LA0GQ7z4K67JSotVKu5058v1A==", + "dev": true + }, + "node_modules/lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha512-mTzAr1aNAv/i7W43vOR/uD/aJ4ngbtsRaCubp2BfZhlGU/eORUjg/7F6X0orNMdv33JOrdgGybtvMN/po3EWrA==", + "dev": true + }, + "node_modules/lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha512-H94wl5P13uEqlCg7OcNNhMQ8KvWSIyqXzOPusRgHC9DK3o54P6P3xtbXlVbRABG4q5gSmp7EDdJ0MSuW9HX6Mg==", + "dev": true + }, + "node_modules/lodash._bindcallback": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", + "integrity": "sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ==", + "dev": true + }, + "node_modules/lodash._createassigner": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz", + "integrity": "sha512-LziVL7IDnJjQeeV95Wvhw6G28Z8Q6da87LWKOPWmzBLv4u6FAT/x5v00pyGW0u38UoogNF2JnD3bGgZZDaNEBw==", + "dev": true, + "dependencies": { + "lodash._bindcallback": "^3.0.0", + "lodash._isiterateecall": "^3.0.0", + "lodash.restparam": "^3.0.0" + } + }, + "node_modules/lodash._createcompounder": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._createcompounder/-/lodash._createcompounder-3.0.0.tgz", + "integrity": "sha512-D6HOkfALqHY2Qe/CXda7I1SVo8714LG1Ayo7VP2RQs8oha08eXSbAYnTg/fxtaOI7RX6GVIAJ2Gw3rkr02HXhQ==", + "dev": true, + "dependencies": { + "lodash.deburr": "^3.0.0", + "lodash.words": "^3.0.0" + } + }, + "node_modules/lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA==", + "dev": true + }, + "node_modules/lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha512-De+ZbrMu6eThFti/CSzhRvTKMgQToLxbij58LMfM8JnYDNSOjkjTCIaa8ixglOeGh2nyPlakbt5bJWJ7gvpYlQ==", + "dev": true + }, + "node_modules/lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha512-Sjlavm5y+FUVIF3vF3B75GyXrzsfYV8Dlv3L4mEpuB9leg8N6yf/7rU06iLPx9fY0Mv3khVp9p7Dx0mGV6V5OQ==", + "dev": true + }, + "node_modules/lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha512-OrPwdDc65iJiBeUe5n/LIjd7Viy99bKwDdk7Z5ljfZg0uFRFlfQaCy9tZ4YMAag9WAZmlVpe1iZrkIMMSMHD3w==", + "dev": true + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", + "dev": true + }, + "node_modules/lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ==", + "dev": true + }, + "node_modules/lodash.assign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-3.2.0.tgz", + "integrity": "sha512-/VVxzgGBmbphasTg51FrztxQJ/VgAUpol6zmJuSVSGcNg4g7FA4z7rQV8Ovr9V3vFBNWZhvKWHfpAytjTVUfFA==", + "dev": true, + "dependencies": { + "lodash._baseassign": "^3.0.0", + "lodash._createassigner": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "node_modules/lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg==", + "dev": true + }, + "node_modules/lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha512-lxdsn7xxlCymgLYo1gGvVrfHmkjDiyqVv62FAeF2i5ta72BipE1SLxw8hPEPLhD4/247Ijw07UQH7Hq/chT5LA==", + "dev": true + }, + "node_modules/lodash.camelcase": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-3.0.1.tgz", + "integrity": "sha512-9wNcnz9dBpQ4laWW4je9Lqtjaj3n2QrWLK8fVTjSRfQlUcIrqYxbKxsiDtXV80abRfdlnLLvtOGMd6B+brC3AA==", + "dev": true, + "dependencies": { + "lodash._createcompounder": "^3.0.0" + } + }, + "node_modules/lodash.clonedeep": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-3.0.2.tgz", + "integrity": "sha512-I8MpGh5z+6OixDAAb21teLSZDmqVPjlq02Q7ZFrbn2xnQHYYuJf6on/94SWpF/p0s3p/cEv/53ro4AhDOfCR0g==", + "dev": true, + "dependencies": { + "lodash._baseclone": "^3.0.0", + "lodash._bindcallback": "^3.0.0" + } + }, + "node_modules/lodash.deburr": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.deburr/-/lodash.deburr-3.2.0.tgz", + "integrity": "sha512-MGjyYe8cBGUmPnE+AeeRychzUak8pUIe48Zli95iExeCC3qgRzEf3DiI3A/i5KnSWPPmaB2samsdm6gvACmCTg==", + "dev": true, + "dependencies": { + "lodash._root": "^3.0.0" + } + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "dev": true + }, + "node_modules/lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha512-n1PZMXgaaDWZDSvuNZ/8XOcYO2hOKDqZel5adtR30VKQAtoWs/5AOeFA0vPV8moiPzlqe7F4cP2tzpFewQyelQ==", + "dev": true, + "dependencies": { + "lodash._root": "^3.0.0" + } + }, + "node_modules/lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha512-pXYUy7PR8BCLwX5mgJ/aNtyOvuJTdZAo9EQFUvMIYugqmJxnrYaANvTbgndOzHSCSR0wnlBBfRXJL5SbWxo3FQ==", + "dev": true + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", + "dev": true + }, + "node_modules/lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==", + "dev": true + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "dev": true + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", + "dev": true + }, + "node_modules/lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ==", + "dev": true + }, + "node_modules/lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha512-CuBsapFjcubOGMn3VD+24HOAPxM79tH+V6ivJL3CHYjtrawauDJHUk//Yew9Hvc6e9rbCrURGk8z6PC+8WJBfQ==", + "dev": true, + "dependencies": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "node_modules/lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.partition": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.partition/-/lodash.partition-4.6.0.tgz", + "integrity": "sha512-35L3dSF3Q6V1w5j6V3NhNlQjzsRDC/pYKCTdYTmwqSib+Q8ponkAmt/PwEOq3EmI38DSCl+SkIVwLd+uSlVdrg==", + "dev": true + }, + "node_modules/lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", + "dev": true + }, + "node_modules/lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw==", + "dev": true + }, + "node_modules/lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha512-qkTuvgEzYdyhiJBx42YPzPo71R1aEr0z79kAv7Ixg8wPFEjgRgJdUsGMG3Hf3OYSF/kHI79XhNlt+5Ar6OzwxQ==", + "dev": true + }, + "node_modules/lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw==", + "dev": true + }, + "node_modules/lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ==", + "dev": true + }, + "node_modules/lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha512-0B4Y53I0OgHUJkt+7RmlDFWKjVAI/YUpWNiL9GQz5ORDr4ttgfQGo+phBWKFLJbBdtOwgMuUkdOHOnPg45jKmQ==", + "dev": true, + "dependencies": { + "lodash._basecopy": "^3.0.0", + "lodash._basetostring": "^3.0.0", + "lodash._basevalues": "^3.0.0", + "lodash._isiterateecall": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0", + "lodash.keys": "^3.0.0", + "lodash.restparam": "^3.0.0", + "lodash.templatesettings": "^3.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha512-TcrlEr31tDYnWkHFWDCV3dHYroKEXpJZ2YJYvJdhN+y4AkWMDZ5I4I8XDtUKqSAyG81N7w+I1mFEJtcED+tGqQ==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0" + } + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "node_modules/lodash.words": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.words/-/lodash.words-3.2.0.tgz", + "integrity": "sha512-ZsfO33BwfQ0Eq3YDX7TJOwRC9/owKfKaCyKm5bWxBePVf8kKhlJBkOSGrj4+NM6XU07Mq2lYnyJGZ8zyeu/m3Q==", + "dev": true, + "dependencies": { + "lodash._root": "^3.0.0" + } + }, + "node_modules/log-update": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz", + "integrity": "sha512-4vSow8gbiGnwdDNrpy1dyNaXWKSCIPop0EHdE8GrnngHoJujM3QhvHUN/igsYCgPoHo7pFOezlJ61Hlln0KHyA==", + "dev": true, + "dependencies": { + "ansi-escapes": "^1.0.0", + "cli-cursor": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha512-k+yt5n3l48JU4k8ftnKG6V7u32wyH2NfKzeMto9F/QRE0amxy/LayxwlvjjkZEIzqR+19IrtFO8p5kB9QaYUFg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", + "dev": true, + "dependencies": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/make-error-cause": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz", + "integrity": "sha512-4TO2Y3HkBnis4c0dxhAgD/jprySYLACf7nwN6V0HAHDx59g12WlRpUmFy1bRHamjGUEEBrEvCq6SUpsEE2lhUg==", + "dev": true, + "dependencies": { + "make-error": "^1.2.0" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/marked": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", + "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", + "dev": true, + "bin": { + "marked": "bin/marked" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/marked-terminal": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-3.3.0.tgz", + "integrity": "sha512-+IUQJ5VlZoAFsM5MHNT7g3RHSkA3eETqhRCdXv4niUMAKHQ7lb1yvAcuGPmm4soxhmtX13u4Li6ZToXtvSEH+A==", + "dev": true, + "dependencies": { + "ansi-escapes": "^3.1.0", + "cardinal": "^2.1.1", + "chalk": "^2.4.1", + "cli-table": "^0.3.1", + "node-emoji": "^1.4.1", + "supports-hyperlinks": "^1.0.1" + }, + "peerDependencies": { + "marked": "^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0" + } + }, + "node_modules/marked-terminal/node_modules/ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/marked-terminal/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/marked-terminal/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/marked-terminal/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/marked-terminal/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/math-expression-evaluator": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.4.0.tgz", + "integrity": "sha512-4vRUvPyxdO8cWULGTh9dZWL2tZK6LDBvj+OGHBER7poH9Qdt7kXEoj20wiz4lQUbUXQZFjPbe5mVDo9nutizCw==", + "dev": true + }, + "node_modules/math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memory-fs": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", + "integrity": "sha512-+y4mDxU4rvXXu5UDSGCGNiesFmwCHuefGMoPCO1WYucNYj7DsLqrFaa2fXVI0H+NNiPTwwzKwspn9yTZqUGqng==", + "dev": true + }, + "node_modules/meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA==", + "dev": true, + "dependencies": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", + "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==", + "dev": true + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha512-LnU2XFEk9xxSJ6rfgAry/ty5qwUTyHYOBU0g4R6tIw5ljwgGIBmiKhRWLw5NpMOnrgUNcDJ4WMp8rl3sYVHLNA==", + "dev": true, + "dependencies": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", + "dev": true, + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha512-0mzK8ymiWdehTBiJh0vClAzGyQbdtyWqzSVx//EK4N/D+599RFlGfTAsKw2zMSABtDG9C6Ul2+t8f2Lbdjf5mA==", + "dev": true, + "dependencies": { + "array-differ": "^1.0.0", + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "minimatch": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha512-7ZxrUybYv9NonoXgwoOqtStIu18D1c3eFZj27hqgf5kBrBF8Q+tE8V0MW8dKM5QLkQPh1JhhbKgHLY9kifov4Q==", + "dev": true, + "dependencies": { + "duplexer2": "0.0.2" + } + }, + "node_modules/nan": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", + "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", + "dev": true, + "optional": true + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-libs-browser": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-0.7.0.tgz", + "integrity": "sha512-V0EeBff5/nauAta4yGYMdn/CYXpn2KYcE8r6rwU9qJDXG6wMrBhtWVfoKWphSvsnX+mZk6DzaGSO+Yz/MGBAGQ==", + "dev": true, + "dependencies": { + "assert": "^1.1.1", + "browserify-zlib": "^0.1.4", + "buffer": "^4.9.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "3.3.0", + "domain-browser": "^1.1.1", + "events": "^1.0.0", + "https-browserify": "0.0.1", + "os-browserify": "^0.2.0", + "path-browserify": "0.0.0", + "process": "^0.11.0", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.0.5", + "stream-browserify": "^2.0.1", + "stream-http": "^2.3.1", + "string_decoder": "^0.10.25", + "timers-browserify": "^2.0.2", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.10.3", + "vm-browserify": "0.0.4" + } + }, + "node_modules/node-libs-browser/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/node-libs-browser/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/node-libs-browser/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/node-libs-browser/node_modules/readable-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/node-libs-browser/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/node-libs-browser/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true + }, + "node_modules/node-notifier": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-4.6.1.tgz", + "integrity": "sha512-UPTmeIGLTzZSizsf7EX8xr1iN/xXbULADNW3aOHnNf6mSUu2vtWcRTLTKHs/iNfV9Gbttp0iTQfICDNOeqlsLw==", + "dev": true, + "dependencies": { + "cli-usage": "^0.1.1", + "growly": "^1.2.0", + "lodash.clonedeep": "^3.0.0", + "minimist": "^1.1.1", + "semver": "^5.1.0", + "shellwords": "^0.1.0", + "which": "^1.0.5" + }, + "bin": { + "notify": "bin.js" + } + }, + "node_modules/node-status-codes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", + "integrity": "sha512-1cBMgRxdMWE8KeWCqk2RIOrvUb0XCwYfEsY5/y2NlXyq4Y/RumnOZvTj4Nbr77+Vb2C+kyBoRTdkNOS8L3d/aQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha512-A48My/mtCklowHBlI8Fq2jFWK4tX4lJ5E6ytFsSOq1fzpvT0SQSgKhSg7lN5c2uYFOrUAOQp6zhhJnpp1eMloQ==", + "dev": true, + "dependencies": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==", + "dev": true + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nwmatcher": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", + "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==", + "dev": true + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-visit/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", + "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha512-UiAM5mhmIuKLsOvrL+B0U2d1hXHF3bFYWIuH1LMpuV2EJEHG1Ntz06PgLEHjm6VFd87NpH8rastvPoyv6UW2fA==", + "dev": true, + "dependencies": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha512-GZ+g4jayMqzCRMgB2sol7GiCLjKfS1PINkjmx8spcKce1LiVqcbQreXwqs2YAFXC6R03VIG28ZS31t8M866v6A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/open": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/open/-/open-0.0.5.tgz", + "integrity": "sha512-+X/dJYLapVO1VbC620DhtNZK9U4/kQVaTQp/Gh7cb6UTLYfGZzzU2ZXkWrOA/wBrf4UqAFwtLqXYTxe4tSnWQQ==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha512-snN4O4TkigujZphWLN0E//nQmm7790RYaE53DdL7ZYwee2D8DDo9/EyYiKUfN3rneWUjhJnueija3G9I2i0h3g==", + "dev": true, + "dependencies": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "node_modules/optimist/node_modules/minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==", + "dev": true + }, + "node_modules/optimist/node_modules/wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-browserify": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", + "integrity": "sha512-vHbnbzdqWJWvGOm7aOMDXHVUykPG0GdhfLkn5ZDmvbRI+wPj/XoB0/CRAkP9v28eZ7REIPPHJa+8ZEYixsWKmQ==", + "dev": true + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", + "dev": true, + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz", + "integrity": "sha512-PRg65iXMTt/uK8Rfh5zvzkUbfAPitF17YaCY+IbHsYgksiLvtzWWTUildHth3mVaZ7871OJ7gtP4LBRBlmAdXg==", + "dev": true, + "dependencies": { + "got": "^5.0.0", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", + "dev": true + }, + "node_modules/parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha512-FC5TeK0AwXzq3tUBFtH74naWkPQCEWs4K+xMxWZBlKDWu0bVHXGZa+KKqxKidd7xwhdZ19ZNuF2uO1M/r196HA==", + "dev": true, + "dependencies": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse5": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", + "integrity": "sha512-w2jx/0tJzvgKwZa58sj2vAYq/S/K1QJfIB3cWYea/Iu1scFPDQQ3IQiVZTHWtRBwAjv2Yd7S/xeZf3XqLDb3bA==", + "dev": true + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha512-WA3pxi1olUQcsl82W576vkqhUSGp0uBtr/381pxx5WXLp3NC+AB99hUG3aGW7H0Kg9PFr1D8wv1iJeICe+9Mhw==", + "dev": true + }, + "node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pbkdf2-compat": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pbkdf2-compat/-/pbkdf2-compat-2.0.1.tgz", + "integrity": "sha512-JYubxYhymODUUWVq9/Tmo9VQFZ8LyrD/pbXVpwmt1Npr2z29KZwp7+IBT3/PRjr1xpecX4W1EcbjFjp8nE3stQ==", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha512-c6pv3OE78mcZ92ckebVDqg0aWSoKhOTbwCV6qbCWMk546mAL9pZln0+QsN/yQ7fkucd4+yJPLrCBXNt8Ruk+Eg==", + "dev": true, + "dependencies": { + "find-up": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/popsicle": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/popsicle/-/popsicle-8.2.0.tgz", + "integrity": "sha512-KlV0bXG+ozFjKDVdiYmkPMq9KcylEc2446OuMAch1w+zl+YGRO9hy5a4hNT9HEJw4oH7rkyJI+W+uYpmJXsvQg==", + "dev": true, + "dependencies": { + "any-promise": "^1.3.0", + "arrify": "^1.0.0", + "concat-stream": "^1.4.7", + "form-data": "^2.0.0", + "make-error-cause": "^1.2.1", + "throwback": "^1.1.0", + "tough-cookie": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/popsicle-proxy-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/popsicle-proxy-agent/-/popsicle-proxy-agent-3.0.0.tgz", + "integrity": "sha512-+0MhWUYhHbBWWIdKT4sO5cwgEMXPDskC3mGpgiCMLUdJt3mV3OuEFXubSjsiF4UDuiK6XNEst8oasZe9ZCUs8Q==", + "deprecated": "Use `agent` option with `popsicle` directly", + "dev": true, + "dependencies": { + "http-proxy-agent": "^1.0.0", + "https-proxy-agent": "^1.0.0" + } + }, + "node_modules/popsicle-retry": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/popsicle-retry/-/popsicle-retry-3.2.1.tgz", + "integrity": "sha512-AOKZJrHLXZMaMQtQcQW03tDZSgknkFOdoeAv5YuXuE1HqJH3D1oobHYmVIIjmdyBdHsqBnCX1inq2lRX1zocxQ==", + "dev": true, + "dependencies": { + "any-promise": "^1.1.0", + "xtend": "^4.0.1" + } + }, + "node_modules/popsicle-rewrite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/popsicle-rewrite/-/popsicle-rewrite-1.0.0.tgz", + "integrity": "sha512-ySNEf50wDXcSr89LCsAb00dYItQ/Cnisb1aGleYFnc69pmSzFDB090pDvLwptgWWaokvFDiLCAjUWRWZyZku/w==", + "dev": true + }, + "node_modules/popsicle-status": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/popsicle-status/-/popsicle-status-2.0.1.tgz", + "integrity": "sha512-jMzDnC9xEmyF624Fq4kfjWkFZuK4fOiCHKtr9MthCwpmQXRT+Eck1yEXbRwOEoS9qEWQGbi3THsBfC1Bzk7R/A==", + "dev": true + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/postcss-calc": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "integrity": "sha512-iBcptYFq+QUh9gzP7ta2btw50o40s4uLI4UDVgd5yRAZtUDWc5APdl5yQDd2h/TyiZNbJrv0HiYhT102CMgN7Q==", + "dev": true, + "dependencies": { + "postcss": "^5.0.2", + "postcss-message-helpers": "^2.0.0", + "reduce-css-calc": "^1.2.6" + } + }, + "node_modules/postcss-colormin": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", + "integrity": "sha512-XXitQe+jNNPf+vxvQXIQ1+pvdQKWKgkx8zlJNltcMEmLma1ypDRDQwlLt+6cP26fBreihNhZxohh1rcgCH2W5w==", + "dev": true, + "dependencies": { + "colormin": "^1.0.5", + "postcss": "^5.0.13", + "postcss-value-parser": "^3.2.3" + } + }, + "node_modules/postcss-convert-values": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz", + "integrity": "sha512-SE7mf25D3ORUEXpu3WUqQqy0nCbMuM5BEny+ULE/FXdS/0UMA58OdzwvzuHJRpIFlk1uojt16JhaEogtP6W2oA==", + "dev": true, + "dependencies": { + "postcss": "^5.0.11", + "postcss-value-parser": "^3.1.2" + } + }, + "node_modules/postcss-discard-comments": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "integrity": "sha512-yGbyBDo5FxsImE90LD8C87vgnNlweQkODMkUZlDVM/CBgLr9C5RasLGJxxh9GjVOBeG8NcCMatoqI1pXg8JNXg==", + "dev": true, + "dependencies": { + "postcss": "^5.0.14" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz", + "integrity": "sha512-+lk5W1uqO8qIUTET+UETgj9GWykLC3LOldr7EehmymV0Wu36kyoHimC4cILrAAYpHQ+fr4ypKcWcVNaGzm0reA==", + "dev": true, + "dependencies": { + "postcss": "^5.0.4" + } + }, + "node_modules/postcss-discard-empty": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "integrity": "sha512-IBFoyrwk52dhF+5z/ZAbzq5Jy7Wq0aLUsOn69JNS+7YeuyHaNzJwBIYE0QlUH/p5d3L+OON72Fsexyb7OK/3og==", + "dev": true, + "dependencies": { + "postcss": "^5.0.14" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "integrity": "sha512-IyKoDL8QNObOiUc6eBw8kMxBHCfxUaERYTUe2QF8k7j/xiirayDzzkmlR6lMQjrAM1p1DDRTvWrS7Aa8lp6/uA==", + "dev": true, + "dependencies": { + "postcss": "^5.0.16" + } + }, + "node_modules/postcss-discard-unused": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", + "integrity": "sha512-nCbFNfqYAbKCw9J6PSJubpN9asnrwVLkRDFc4KCwyUEdOtM5XDE/eTW3OpqHrYY1L4fZxgan7LLRAAYYBzwzrg==", + "dev": true, + "dependencies": { + "postcss": "^5.0.14", + "uniqs": "^2.0.0" + } + }, + "node_modules/postcss-filter-plugins": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz", + "integrity": "sha512-T53GVFsdinJhgwm7rg1BzbeBRomOg9y5MBVhGcsV0CxurUdVj1UlPdKtn7aqYA/c/QVkzKMjq2bSV5dKG5+AwQ==", + "dev": true, + "dependencies": { + "postcss": "^5.0.4" + } + }, + "node_modules/postcss-merge-idents": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", + "integrity": "sha512-9DHmfCZ7/hNHhIKnNkz4CU0ejtGen5BbTRJc13Z2uHfCedeCUsK2WEQoAJRBL+phs68iWK6Qf8Jze71anuysWA==", + "dev": true, + "dependencies": { + "has": "^1.0.1", + "postcss": "^5.0.10", + "postcss-value-parser": "^3.1.1" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz", + "integrity": "sha512-ma7YvxjdLQdifnc1HFsW/AW6fVfubGyR+X4bE3FOSdBVMY9bZjKVdklHT+odknKBB7FSCfKIHC3yHK7RUAqRPg==", + "dev": true, + "dependencies": { + "postcss": "^5.0.4" + } + }, + "node_modules/postcss-merge-rules": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz", + "integrity": "sha512-Wgg2FS6W3AYBl+5L9poL6ZUISi5YzL+sDCJfM7zNw/Q1qsyVQXXZ2cbVui6mu2cYJpt1hOKCGj1xA4mq/obz/Q==", + "dev": true, + "dependencies": { + "browserslist": "^1.5.2", + "caniuse-api": "^1.5.2", + "postcss": "^5.0.4", + "postcss-selector-parser": "^2.2.2", + "vendors": "^1.0.0" + } + }, + "node_modules/postcss-message-helpers": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", + "integrity": "sha512-tPLZzVAiIJp46TBbpXtrUAKqedXSyW5xDEo1sikrfEfnTs+49SBZR/xDdqCiJvSSbtr615xDsaMF3RrxS2jZlA==", + "dev": true + }, + "node_modules/postcss-minify-font-values": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "integrity": "sha512-vFSPzrJhNe6/8McOLU13XIsERohBJiIFFuC1PolgajOZdRWqRgKITP/A4Z/n4GQhEmtbxmO9NDw3QLaFfE1dFQ==", + "dev": true, + "dependencies": { + "object-assign": "^4.0.1", + "postcss": "^5.0.4", + "postcss-value-parser": "^3.0.2" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "integrity": "sha512-DZhT0OE+RbVqVyGsTIKx84rU/5cury1jmwPa19bViqYPQu499ZU831yMzzsyC8EhiZVd73+h5Z9xb/DdaBpw7Q==", + "dev": true, + "dependencies": { + "postcss": "^5.0.12", + "postcss-value-parser": "^3.3.0" + } + }, + "node_modules/postcss-minify-params": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "integrity": "sha512-hhJdMVgP8vasrHbkKAk+ab28vEmPYgyuDzRl31V3BEB3QOR3L5TTIVEWLDNnZZ3+fiTi9d6Ker8GM8S1h8p2Ow==", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.1", + "postcss": "^5.0.2", + "postcss-value-parser": "^3.0.2", + "uniqs": "^2.0.0" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "integrity": "sha512-e13vxPBSo3ZaPne43KVgM+UETkx3Bs4/Qvm6yXI9HQpQp4nyb7HZ0gKpkF+Wn2x+/dbQ+swNpCdZSbMOT7+TIA==", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.2", + "has": "^1.0.1", + "postcss": "^5.0.14", + "postcss-selector-parser": "^2.0.0" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz", + "integrity": "sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw==", + "dev": true, + "dependencies": { + "postcss": "^6.0.1" + } + }, + "node_modules/postcss-modules-extract-imports/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-extract-imports/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-extract-imports/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-extract-imports/node_modules/postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-modules-extract-imports/node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-modules-extract-imports/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha512-X4cquUPIaAd86raVrBwO8fwRfkIdbwFu7CTfEOjiZQHVQwlHRSkTgH5NLDmMm5+1hQO8u6dZ+TOOJDbay1hYpA==", + "dev": true, + "dependencies": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/css-selector-tokenizer": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz", + "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha512-LTYwnA4C1He1BKZXIx1CYiHixdSe9LWYVKadq9lK5aCCMkoOkFyZ7aigt+srfjlRplJY3gIol6KUNefdMQJdlw==", + "dev": true, + "dependencies": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "node_modules/postcss-modules-scope/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-scope/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-scope/node_modules/css-selector-tokenizer": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz", + "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2" + } + }, + "node_modules/postcss-modules-scope/node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-scope/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-scope/node_modules/postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-modules-scope/node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-modules-scope/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha512-i7IFaR9hlQ6/0UgFuqM6YWaCfA1Ej8WMg8A5DggnH1UGKJvTV/ugqq/KaULixzzOi3T/tF6ClBXcHGCzdd5unA==", + "dev": true, + "dependencies": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^6.0.1" + } + }, + "node_modules/postcss-modules-values/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-values/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-values/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-values/node_modules/postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-modules-values/node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-modules-values/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "integrity": "sha512-RKgjEks83l8w4yEhztOwNZ+nLSrJ+NvPNhpS+mVDzoaiRHZQVoG7NF2TP5qjwnaN9YswUhj6m1E0S0Z+WDCgEQ==", + "dev": true, + "dependencies": { + "postcss": "^5.0.5" + } + }, + "node_modules/postcss-normalize-url": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "integrity": "sha512-WqtWG6GV2nELsQEFES0RzfL2ebVwmGl/M8VmMbshKto/UClBo+mznX8Zi4/hkThdqx7ijwv+O8HWPdpK7nH/Ig==", + "dev": true, + "dependencies": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^1.4.0", + "postcss": "^5.0.14", + "postcss-value-parser": "^3.2.3" + } + }, + "node_modules/postcss-ordered-values": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz", + "integrity": "sha512-5RB1IUZhkxDCfa5fx/ogp/A82mtq+r7USqS+7zt0e428HJ7+BHCxyeY39ClmkkUtxdOd3mk8gD6d9bjH2BECMg==", + "dev": true, + "dependencies": { + "postcss": "^5.0.4", + "postcss-value-parser": "^3.0.1" + } + }, + "node_modules/postcss-reduce-idents": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", + "integrity": "sha512-0+Ow9e8JLtffjumJJFPqvN4qAvokVbdQPnijUDSOX8tfTwrILLP4ETvrZcXZxAtpFLh/U0c+q8oRMJLr1Kiu4w==", + "dev": true, + "dependencies": { + "postcss": "^5.0.4", + "postcss-value-parser": "^3.0.2" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "integrity": "sha512-jJFrV1vWOPCQsIVitawGesRgMgunbclERQ/IRGW7r93uHrVzNQQmHQ7znsOIjJPZ4yWMzs5A8NFhp3AkPHPbDA==", + "dev": true, + "dependencies": { + "postcss": "^5.0.4" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "integrity": "sha512-lGgRqnSuAR5i5uUg1TA33r9UngfTadWxOyL2qx1KuPoCQzfmtaHjp9PuwX7yVyRxG3BWBzeFUaS5uV9eVgnEgQ==", + "dev": true, + "dependencies": { + "has": "^1.0.1", + "postcss": "^5.0.8", + "postcss-value-parser": "^3.0.1" + } + }, + "node_modules/postcss-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha512-3pqyakeGhrO0BQ5+/tGTfvi5IAUAhHRayGK8WFSu06aEv2BmHoXw/Mhb+w7VY5HERIuC+QoUI7wgrCcq2hqCVA==", + "dev": true, + "dependencies": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "node_modules/postcss-svgo": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "integrity": "sha512-y5AdQdgBoF4rbpdbeWAJuxE953g/ylRfVNp6mvAi61VCN/Y25Tu9p5mh3CyI42WbTRIiwR9a1GdFtmDnNPeskQ==", + "dev": true, + "dependencies": { + "is-svg": "^2.0.0", + "postcss": "^5.0.14", + "postcss-value-parser": "^3.2.3", + "svgo": "^0.7.0" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "integrity": "sha512-WZX8r1M0+IyljoJOJleg3kYm10hxNYF9scqAT7v/xeSX1IdehutOM85SNO0gP9K+bgs86XERr7Ud5u3ch4+D8g==", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.1", + "postcss": "^5.0.4", + "uniqs": "^2.0.0" + } + }, + "node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-zindex": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", + "integrity": "sha512-uhRZ2hRgj0lorxm9cr62B01YzpUe63h0RXMXQ4gWW3oa2rpJh+FJAiEAytaFCPU/VgaBS+uW2SJ1XKyDNz1h4w==", + "dev": true, + "dependencies": { + "has": "^1.0.1", + "postcss": "^5.0.4", + "uniqs": "^2.0.0" + } + }, + "node_modules/postcss/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha512-s/46sYeylUfHNjI+sA/78FAHlmIuKqI9wNnzEOGehAlUUYeObv5C2mOinXBjyUyWmJ2SfcS2/ydApH4hTF4WXQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pretty-format": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-4.2.3.tgz", + "integrity": "sha512-wzxxVhkcBaS/F/rjPp7Z7nT4pOD/p5kUVjHOgnuGdkcDMB3Bf9KgmuqRyRK+kIgzOSYyDbSZQ36BWYyz6UB4gw==", + "dev": true + }, + "node_modules/private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/promise-finally": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/promise-finally/-/promise-finally-2.2.1.tgz", + "integrity": "sha512-OtiwORAP//1Ewt1SmLfFfopqGD+CGwSmTbdyH13e4cL4fiOUOI9l/HyZ59TLkKybWUzY+hfDJ8DjMpM/cqo0tg==", + "dev": true, + "dependencies": { + "any-promise": "^1.3.0" + } + }, + "node_modules/promise-polyfill": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-7.1.2.tgz", + "integrity": "sha512-FuEc12/eKqqoRYIGBrUptCBRhobL19PS2U31vMNTfyck1FxPyMfgsXyW4Mav85y/ZN1hop3hOwRlUDok23oYfQ==", + "dev": true + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, + "node_modules/randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "dev": true, + "dependencies": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/randomatic/node_modules/is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/randomatic/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "15.7.0", + "resolved": "https://registry.npmjs.org/react/-/react-15.7.0.tgz", + "integrity": "sha512-5/MMRYmpmM0sMTHGLossnJCrmXQIiJilD6y3YN3TzAwGFj6zdnMtFv6xmi65PHKRV+pehIHpT7oy67Sr6s9AHA==", + "dependencies": { + "create-react-class": "^15.6.0", + "fbjs": "^0.8.9", + "loose-envify": "^1.1.0", + "object-assign": "^4.1.0", + "prop-types": "^15.5.10" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-addons-test-utils": { + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/react-addons-test-utils/-/react-addons-test-utils-15.6.2.tgz", + "integrity": "sha512-6IUCnLp7jQRBftm2anf8rP8W+8M2PsC7GPyMFe2Wef3Wfml7j2KybVL//Ty7bRDBqLh8AG4m/zNZbFlwulldFw==", + "dev": true, + "peerDependencies": { + "react-dom": "^15.4.2" + } + }, + "node_modules/react-datepicker": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-0.29.0.tgz", + "integrity": "sha512-TA2Sc/EZB3e3VNvAqP5T2yjd1NOpmP5jFouH/f08V7C7nNOfMvU4Rb9v+mS4JmCLdVZbEeAhEyxAeqilYKJo8Q==", + "dependencies": { + "classnames": "^2.2.1", + "moment": "^2.13.0", + "react-onclickoutside": "^4.8.0", + "tether": "^1.3.2" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0", + "react-dom": "^0.14.0 || ^15.0.0" + } + }, + "node_modules/react-deep-force-update": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/react-deep-force-update/-/react-deep-force-update-2.1.3.tgz", + "integrity": "sha512-lqD4eHKVuB65RyO/hGbEST53E2/GPbcIPcFYyeW/p4vNngtH4G7jnKGlU6u1OqrFo0uNfIvwuBOg98IbLHlNEA==", + "dev": true + }, + "node_modules/react-dom": { + "version": "15.7.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.7.0.tgz", + "integrity": "sha512-mpjXqC2t1FuYsILOLCj0kg6pbg460byZkVA/80VtDmKU/pYmoTdHOtaMcTRIDiyXLz4sIur0cQ04nOC6iGndJg==", + "dependencies": { + "fbjs": "^0.8.9", + "loose-envify": "^1.1.0", + "object-assign": "^4.1.0", + "prop-types": "^15.5.10" + }, + "peerDependencies": { + "react": "^15.7.0" + } + }, + "node_modules/react-hot-loader": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-3.1.3.tgz", + "integrity": "sha512-d7nZf78irxoGN5PY4zd6CSgZiroOhvIWzRast3qwTn4sSnBwlt08kV8WMQ9mitmxEdlCTwZt+5ClrRSjxWguMQ==", + "dev": true, + "dependencies": { + "global": "^4.3.0", + "react-deep-force-update": "^2.1.1", + "react-proxy": "^3.0.0-alpha.0", + "redbox-react": "^1.3.6", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/react-hot-loader/node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-onclickoutside": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-4.9.0.tgz", + "integrity": "sha512-q9H25qcZakiJF0jgw9Ql2CKnCl7cr6kdqetTITeuxoGhXoNWqegnfUdA8LXfPDRVGerwb3m+Ow2OXpduH7ZvCw==", + "dependencies": { + "object-assign": "^4.0.1" + } + }, + "node_modules/react-proxy": { + "version": "3.0.0-alpha.1", + "resolved": "https://registry.npmjs.org/react-proxy/-/react-proxy-3.0.0-alpha.1.tgz", + "integrity": "sha512-uyPHKDJ99eBf/wTi768z176I8+c2NvGG5wKdctvHJO5XyZl/brIiwDQ+HBA8Zag5nDdTICYxdBafxBiUxJARrQ==", + "dev": true, + "dependencies": { + "lodash": "^4.6.1" + } + }, + "node_modules/react-router": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-2.8.1.tgz", + "integrity": "sha512-8CmCXkPag5JmqUlLxeyRzVsntAhIdhfIbdNqsOaNOE0imG9NgZIdSn4jWEvGIyw7YAGbvyJ15BDAad+2R/Zj3Q==", + "dependencies": { + "history": "^2.1.2", + "hoist-non-react-statics": "^1.2.0", + "invariant": "^2.2.1", + "loose-envify": "^1.2.0", + "warning": "^3.0.0" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0" + } + }, + "node_modules/read-all-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", + "integrity": "sha512-DI1drPHbmBcUDWrJ7ull/F2Qb8HkwBncVx8/RpKYFSIACYaVRQReISYPdZz/mt1y1+qMCOrfReTopERmaxtP6w==", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-all-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/read-all-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/read-all-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/read-all-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", + "dev": true, + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", + "dev": true, + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/readdirp/node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/readdirp/node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/readdirp/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/readdirp/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/redbox-react": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/redbox-react/-/redbox-react-1.6.0.tgz", + "integrity": "sha512-mLjM5eYR41yOp5YKHpd3syFeGq6B4Wj5vZr64nbLvTZW5ZLff4LYk7VE4ITpVxkZpCY6OZuqh0HiP3A3uEaCpg==", + "dependencies": { + "error-stack-parser": "^1.3.6", + "object-assign": "^4.0.1", + "prop-types": "^15.5.4", + "sourcemapped-stacktrace": "^1.1.6" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16.0.0-beta || ^16.0.0", + "react-dom": "^0.14.0 || ^15.0.0 || ^16.0.0-beta || ^16.0.0" + } + }, + "node_modules/redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==", + "dev": true, + "dependencies": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dev": true, + "dependencies": { + "esprima": "~4.0.0" + } + }, + "node_modules/redeyed/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/reduce-css-calc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "integrity": "sha512-0dVfwYVOlf/LBA2ec4OwQ6p3X9mYxn/wOl2xTcLwjnPYrkgEfPx3VI4eGCH3rQLlPISG5v9I9bkZosKsNRTRKA==", + "dev": true, + "dependencies": { + "balanced-match": "^0.4.2", + "math-expression-evaluator": "^1.2.14", + "reduce-function-call": "^1.0.1" + } + }, + "node_modules/reduce-css-calc/node_modules/balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha512-STw03mQKnGUYtoNjmowo4F2cRmIIxYEGiMsjjwla/u5P1lxadj/05WkNaFjNiKTgJkj8KiXbgAiRTmcQRwQNtg==", + "dev": true + }, + "node_modules/reduce-function-call": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.3.tgz", + "integrity": "sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "node_modules/regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "dependencies": { + "is-equal-shallow": "^0.1.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==", + "dev": true, + "dependencies": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "node_modules/registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "dev": true, + "dependencies": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==", + "dev": true, + "dependencies": { + "rc": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/remap-istanbul": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/remap-istanbul/-/remap-istanbul-0.7.0.tgz", + "integrity": "sha512-0reM3U7UbfTdUhwNWs5qMbqeSencGl19Wq3PpYu4odGamuunrjXZcWXiKAbILOveyl/WRbD5NOgZLvwwIZYGRw==", + "dev": true, + "dependencies": { + "amdefine": "1.0.0", + "gulp-util": "3.0.7", + "istanbul": "0.4.5", + "source-map": ">=0.5.6", + "through2": "2.0.1" + }, + "bin": { + "remap-istanbul": "bin/remap-istanbul" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==", + "dev": true, + "dependencies": { + "is-finite": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha512-AFBWBy9EVRTa/LhEcG8QDP3FvpwZqmvN2QFDuJswFeaVhWnZMp8q3E6Zd90SR04PlIwfGdyVjNyLPyen/ek5CQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", + "dev": true + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", + "dev": true + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, + "node_modules/restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha512-reSjH4HuiFlxlaBaFCiS6O76ZGG2ygKoSlCsipKdaZuKSPx/+bt9mULkn4l0asVzbEfQQmXRg6Wp6gv6m0wElw==", + "dev": true, + "dependencies": { + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha512-yqINtL/G7vs2v+dFIZmFUDbnVyFUJFKd6gK22Kgo6R4jfJGFtisKyncWDDULgjfqf4ASQuIQyjJ7XZ+3aWpsAg==", + "dev": true, + "dependencies": { + "align-text": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ripemd160": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-0.2.0.tgz", + "integrity": "sha512-JJsJ74Mw4sUDDisXGDnNNyN9xWmt5HcH6Kwvb/0m/IvTKjnLAtZfzeoLdpxk44AxQZki54oCCd+Kt0nPQ2AF2g==", + "dev": true + }, + "node_modules/safe-array-concat": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.1.tgz", + "integrity": "sha512-a4i5sUH9QtYYwK3n+9LEumSTV3VMZwlH2xkf/MdMd1dGtFr7wjCbJi9RoKEgfNpX3utiIsNEhadCCqBTKOtaGQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sane": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sane/-/sane-1.4.1.tgz", + "integrity": "sha512-SYAk0K6cl6My8GfdH5eLZUVGh4u/rMk78YeD36PutZPrNA7YZqZCF5dweNA4zm1pQamBx4EnCUdm1Ow12DYhJQ==", + "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", + "dev": true, + "dependencies": { + "exec-sh": "^0.2.0", + "fb-watchman": "^1.8.0", + "minimatch": "^3.0.2", + "minimist": "^1.1.1", + "walker": "~1.0.5", + "watch": "~0.10.0" + }, + "bin": { + "sane": "src/cli.js" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==", + "dev": true + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha512-gL8F8L4ORwsS0+iQ34yCYv///jsOq0ZL7WP55d1HnJ32o7tyFYEFQZQA22mrLIacZdU6xecaBBZ+uEiffGNyXw==", + "dev": true, + "dependencies": { + "semver": "^5.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/sha.js": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.2.6.tgz", + "integrity": "sha512-GC+qN4sf/O6bDwz6CHaz8HVQfLbbNyIsXpTZLiD5c1badnWA63WVAH1msoCq+fXcV0dZ50jxTqKA8seu40845A==", + "dev": true, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha512-up04hB2hR92PgjpyU3y/eg91yIBILyjVY26NvvciY3EVVPjybkMszMpXQ9QAkcS3I5rtJBDLoTxxg+qvW8c7rw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha512-7bgVOAnPj3XjrKY577S+puCKGCRlUrcrEdsMeRXlg9Ghf5df/xNi6sONUa43WrHUd3TjJBF7O04jYoiY0FVa0A==", + "deprecated": "This module moved to @hapi/sntp. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.", + "dev": true, + "optional": true, + "dependencies": { + "hoek": "2.x.x" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sockjs-client": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.6.1.tgz", + "integrity": "sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "eventsource": "^2.0.2", + "faye-websocket": "^0.11.4", + "inherits": "^2.0.4", + "url-parse": "^1.5.10" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://tidelift.com/funding/github/npm/sockjs-client" + } + }, + "node_modules/sockjs-client/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/sockjs-client/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/sockjs/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-list-map": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", + "integrity": "sha512-cabwdhnSNf/tTDMh/DXZXlkeQLvdYT5xfGYBohqHG7wb3bBQrQlHQNWM9NWSOboXXK1zgwz6JzS5e4hZq9vxMw==", + "dev": true + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "dependencies": { + "source-map": "^0.5.6" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", + "dev": true + }, + "node_modules/sourcemapped-stacktrace": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/sourcemapped-stacktrace/-/sourcemapped-stacktrace-1.1.11.tgz", + "integrity": "sha512-O0pcWjJqzQFVsisPlPXuNawJHHg9N9UgpJ/aDmvi9+vnS3x1C0NhwkVFzzZ1VN0Xo+bekyweoqYvBw5ZBKiNnQ==", + "dependencies": { + "source-map": "0.5.6" + } + }, + "node_modules/sourcemapped-stacktrace/node_modules/source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sparkles": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", + "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", + "dev": true + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackframe": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-0.3.1.tgz", + "integrity": "sha512-XmoiF4T5nuWEp2x2w92WdGjdHGY/cZa6LIbRsDRQR/Xlk4uW0PAUlH1zJYVffocwKpCdwyuypIp25xsSXEtZHw==" + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-browserify/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/stream-browserify/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/stream-browserify/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/stream-browserify/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/stream-cache": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stream-cache/-/stream-cache-0.0.2.tgz", + "integrity": "sha512-FsMTiRi4aXOcbL3M2lh7yAOWqM7kfVWQfkJ6kelrhdKNpJJVm0IebICQ2LURsbC5w9XfPSRwd9DkfqDHR9OP3g==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/stream-http/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/stream-http/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/stream-http/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/stream-http/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-template": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-1.0.0.tgz", + "integrity": "sha512-SLqR3GBUXuoPP5MmYtD7ompvXiG87QjT6lzOszyXjTM86Uu7At7vNnt2xgyTLq5o9T4IxTYFyGxcULqpsmsfdg==", + "dev": true + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringstream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", + "dev": true, + "optional": true + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "dev": true, + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA==", + "dev": true, + "dependencies": { + "get-stdin": "^4.0.1" + }, + "bin": { + "strip-indent": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha512-AOPG8EBc5wAikaG1/7uFCNFJwnKOuQwFTpYBdTW6OvWHeZBQBrAA/amefHGrEiOnCPcLFZK6FUPtWVKpQVIRgg==", + "dev": true, + "bin": { + "strip-json-comments": "cli.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/style-loader": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.13.2.tgz", + "integrity": "sha512-0lN0o7DS1G/HRoYJQMEO3yP+tNCuAnNuX1mt/2Yw4edSok45vebtyJoHUyBREasuPYBtZpC3d8wvgY/WD68ZJg==", + "dev": true, + "dependencies": { + "loader-utils": "^1.0.2" + } + }, + "node_modules/style-loader/node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/style-loader/node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/style-loader/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/style-loader/node_modules/loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/supports-hyperlinks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz", + "integrity": "sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw==", + "dev": true, + "dependencies": { + "has-flag": "^2.0.0", + "supports-color": "^5.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svgo": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", + "integrity": "sha512-jT/g9FFMoe9lu2IT6HtAxTA7RR2XOrmcrmCtGnyB/+GQnV6ZjNn+KOHZbZ35yL81+1F/aB6OeEsJztzBQ2EEwA==", + "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", + "dev": true, + "dependencies": { + "coa": "~1.0.1", + "colors": "~1.1.2", + "csso": "~2.3.1", + "js-yaml": "~3.7.0", + "mkdirp": "~0.5.1", + "sax": "~1.2.1", + "whet.extend": "~0.9.9" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/svgo/node_modules/colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha512-ENwblkFQpqqia6b++zLD/KUWafYlVY/UNnAp7oz7LY7E924wmpye416wBOmvv/HMWzl8gL1kJlfvId/1Dg176w==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/svgo/node_modules/js-yaml": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", + "integrity": "sha512-eIlkGty7HGmntbV6P/ZlAsoncFLGsNoM27lkTzS+oneY/EiNhj+geqD9ezg/ip+SW6Var0BJU2JtV0vEUZpWVQ==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^2.6.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/svgo/node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/tapable": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", + "integrity": "sha512-jX8Et4hHg57mug1/079yitEKWGB3LCwoxByLsNim89LABq8NqgiX+6iYVOsq0vX8uJHkU+DZ5fnq95f800bEsQ==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/test-exclude": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-2.1.3.tgz", + "integrity": "sha512-KeBNu9ZFrS3fIVWQuvZ5qKoMVxiX14sEFcKYOfUhhxUZHmPSBthPcjbQJYPUTQSl0oBPF9ckmPKDjPAvctjL6g==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "micromatch": "^2.3.11", + "object-assign": "^4.1.0", + "read-pkg-up": "^1.0.1", + "require-main-filename": "^1.0.1" + } + }, + "node_modules/testcheck": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/testcheck/-/testcheck-0.1.4.tgz", + "integrity": "sha512-pDOhTffyEt7kwfFVPRMXhTiNGxSKGpDnu1srIb9AjDZWf0lWKGF/viOiS+FHvwpzZB1H03aoMH3FvAyk9QzfTg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/tether": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/tether/-/tether-1.4.7.tgz", + "integrity": "sha512-Z0J1aExjoFU8pybVkQAo/vD2wfSO63r+XOPfWQMC5qtf1bI7IWqNk4MiyBcgvvnY8kqnY06dVdvwTK2S3PU/Fw==" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/throat": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-3.2.0.tgz", + "integrity": "sha512-/EY8VpvlqJ+sFtLPeOgc8Pl7kQVOWv0woD87KTXVHPIAE842FGT+rokxIhe8xIUP1cfgrkt0as0vDLjDiMtr8w==", + "dev": true + }, + "node_modules/through2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.1.tgz", + "integrity": "sha512-/vp02SIbpmVHapNMjox4hDBzykPdAOmH5y3INcKaxGfpEPSCMqzdWXyGfqPYyxoBLo1JpxBrlh3Z9esv0vWUYw==", + "dev": true, + "dependencies": { + "readable-stream": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/through2/node_modules/process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==", + "dev": true + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha512-TXcFfb63BQe1+ySzsHZI/5v1aJPCShfqvWJ64ayNImXMsN1Cd0YGk/wm8KB7/OeessgPc9QvS9Zou8QTkFzsLw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true + }, + "node_modules/throwback": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/throwback/-/throwback-1.1.1.tgz", + "integrity": "sha512-3+kMV9CVkLb9k1adHi58IeFJDLK0LJZPC7SKUMtSmj41a4nFEubsXsGLyu4sFVHFo4tXvWVK908LtJR5oWtnrA==", + "dev": true, + "dependencies": { + "any-promise": "^1.3.0" + } + }, + "node_modules/time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/timed-out": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz", + "integrity": "sha512-pqqJOi1rF5zNs/ps4vmbE4SFCrM4iR7LW+GHAsHqO/EumqbIWceioevYLM5xZRgQSH6gFgL9J/uB7EcJhQ9niQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true, + "dependencies": { + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-1.0.0.tgz", + "integrity": "sha512-7PLLVW4cfMVYXtMgX0ynJvyZDiupF2rzGzzf0yATTzgCgNK98DHjRSTm5zU1bFUtRjFdXNrEynn9+vhflVpC0A==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "touch": "bin/touch.js" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch/node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ts-jest": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-0.1.13.tgz", + "integrity": "sha512-NE9xloQ9P1vEhuAbUUxLmc/nyYpS7DyNG6kpWM66OHZ1LIvxpTYcHhsfZh6fjKZEv+Nc87lm9LOV/Ga/hXp9Sw==", + "dev": true, + "dependencies": { + "glob-all": "^3.1.0", + "istanbul-lib-instrument": "^1.2.0", + "jest-config": "^16.0.2", + "jest-util": "^16.0.2", + "lodash.assign": "^4.2.0", + "lodash.includes": "^4.3.0", + "lodash.partition": "^4.6.0", + "remap-istanbul": "^0.7.0", + "source-map-support": "^0.4.4", + "yargs": "^6.1.1" + }, + "peerDependencies": { + "jest": "~16.0.2", + "typescript": "~2.0.6" + } + }, + "node_modules/ts-jest/node_modules/camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ts-jest/node_modules/lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", + "dev": true + }, + "node_modules/ts-jest/node_modules/yargs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "integrity": "sha512-6/QWTdisjnu5UHUzQGst+UOEuEVwIzFVGBjq3jMTFNs5WJQsH/X6nMURSaScIdF5txylr1Ao9bvbWiKi2yXbwA==", + "dev": true, + "dependencies": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "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", + "y18n": "^3.2.1", + "yargs-parser": "^4.2.0" + } + }, + "node_modules/ts-jest/node_modules/yargs-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "integrity": "sha512-+QQWqC2xeL0N5/TE+TY6OGEqyNRM+g2/r712PDNYgiCdXYCApXf1vzfmDSLBxfGRwV+moTq/V8FnMI24JCm2Yg==", + "dev": true, + "dependencies": { + "camelcase": "^3.0.0" + } + }, + "node_modules/ts-loader": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-0.8.2.tgz", + "integrity": "sha512-6cTtQmlLgs4m0HlwH+6p7beVqGJALFwLeqKUGtXBDPkOgS0Q2tYmC/qZiF+EkBrfFqyC/5ysNa9Y6Ph/CvHPgg==", + "dev": true, + "dependencies": { + "arrify": "^1.0.0", + "colors": "^1.0.3", + "enhanced-resolve": "^0.9.0", + "loader-utils": "^0.2.6", + "object-assign": "^2.0.0", + "semver": "^5.0.1" + } + }, + "node_modules/ts-loader/node_modules/object-assign": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", + "integrity": "sha512-CdsOUYIh5wIiozhJ3rLQgmUTgcyzFwZZrqhkKhODMoGtPKM+wt0h0CNIoauJWMsS9822EdzPsF/6mb4nLvPN5g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tslint": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-3.15.1.tgz", + "integrity": "sha512-wkqXlDiU1qG31dMuxnCSNeNMdKmSaEMYgJ2RERgFkt1WvVEF/wYwUYR396DDDcJDDBYpq16a6XJodQh70IRtBQ==", + "dev": true, + "dependencies": { + "colors": "^1.1.2", + "diff": "^2.2.1", + "findup-sync": "~0.3.0", + "glob": "^7.0.3", + "optimist": "~0.6.0", + "resolve": "^1.1.7", + "underscore.string": "^3.3.4" + }, + "bin": { + "tslint": "bin/tslint" + }, + "peerDependencies": { + "typescript": ">=1.7.3" + } + }, + "node_modules/tslint-loader": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/tslint-loader/-/tslint-loader-2.1.5.tgz", + "integrity": "sha512-iCOBqlKZqgJ8dBGvovA/+wNEsyus2m6olMDpWn6sM3/045vnf181HMF+U9Ob5CVyM8I/9j1Ja8tdMR5ldON40w==", + "dev": true, + "dependencies": { + "loader-utils": "^0.2.7", + "mkdirp": "^0.5.1", + "object-assign": "^4.0.1", + "rimraf": "^2.4.4", + "strip-json-comments": "^1.0.2" + }, + "peerDependencies": { + "tslint": "^3.0.0" + } + }, + "node_modules/tslint/node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/tslint/node_modules/diff": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-2.2.3.tgz", + "integrity": "sha512-9wfm3RLzMp/PyTFWuw9liEzdlxsdGixCW0ZTU1XDmtlAkvpVXTPGF8KnfSs0hm3BPbg19OrUPPsRkHXoREpP1g==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "node_modules/typescript": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.0.10.tgz", + "integrity": "sha512-A1McfqUmeBy/8UpP106D7ShCZ3/C6w1muFGDEQ+2EhvwHcWC4uduBntOM8lXlHWOnWOA1vHo48lKe9ZDrJZsJg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/typings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/typings/-/typings-1.5.0.tgz", + "integrity": "sha512-TkrmcDqBe6kUwyJ+L4+A9nlgYRaMKDhaCTG5BmkmlkeOCrs7OoH4ZKw35dvWQxLKeyUJuYx8yAJxcUJ8hKF1mw==", + "deprecated": "Typings is deprecated in favor of NPM @types -- see README for more information", + "dev": true, + "dependencies": { + "any-promise": "^1.3.0", + "archy": "^1.0.0", + "bluebird": "^3.1.1", + "chalk": "^1.0.0", + "cli-truncate": "^0.2.1", + "columnify": "^1.5.2", + "elegant-spinner": "^1.0.1", + "has-unicode": "^2.0.1", + "listify": "^1.0.0", + "log-update": "^1.0.2", + "minimist": "^1.2.0", + "promise-finally": "^2.2.1", + "typings-core": "^1.6.1", + "update-notifier": "^1.0.0", + "wordwrap": "^1.0.0", + "xtend": "^4.0.1" + }, + "bin": { + "typings": "dist/bin.js" + } + }, + "node_modules/typings-core": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/typings-core/-/typings-core-1.6.1.tgz", + "integrity": "sha512-/mGsefGvvyVFxzU/L/iVr4u2qmy/5F3gKsP1v14VNgVCUvsxA6zW6GIMEtacQKNgxlKs+Rqdg1I/JfAF1Gk7Xw==", + "dev": true, + "dependencies": { + "any-promise": "^1.3.0", + "array-uniq": "^1.0.2", + "configstore": "^2.0.0", + "debug": "^2.2.0", + "detect-indent": "^4.0.0", + "graceful-fs": "^4.1.2", + "has": "^1.0.1", + "invariant": "^2.2.0", + "is-absolute": "^0.2.3", + "listify": "^1.0.0", + "lockfile": "^1.0.1", + "make-error-cause": "^1.2.1", + "mkdirp": "^0.5.1", + "object.pick": "^1.1.1", + "parse-json": "^2.2.0", + "popsicle": "^8.0.2", + "popsicle-proxy-agent": "^3.0.0", + "popsicle-retry": "^3.2.0", + "popsicle-rewrite": "^1.0.0", + "popsicle-status": "^2.0.0", + "promise-finally": "^2.0.1", + "rc": "^1.1.5", + "rimraf": "^2.4.4", + "sort-keys": "^1.0.0", + "string-template": "^1.0.0", + "strip-bom": "^2.0.0", + "thenify": "^3.1.0", + "throat": "^3.0.0", + "touch": "^1.0.0", + "typescript": "^2.0.3", + "xtend": "^4.0.0", + "zip-object": "^0.1.0" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.37", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.37.tgz", + "integrity": "sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "engines": { + "node": "*" + } + }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha512-vb2s1lYx2xBtUgy+ta+b2J/GLVUR+wmpINwHePmPRhOsIVCG2wDzKJ0n14GslH1BifsqVzSOwQhRaCAsZ/nI4Q==", + "dev": true + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/underscore.string": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", + "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", + "dev": true, + "dependencies": { + "sprintf-js": "^1.1.1", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/underscore.string/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==", + "dev": true + }, + "node_modules/uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha512-mZdDpf3vBV5Efh29kMw5tXoup/buMgxLzOt/XKFKcVmi+15ManNQWr6HfZ2aiZTYlYixbdNJ0KFmIZIv52tHSQ==", + "dev": true + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", + "dev": true, + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/unset-value/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unzip-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", + "integrity": "sha512-pwCcjjhEcpW45JZIySExBHYv5Y9EeL2OIGEfrSKp2dMUFGFv4CpvZkwJbVge8OvGH2BNNtJBx67DuKuJhf+N5Q==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/update-notifier": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-1.0.3.tgz", + "integrity": "sha512-iQSLFuxB2ZFAxXGN28DTxk/GNGlBmtqawvguYDtChAHI9Xjy0z7c7hpw6ywutK34SEDYTpLEsAM1ATMq5pcQsw==", + "dev": true, + "dependencies": { + "boxen": "^0.6.0", + "chalk": "^1.0.0", + "configstore": "^2.0.0", + "is-npm": "^1.0.0", + "latest-version": "^2.0.0", + "lazy-req": "^1.1.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true + }, + "node_modules/url": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", + "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", + "dev": true, + "dependencies": { + "punycode": "^1.4.1", + "qs": "^6.11.2" + } + }, + "node_modules/url-loader": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.5.9.tgz", + "integrity": "sha512-B7QYFyvv+fOBqBVeefsxv6koWWtjmHaMFT6KZWti4KRw8YUD/hOU+3AECvXuzyVawIBx3z7zQRejXCDSO5kk1Q==", + "dev": true, + "dependencies": { + "loader-utils": "^1.0.2", + "mime": "1.3.x" + }, + "peerDependencies": { + "file-loader": "*" + } + }, + "node_modules/url-loader/node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/url-loader/node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/url-loader/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/url-loader/node_modules/loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/url-loader/node_modules/mime": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.6.tgz", + "integrity": "sha512-a/kG+3WTtU8GJG1ngpkkHOHcH6zNjGrI47OQyoFsFBN0QpYYJ4u2yEORsGK5cZMI+cfu9HbSCCfGfRzG0fWE9A==", + "dev": true, + "bin": { + "mime": "cli.js" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==", + "dev": true, + "dependencies": { + "prepend-http": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/url/node_modules/qs": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz", + "integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "dependencies": { + "inherits": "2.0.3" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/util/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha512-P5zdf3WB9uzr7IFoVQ2wZTmUwHL8cMZWJGzLBNCHNZ3NB6HTMsYABtt7z8tAGIINLXyAob9B9a1yzVGMFOYKEA==", + "dev": true, + "dependencies": { + "clone": "^1.0.0", + "clone-stats": "^0.0.1", + "replace-ext": "0.0.1" + }, + "engines": { + "node": ">= 0.9" + } + }, + "node_modules/vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha512-NyZNR3WDah+NPkjh/YmhuWSsT4a0mF0BJYgUmvrJ70zxjTXh5Y2Asobxlh0Nfs0PCFB5FVpRJft7NozAWFMwLQ==", + "dev": true, + "dependencies": { + "indexof": "0.0.1" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha512-jMBt6pUrKn5I+OGgtQ4YZLdhIeJmObddh6CsibPxyQ5yPZm1XExSyzC1LCNX7BzhxWgiHmizBWJTHJIjMjTQYQ==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/watch": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/watch/-/watch-0.10.0.tgz", + "integrity": "sha512-FAk18nzhYggg939xgRRLJjvqmAKZciO24wr8neoxNPl87w8J3m784wxL4zFBwME+0gNQ2Sv/vfsCrUxPxU2Dmg==", + "dev": true, + "engines": [ + "node >=0.1.95" + ] + }, + "node_modules/watchpack": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-0.2.9.tgz", + "integrity": "sha512-hmLWdxNfe0Ou1xaRj+ublbOYUaZJfVz1VuHQfERLVlUrLS21gUaGa2gWRl8L5Ej1aUS3KxFN+1qoWK4kZLMvKw==", + "dev": true, + "dependencies": { + "async": "^0.9.0", + "chokidar": "^1.0.0", + "graceful-fs": "^4.1.2" + } + }, + "node_modules/watchpack/node_modules/async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha512-l6ToIJIotphWahxxHyzK9bnLR6kM4jJIIgLShZeqLY7iboHoGkdgFl7W2/Ivi4SkMJYGKqW8vSuk0uKUj6qsSw==", + "dev": true + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "node_modules/webpack": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-1.15.0.tgz", + "integrity": "sha512-+8bxNSHMZCWBa6hi++2A2pw9GmLUWY6lII+aIXlgUPpB+ClNrUKgP8hx0w+hxjWhX81hclUYPGFg+7NxgLTUYQ==", + "dev": true, + "dependencies": { + "acorn": "^3.0.0", + "async": "^1.3.0", + "clone": "^1.0.2", + "enhanced-resolve": "~0.9.0", + "interpret": "^0.6.4", + "loader-utils": "^0.2.11", + "memory-fs": "~0.3.0", + "mkdirp": "~0.5.0", + "node-libs-browser": "^0.7.0", + "optimist": "~0.6.0", + "supports-color": "^3.1.0", + "tapable": "~0.1.8", + "uglify-js": "~2.7.3", + "watchpack": "^0.2.1", + "webpack-core": "~0.6.9" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/webpack-core": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz", + "integrity": "sha512-P6ZUGXn5buTEZyTStCHHLwtWGKSm/jA629Zgp4pcHSsy60CCsT9MaHDxNIPL+GGJ2KwOgI6ORwQtHcrYHAt2UQ==", + "dev": true, + "dependencies": { + "source-list-map": "~0.1.7", + "source-map": "~0.4.1" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/webpack-core/node_modules/source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha512-Y8nIfcb1s/7DcobUz1yOO1GSp7gyL+D9zLHDehT7iRESqGSxjJ448Sg7rvfgsRJCnKLdSl11uGf0s9X80cH0/A==", + "dev": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "memory-fs": "~0.4.1", + "mime": "^1.5.0", + "path-is-absolute": "^1.0.0", + "range-parser": "^1.0.3", + "time-stamp": "^2.0.0" + }, + "engines": { + "node": ">=0.6" + }, + "peerDependencies": { + "webpack": "^1.0.0 || ^2.0.0 || ^3.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/webpack-dev-middleware/node_modules/memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "node_modules/webpack-dev-middleware/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/webpack-dev-middleware/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/webpack-dev-middleware/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/time-stamp": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-2.2.0.tgz", + "integrity": "sha512-zxke8goJQpBeEgD82CXABeMh0LSJcj7CXEd0OHOg45HgcofF7pxNwZm9+RknpxpDhwN4gFpySkApKfFYfRQnUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server": { + "version": "1.16.5", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-1.16.5.tgz", + "integrity": "sha512-on9j8SBuJXa2lzyIAv0DasJT8SteshUrEjjKc/mc8D68U7RN0mIBZksAcjnPW72RSJa9scWZ+C+Dme76LDH+lA==", + "dev": true, + "dependencies": { + "compression": "^1.5.2", + "connect-history-api-fallback": "^1.3.0", + "express": "^4.13.3", + "http-proxy-middleware": "~0.17.1", + "open": "0.0.5", + "optimist": "~0.6.1", + "serve-index": "^1.7.2", + "sockjs": "^0.3.15", + "sockjs-client": "^1.0.3", + "stream-cache": "~0.0.1", + "strip-ansi": "^3.0.0", + "supports-color": "^3.1.1", + "webpack-dev-middleware": "^1.10.2" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "peerDependencies": { + "webpack": ">=1.3.0 <3" + } + }, + "node_modules/webpack-dev-server/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/webpack-sources": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-0.1.5.tgz", + "integrity": "sha512-8CXYfPZkWvY0VWadHDQ3q2hUBqk2IJKTTdDPYb5hwnGVVma8bzqTJEerUDrpWwXnuY9vxZ0mGEnjYD0XLhRHeQ==", + "dev": true, + "dependencies": { + "source-list-map": "~0.1.7", + "source-map": "~0.5.3" + } + }, + "node_modules/webpack/node_modules/acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/webpack/node_modules/camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha512-wzLkDa4K/mzI1OSITC+DUyjgIl/ETNHE9QvYgy6J6Jvqyyz4C0Xfd+lQhb19sX2jMpZV4IssUn0VDVmglV+s4g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha512-GIOYRizG+TGoc7Wgc1LiOTLare95R3mzKgoln+Q/lE4ceiYH19gUpl0l0Ffq4lJDEf3FxujMe6IBfOCs7pfqNA==", + "dev": true, + "dependencies": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + } + }, + "node_modules/webpack/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/webpack/node_modules/memory-fs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.3.0.tgz", + "integrity": "sha512-QTNXnl79X97kZ9jJk/meJrtDuvgvRakX5LU7HZW1L7MsXHuSTwoMIzN9tOLLH3Xfsj/gbsSqX/ovnsqz246zKQ==", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "node_modules/webpack/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/webpack/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/webpack/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/webpack/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/webpack/node_modules/uglify-js": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.7.5.tgz", + "integrity": "sha512-RvbIYn4DIadCg1MV7YP7OrpxnVrtEieZzbK0KSQvwWGAHojqWJxInkQhmtYGRo9PTwwkJkljIgzMyA1VitEc4Q==", + "dev": true, + "dependencies": { + "async": "~0.2.6", + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/webpack/node_modules/uglify-js/node_modules/async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==", + "dev": true + }, + "node_modules/webpack/node_modules/window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha512-1pTPQDKTdd61ozlKGNCjhNRd+KPmgLSGa3mZTHoOliaGcESD8G1PXhh7c1fgiPjVbNVfgy2Faw4BI8/m0cC8Mg==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/webpack/node_modules/wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha512-xSBsCeh+g+dinoBv3GAOWM4LcVVO68wLXRanibtBSdUvkGWQRGeE9P7IwU9EmDDi4jA6L44lz15CGMwdw9N5+Q==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/webpack/node_modules/yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha512-QFzUah88GAGy9lyDKGBqZdkYApt63rCXYBGYnEP4xDJPXNqXXnBDACnbrXnViV6jRSqAePwrATi2i8mfYm4L1A==", + "dev": true, + "dependencies": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-fetch": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-1.1.1.tgz", + "integrity": "sha512-MVDSiH8wkh6qdk+zxNlUas0pmuKVp8H5RwQZM2tGQhenUC+/nUBmJerAg/lFd3DPYrF2e6ArdaD2JpbGjM9oww==" + }, + "node_modules/whatwg-url": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz", + "integrity": "sha512-nUvUPuenPFtPfy/X+dAYh/TfRbTBlnXTM5iIfLseJFkkQewmpG9pGR6i87E9qL+lZaJzv+99kkQWoGOtLfkZQQ==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/whatwg-url/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whet.extend": { + "version": "0.9.9", + "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", + "integrity": "sha512-mmIPAft2vTgEILgPeZFqE/wWh24SEsR/k+N9fJ3Jxrz44iDFy9aemCxdksfURSHYFCLmvs/d/7Iso5XjPpNfrA==", + "dev": true, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", + "dev": true + }, + "node_modules/which-typed-array": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", + "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.5", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/widest-line": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz", + "integrity": "sha512-r5vvGtqsHUHn98V0jURY4Ts86xJf6+SzK9rpWdV8/73nURB3WFPIHd67aOvPw2fSuunIyHjAUqiJ2TY0x4E5gw==", + "dev": true, + "dependencies": { + "string-width": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==", + "dev": true, + "bin": { + "window-size": "cli.js" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, + "node_modules/worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "dependencies": { + "errno": "~0.1.7" + } + }, + "node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", + "integrity": "sha512-SdrHoC/yVBPpV0Xq/mUZQIpW2sWXAShb/V4pomcJXh92RuaO+f3UTWItiR3Px+pLnV2PvC2/bfn5cwr5X6Vfxw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "slide": "^1.1.5" + } + }, + "node_modules/xdg-basedir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", + "integrity": "sha512-NF1pPn594TaRSUO/HARoB4jK8I+rWgcpVlpQCK6/6o5PHyLUt2CSiDrpUZbQ6rROck+W2EwF8mBJcTs+W98J9w==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/xml-name-validator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", + "integrity": "sha512-jRKe/iQYMyVJpzPH+3HL97Lgu5HrCfii+qSo+TfjKHtOnvbnvdVfMYrn9Q34YV81M2e5sviJlI6Ko9y+nByzvA==", + "dev": true + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true + }, + "node_modules/yargs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-5.0.0.tgz", + "integrity": "sha512-krgVLGNhMWUVY1EJkM/bgbvn3yCIRrsZp6KaeX8hx8ztT+jBtX7/flTQcSHe5089xIDQRUsEr2mzlZVNe/7P5w==", + "dev": true, + "dependencies": { + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.2.0", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "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", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^3.2.0" + } + }, + "node_modules/yargs-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-3.2.0.tgz", + "integrity": "sha512-eANlJIqYwhwS/asi4ybKxkeJYUIjNMZXL36C/KICV5jyudUZWp+/lEfBHM0PuJcQjBfs00HwqePEQjtLJd+Kyw==", + "dev": true, + "dependencies": { + "camelcase": "^3.0.0", + "lodash.assign": "^4.1.0" + } + }, + "node_modules/yargs-parser/node_modules/camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs-parser/node_modules/lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", + "dev": true + }, + "node_modules/yargs/node_modules/lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", + "dev": true + }, + "node_modules/zip-object": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/zip-object/-/zip-object-0.1.0.tgz", + "integrity": "sha512-eujiZK9Z3F/WuswEIWqlaNUwUj67oRw4Op5a1VeKw4n9XBkV7EdxtgblroWBYvLmD7XqZ1cjqsbmE3jU43prTA==", + "dev": true + } + } +} diff --git a/client/src/components/owners/FindOwnersPage.tsx b/client/src/components/owners/FindOwnersPage.tsx index c8737db7..3380fff0 100644 --- a/client/src/components/owners/FindOwnersPage.tsx +++ b/client/src/components/owners/FindOwnersPage.tsx @@ -85,7 +85,7 @@ export default class FindOwnersPage extends React.Component response.json()) diff --git a/client/src/components/owners/OwnerEditor.tsx b/client/src/components/owners/OwnerEditor.tsx index 967790d8..5dafeb71 100644 --- a/client/src/components/owners/OwnerEditor.tsx +++ b/client/src/components/owners/OwnerEditor.tsx @@ -41,7 +41,7 @@ export default class OwnerEditor extends React.Component { if (status === 200 || status === 201) { const newOwner = response as IOwner; @@ -87,4 +87,4 @@ export default class OwnerEditor extends React.Component ); } -} \ No newline at end of file +} diff --git a/client/src/util/index.tsx b/client/src/util/index.tsx index 04a61f23..da79ce81 100644 --- a/client/src/util/index.tsx +++ b/client/src/util/index.tsx @@ -1,7 +1,7 @@ import { IHttpMethod } from '../types'; declare var __API_SERVER_URL__; -const BACKEND_URL = (typeof __API_SERVER_URL__ === 'undefined' ? 'http://localhost:8080' : __API_SERVER_URL__); +const BACKEND_URL = (typeof __API_SERVER_URL__ === 'undefined' ? 'http://localhost:9966/petclinic' : __API_SERVER_URL__); export const url = (path: string): string => `${BACKEND_URL}/${path}`; diff --git a/client/webpack.config.js b/client/webpack.config.js index 80166813..ea26801d 100644 --- a/client/webpack.config.js +++ b/client/webpack.config.js @@ -24,7 +24,7 @@ module.exports = { plugins: [ new webpack.HotModuleReplacementPlugin(), new webpack.DefinePlugin({ - __API_SERVER_URL__: JSON.stringify('http://localhost:8080') + __API_SERVER_URL__: JSON.stringify('http://localhost:9966/petclinic') }) ], resolve: { diff --git a/mvnw b/mvnw index fc7efd17..41c0f0c2 100755 --- a/mvnw +++ b/mvnw @@ -19,7 +19,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script +# Maven Start Up Batch script # # Required ENV vars: # ------------------ @@ -54,38 +54,16 @@ case "`uname`" in CYGWIN*) cygwin=true ;; MINGW*) mingw=true;; Darwin*) darwin=true - # - # Look for the Apple JDKs first to preserve the existing behaviour, and then look - # for the new JDKs provided by Oracle. - # - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then - # - # Oracle JDKs - # - export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then - # - # Apple JDKs - # - export JAVA_HOME=`/usr/libexec/java_home` - fi - ;; + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; esac if [ -z "$JAVA_HOME" ] ; then @@ -130,13 +108,12 @@ if $cygwin ; then CLASSPATH=`cygpath --path --unix "$CLASSPATH"` fi -# For Migwn, ensure paths are in UNIX format before anything is touched +# For Mingw, ensure paths are in UNIX format before anything is touched if $mingw ; then [ -n "$M2_HOME" ] && M2_HOME="`(cd "$M2_HOME"; pwd)`" [ -n "$JAVA_HOME" ] && JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" - # TODO classpath? fi if [ -z "$JAVA_HOME" ]; then @@ -184,27 +161,28 @@ fi CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` -fi - # traverses directory structure from process work directory to filesystem root # first directory with .mvn subdirectory is considered project base directory find_maven_basedir() { - local basedir=$(pwd) - local wdir=$(pwd) + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" while [ "$wdir" != '/' ] ; do if [ -d "$wdir"/.mvn ] ; then basedir=$wdir break fi - wdir=$(cd "$wdir/.."; pwd) + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround done echo "${basedir}" } @@ -216,10 +194,109 @@ concat_lines() { fi } -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" -# Provide a "standardized" way to retrieve the CLI args that will +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will # work with both Windows and non-Windows executions. MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" export MAVEN_CMD_LINE_ARGS @@ -230,5 +307,4 @@ exec "$JAVACMD" \ $MAVEN_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CMD_LINE_ARGS - + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd index 0d49a2de..f0081db3 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -18,7 +18,7 @@ @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script +@REM Maven Start Up Batch script @REM @REM Required ENV vars: @REM JAVA_HOME - location of a JDK home dir @@ -26,7 +26,7 @@ @REM Optional ENV vars @REM M2_HOME - location of maven2's installed home dir @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven @REM e.g. to debug Maven itself, use @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 @@ -35,7 +35,9 @@ @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' @echo off -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% @REM set %HOME% to equivalent of $HOME @@ -80,8 +82,6 @@ goto error :init -set MAVEN_CMD_LINE_ARGS=%MAVEN_CONFIG% %* - @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". @REM Fallback to current working directory if not found. @@ -117,11 +117,48 @@ for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do s :endReadAdditionalConfig SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" - -set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* if ERRORLEVEL 1 goto error goto end diff --git a/petclinic-ermodel.png b/petclinic-ermodel.png new file mode 100644 index 00000000..6c790fb7 Binary files /dev/null and b/petclinic-ermodel.png differ diff --git a/pom.xml b/pom.xml index f2e07de0..0e0b8f06 100644 --- a/pom.xml +++ b/pom.xml @@ -1,40 +1,50 @@ - + 4.0.0 + org.springframework.samples - spring-petclinic-reactjs - 1.4.0 + spring-petclinic-rest + 3.2.1 + + REST version of the Spring Petclinic sample application + https://spring-petclinic.github.io/ + org.springframework.boot spring-boot-starter-parent - 1.4.0.RELEASE + 3.2.1 + - petclinic - jar + + 1.2.1.RELEASE + 2.0.2 + 0.2.1 + 1.4.1.Final + 2.3.0 - - 1.7 - UTF-8 - UTF-8 - arey - - - 1.3 - 5.0.0.GA - - 2.7 + + 0.8.11 + 6.3.0 + 3.2.0 + + 3.4.0 + springcommunity + 3.8.1 - org.springframework.boot spring-boot-starter-actuator + + org.springframework.boot + spring-boot-starter-aop + org.springframework.boot spring-boot-starter-cache @@ -45,86 +55,120 @@ org.springframework.boot - spring-boot-starter-test - test + spring-boot-starter-jdbc org.springframework.boot spring-boot-starter-web - org.springframework.boot - spring-boot-devtools - true - + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-validation + + + org.hsqldb + hsqldb + runtime + + + com.mysql + mysql-connector-j + runtime + + + org.postgresql + postgresql + runtime + - org.apache.tomcat.embed - tomcat-embed-jasper - provided + org.springframework.data + spring-data-jdbc-core + ${spring-data-jdbc.version} + + + org.springframework + * + + + - javax.servlet - jstl + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test - - joda-time - joda-time + com.fasterxml.jackson.core + jackson-core - joda-time - joda-time-hibernate - ${jodatime-hibernate.version} + com.fasterxml.jackson.core + jackson-databind - org.jadira.usertype - usertype.core - ${jadira-usertype-core.version} + com.jayway.jsonpath + json-path + test - com.fasterxml.jackson.datatype - jackson-datatype-joda + org.springdoc + springdoc-openapi-starter-webmvc-ui + ${springdoc-openapi-ui.version} - - org.hsqldb - hsqldb - runtime + org.openapitools + jackson-databind-nullable + ${jackson-databind-nullable.version} + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + org.mapstruct + mapstruct + ${mapstruct.version} - - - - - - javax.cache - cache-api + org.mapstruct + mapstruct-processor + ${mapstruct.version} + - org.ehcache - ehcache + org.mockito + mockito-core + test + + javax.xml.bind + jaxb-api + ${jaxb-api.version} + - - petclinic - install org.springframework.boot spring-boot-maven-plugin - + build-info @@ -132,155 +176,168 @@ ${project.build.sourceEncoding} ${project.reporting.outputEncoding} - ${maven.compiler.source} - ${maven.compiler.target} + ${maven.compiler.release} + - org.apache.maven.plugins - maven-compiler-plugin - 3.0 + org.jacoco + jacoco-maven-plugin + ${jacoco.version} - - - - true - ${java.version} - ${java.version} - true + + + **/org/springframework/samples/petclinic/rest/dto/** + **/org/springframework/samples/petclinic/rest/api/** + + + + + prepare-agent + + + + check + + check + + + + + BUNDLE + + + LINE + COVEREDRATIO + 0.85 + + + BRANCH + COVEREDRATIO + 0.66 + + + + + + + + report + prepare-package + + report + + + + - org.apache.maven.plugins - maven-surefire-plugin - 2.13 + com.google.cloud.tools + jib-maven-plugin + ${docker.jib-maven-plugin.version} - - **/*Tests.java - + + docker.io/${docker.image.prefix}/${project.artifactId} + + ${project.version} + latest + + + + - org.apache.maven.plugins - maven-eclipse-plugin - 2.9 - - true - true - 2.0 - - **/*.* - - - - org.springframework.ide.eclipse.core.springbuilder - - - org.eclipse.m2e.core.maven2Builder - - - - org.eclipse.jdt.core.javanature - org.springframework.ide.eclipse.core.springnature - org.eclipse.m2e.core.maven2Nature - - + org.openapitools + openapi-generator-maven-plugin + + ${openapi-generator-maven-plugin.version} + + + + + generate + + + ${project.basedir}/src/main/resources/openapi.yml + spring + spring-boot + + + Dto + org.springframework.samples.petclinic.rest.api + true + org.springframework.samples.petclinic.rest.dto + + true + + + true + + true + java8 + true + false + + jackson + + springdoc + + + + org.codehaus.mojo - cobertura-maven-plugin - ${cobertura.version} - - - + build-helper-maven-plugin + ${build-helper-maven-plugin.version} + add-source + generate-sources - clean - check + add-source + + + target/generated-sources/openapi/src/main/java + + - - com.spotify - docker-maven-plugin - 0.4.11 + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} - ${docker.image.prefix}/${project.artifactId} - src/main/docker - - - / - ${project.build.directory} - ${project.build.finalName}.jar - - - true - - ${project.version} - latest - - true + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + + + -Amapstruct.suppressGeneratorTimestamp=true + + + -Amapstruct.suppressGeneratorVersionInfoComment=true + + + -Amapstruct.defaultComponentModel=spring + + - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - - org.springframework.boot - - - spring-boot-maven-plugin - - - [1.4.0.RELEASE,) - - - build-info - - - - - - - - - - - - - - - - - org.codehaus.mojo - cobertura-maven-plugin - ${cobertura.version} - - - html - - - - - - - - demopetclinic diff --git a/src/main/docker/Dockerfile b/src/main/docker/Dockerfile deleted file mode 100644 index 2d9a943b..00000000 --- a/src/main/docker/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM openjdk:alpine -MAINTAINER Antoine Rey -# Spring Boot application creates working directories for Tomcat by default -VOLUME /tmp -ADD petclinic.war petclinic.war -RUN sh -c 'touch /petclinic.war' -# To reduce Tomcat startup time we added a system property pointing to "/dev/urandom" as a source of entropy. -ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/petclinic.jar"] diff --git a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java index 80859de9..b41f2f48 100644 --- a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java +++ b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java @@ -1,33 +1,14 @@ -/* - * Copyright 2002-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package org.springframework.samples.petclinic; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; -/** - * PetClinic Spring Boot Application. - * - */ @SpringBootApplication -public class PetClinicApplication { - - public static void main(String[] args) throws Exception { - SpringApplication.run(PetClinicApplication.class, args); - } +public class PetClinicApplication extends SpringBootServletInitializer { + public static void main(String[] args) { + SpringApplication.run(PetClinicApplication.class, args); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/config/CacheConfig.java b/src/main/java/org/springframework/samples/petclinic/config/CacheConfig.java deleted file mode 100644 index 4e1a6a0b..00000000 --- a/src/main/java/org/springframework/samples/petclinic/config/CacheConfig.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.springframework.samples.petclinic.config; - -import java.util.concurrent.TimeUnit; -import javax.cache.CacheManager; - -import org.ehcache.config.CacheConfiguration; -import org.ehcache.config.builders.CacheConfigurationBuilder; -import org.ehcache.config.builders.ResourcePoolsBuilder; -import org.ehcache.config.units.EntryUnit; -import org.ehcache.expiry.Duration; -import org.ehcache.expiry.Expirations; -import org.ehcache.jsr107.Eh107Configuration; - -import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer; -import org.springframework.cache.annotation.EnableCaching; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; - -/** - * Cache could be disable in unit test. - */ -@Configuration -@EnableCaching -@Profile("production") -public class CacheConfig { - - @Bean - public JCacheManagerCustomizer cacheManagerCustomizer() { - return new JCacheManagerCustomizer() { - @Override - public void customize(CacheManager cacheManager) { - CacheConfiguration config = CacheConfigurationBuilder - .newCacheConfigurationBuilder(Object.class, Object.class, - ResourcePoolsBuilder.newResourcePoolsBuilder() - .heap(100, EntryUnit.ENTRIES)) - .withExpiry(Expirations.timeToLiveExpiration(Duration.of(60, TimeUnit.SECONDS))) - .build(); - cacheManager.createCache("vets", Eh107Configuration.fromEhcacheCacheConfiguration(config)); - } - }; - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/config/SwaggerConfig.java b/src/main/java/org/springframework/samples/petclinic/config/SwaggerConfig.java new file mode 100644 index 00000000..44fdae44 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/config/SwaggerConfig.java @@ -0,0 +1,66 @@ +/* + * Copyright 2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.config; + + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Collections; + +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; + +/** + * Java config for Springfox swagger documentation plugin + * + * @author Vitaliy Fedoriv + */ +@Configuration +public class SwaggerConfig { + + @Bean + OpenAPI customOpenAPI() { + + return new OpenAPI().components(new Components()).info(new Info() + .title("REST Petclinic backend Api Documentation").version("1.0") + .termsOfService("Petclinic backend terms of service") + .description( + "This is REST API documentation of the Spring Petclinic backend. If authentication is enabled, when calling the APIs use admin/admin") + .license(swaggerLicense()).contact(swaggerContact())); + } + + private Contact swaggerContact() { + Contact petclinicContact = new Contact(); + petclinicContact.setName("Vitaliy Fedoriv"); + petclinicContact.setEmail("vitaliy.fedoriv@gmail.com"); + petclinicContact.setUrl("https://github.com/spring-petclinic/spring-petclinic-rest"); + return petclinicContact; + } + + private License swaggerLicense() { + License petClinicLicense = new License(); + petClinicLicense.setName("Apache 2.0"); + petClinicLicense.setUrl("http://www.apache.org/licenses/LICENSE-2.0"); + petClinicLicense.setExtensions(Collections.emptyMap()); + return petClinicLicense; + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/mapper/OwnerMapper.java b/src/main/java/org/springframework/samples/petclinic/mapper/OwnerMapper.java new file mode 100644 index 00000000..04e679c2 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/mapper/OwnerMapper.java @@ -0,0 +1,26 @@ +package org.springframework.samples.petclinic.mapper; + +import org.mapstruct.Mapper; +import org.springframework.samples.petclinic.rest.dto.OwnerDto; +import org.springframework.samples.petclinic.model.Owner; +import org.springframework.samples.petclinic.rest.dto.OwnerFieldsDto; + +import java.util.Collection; +import java.util.List; + +/** + * Maps Owner & OwnerDto using Mapstruct + */ +@Mapper(uses = PetMapper.class) +public interface OwnerMapper { + + OwnerDto toOwnerDto(Owner owner); + + Owner toOwner(OwnerDto ownerDto); + + Owner toOwner(OwnerFieldsDto ownerDto); + + List toOwnerDtoCollection(Collection ownerCollection); + + Collection toOwners(Collection ownerDtos); +} diff --git a/src/main/java/org/springframework/samples/petclinic/mapper/PetMapper.java b/src/main/java/org/springframework/samples/petclinic/mapper/PetMapper.java new file mode 100644 index 00000000..1a20bf4a --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/mapper/PetMapper.java @@ -0,0 +1,35 @@ +package org.springframework.samples.petclinic.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.springframework.samples.petclinic.rest.dto.PetDto; +import org.springframework.samples.petclinic.rest.dto.PetFieldsDto; +import org.springframework.samples.petclinic.rest.dto.PetTypeDto; +import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.model.PetType; + +import java.util.Collection; + +/** + * Map Pet & PetDto using mapstruct + */ +@Mapper +public interface PetMapper { + + @Mapping(source = "owner.id", target = "ownerId") + PetDto toPetDto(Pet pet); + + Collection toPetsDto(Collection pets); + + Collection toPets(Collection pets); + + Pet toPet(PetDto petDto); + + Pet toPet(PetFieldsDto petFieldsDto); + + PetTypeDto toPetTypeDto(PetType petType); + + PetType toPetType(PetTypeDto petTypeDto); + + Collection toPetTypeDtos(Collection petTypes); +} diff --git a/src/main/java/org/springframework/samples/petclinic/mapper/PetTypeMapper.java b/src/main/java/org/springframework/samples/petclinic/mapper/PetTypeMapper.java new file mode 100644 index 00000000..486e5cba --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/mapper/PetTypeMapper.java @@ -0,0 +1,24 @@ +package org.springframework.samples.petclinic.mapper; + +import org.mapstruct.Mapper; +import org.springframework.samples.petclinic.rest.dto.PetTypeDto; +import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.rest.dto.PetTypeFieldsDto; + +import java.util.Collection; +import java.util.List; + +/** + * Map PetType & PetTypeDto using mapstruct + */ +@Mapper +public interface PetTypeMapper { + + PetType toPetType(PetTypeDto petTypeDto); + + PetType toPetType(PetTypeFieldsDto petTypeFieldsDto); + + PetTypeDto toPetTypeDto(PetType petType); + + List toPetTypeDtos(Collection petTypes); +} diff --git a/src/main/java/org/springframework/samples/petclinic/mapper/SpecialtyMapper.java b/src/main/java/org/springframework/samples/petclinic/mapper/SpecialtyMapper.java new file mode 100644 index 00000000..c89334dc --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/mapper/SpecialtyMapper.java @@ -0,0 +1,22 @@ +package org.springframework.samples.petclinic.mapper; + +import org.mapstruct.Mapper; +import org.springframework.samples.petclinic.rest.dto.SpecialtyDto; +import org.springframework.samples.petclinic.model.Specialty; + +import java.util.Collection; + +/** + * Map Specialty & SpecialtyDto using mapstruct + */ +@Mapper +public interface SpecialtyMapper { + Specialty toSpecialty(SpecialtyDto specialtyDto); + + SpecialtyDto toSpecialtyDto(Specialty specialty); + + Collection toSpecialtyDtos(Collection specialties); + + Collection toSpecialtys(Collection specialties); + +} diff --git a/src/main/java/org/springframework/samples/petclinic/mapper/UserMapper.java b/src/main/java/org/springframework/samples/petclinic/mapper/UserMapper.java new file mode 100644 index 00000000..718e5410 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/mapper/UserMapper.java @@ -0,0 +1,28 @@ +package org.springframework.samples.petclinic.mapper; + +import org.mapstruct.Mapper; +import org.springframework.samples.petclinic.rest.dto.RoleDto; +import org.springframework.samples.petclinic.rest.dto.UserDto; +import org.springframework.samples.petclinic.model.Role; +import org.springframework.samples.petclinic.model.User; + +import java.util.Collection; + +/** + * Map User/Role & UserDto/RoleDto using mapstruct + */ +@Mapper +public interface UserMapper { + Role toRole(RoleDto roleDto); + + RoleDto toRoleDto(Role role); + + Collection toRoleDtos(Collection roles); + + User toUser(UserDto userDto); + + UserDto toUserDto(User user); + + Collection toRoles(Collection roleDtos); + +} diff --git a/src/main/java/org/springframework/samples/petclinic/mapper/VetMapper.java b/src/main/java/org/springframework/samples/petclinic/mapper/VetMapper.java new file mode 100644 index 00000000..3c25e514 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/mapper/VetMapper.java @@ -0,0 +1,22 @@ +package org.springframework.samples.petclinic.mapper; + +import org.mapstruct.Mapper; +import org.springframework.samples.petclinic.rest.dto.VetDto; +import org.springframework.samples.petclinic.model.Vet; +import org.springframework.samples.petclinic.rest.dto.VetFieldsDto; + +import java.util.Collection; + +/** + * Map Vet & VetoDto using mapstruct + */ +@Mapper(uses = SpecialtyMapper.class) +public interface VetMapper { + Vet toVet(VetDto vetDto); + + Vet toVet(VetFieldsDto vetFieldsDto); + + VetDto toVetDto(Vet vet); + + Collection toVetDtos(Collection vets); +} diff --git a/src/main/java/org/springframework/samples/petclinic/mapper/VisitMapper.java b/src/main/java/org/springframework/samples/petclinic/mapper/VisitMapper.java new file mode 100644 index 00000000..62767fca --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/mapper/VisitMapper.java @@ -0,0 +1,25 @@ +package org.springframework.samples.petclinic.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.springframework.samples.petclinic.rest.dto.VisitDto; +import org.springframework.samples.petclinic.model.Visit; +import org.springframework.samples.petclinic.rest.dto.VisitFieldsDto; + +import java.util.Collection; + +/** + * Map Visit & VisitDto using mapstruct + */ +@Mapper(uses = PetMapper.class) +public interface VisitMapper { + Visit toVisit(VisitDto visitDto); + + Visit toVisit(VisitFieldsDto visitFieldsDto); + + @Mapping(source = "pet.id", target = "petId") + VisitDto toVisitDto(Visit visit); + + Collection toVisitsDto(Collection visits); + +} diff --git a/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java b/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java index 8b59b78b..80bf7553 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java +++ b/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java @@ -15,12 +15,12 @@ */ package org.springframework.samples.petclinic.model; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.MappedSuperclass; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.MappedSuperclass; -import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonIgnore; /** * Simple JavaBean domain object with an id property. Used as a base class for objects needing this property. @@ -41,8 +41,7 @@ public Integer getId() { public void setId(Integer id) { this.id = id; } - - @JsonProperty("isNew") + @JsonIgnore public boolean isNew() { return this.id == null; } diff --git a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java index d66c97ae..0ae19533 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java +++ b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java @@ -15,8 +15,10 @@ */ package org.springframework.samples.petclinic.model; -import javax.persistence.Column; -import javax.persistence.MappedSuperclass; +import jakarta.persistence.Column; +import jakarta.persistence.MappedSuperclass; + +import jakarta.validation.constraints.NotEmpty; /** @@ -30,6 +32,7 @@ public class NamedEntity extends BaseEntity { @Column(name = "name") + @NotEmpty private String name; public String getName() { diff --git a/src/main/java/org/springframework/samples/petclinic/model/Owner.java b/src/main/java/org/springframework/samples/petclinic/model/Owner.java index 9a09bd77..80c89359 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Owner.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Owner.java @@ -15,24 +15,16 @@ */ package org.springframework.samples.petclinic.model; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.validation.constraints.Digits; - -import org.hibernate.validator.constraints.NotEmpty; import org.springframework.beans.support.MutableSortDefinition; import org.springframework.beans.support.PropertyComparator; import org.springframework.core.style.ToStringCreator; +import jakarta.persistence.*; +import jakarta.validation.constraints.Digits; +import jakarta.validation.constraints.NotEmpty; +import java.util.*; + + /** * Simple JavaBean domain object representing an owner. * @@ -57,7 +49,7 @@ public class Owner extends Person { @Digits(fraction = 0, integer = 10) private String telephone; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner") + @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch = FetchType.EAGER) private Set pets; @@ -102,10 +94,12 @@ public List getPets() { return Collections.unmodifiableList(sortedPets); } + public void setPets(List pets) { + this.pets = new HashSet<>(pets); + } + public void addPet(Pet pet) { - if (pet.isNew()) { - getPetsInternal().add(pet); - } + getPetsInternal().add(pet); pet.setOwner(this); } diff --git a/src/main/java/org/springframework/samples/petclinic/model/Person.java b/src/main/java/org/springframework/samples/petclinic/model/Person.java index adbf997e..6257f2ee 100755 --- a/src/main/java/org/springframework/samples/petclinic/model/Person.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Person.java @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.model; +package org.springframework.samples.petclinic.model; -import javax.persistence.Column; -import javax.persistence.MappedSuperclass; -import javax.validation.constraints.Pattern; +import jakarta.persistence.Column; +import jakarta.persistence.MappedSuperclass; -import org.hibernate.validator.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; /** * Simple JavaBean domain object representing an person. @@ -31,12 +30,10 @@ public class Person extends BaseEntity { @Column(name = "first_name") @NotEmpty - @Pattern(regexp = "[a-z-A-Z]*", message = "First name has invalid characters") protected String firstName; @Column(name = "last_name") @NotEmpty - @Pattern(regexp = "[a-z-A-Z]*", message = "Last name has invalid characters") protected String lastName; public String getFirstName() { diff --git a/src/main/java/org/springframework/samples/petclinic/model/Pet.java b/src/main/java/org/springframework/samples/petclinic/model/Pet.java index 2b318806..f5d3402f 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Pet.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Pet.java @@ -15,28 +15,14 @@ */ package org.springframework.samples.petclinic.model; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -import org.hibernate.annotations.Type; -import org.joda.time.LocalDate; import org.springframework.beans.support.MutableSortDefinition; import org.springframework.beans.support.PropertyComparator; import org.springframework.format.annotation.DateTimeFormat; -import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.persistence.*; +import java.time.LocalDate; +import java.util.*; + /** * Simple business object representing a pet. @@ -49,9 +35,7 @@ @Table(name = "pets") public class Pet extends NamedEntity { - @Column(name = "birth_date") - @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate") - @DateTimeFormat(pattern = "yyyy/MM/dd") + @Column(name = "birth_date", columnDefinition = "DATE") private LocalDate birthDate; @ManyToOne @@ -60,7 +44,6 @@ public class Pet extends NamedEntity { @ManyToOne @JoinColumn(name = "owner_id") - @JsonIgnore private Owner owner; @OneToMany(cascade = CascadeType.ALL, mappedBy = "pet", fetch = FetchType.EAGER) @@ -86,7 +69,7 @@ public Owner getOwner() { return this.owner; } - protected void setOwner(Owner owner) { + public void setOwner(Owner owner) { this.owner = owner; } @@ -107,13 +90,13 @@ public List getVisits() { return Collections.unmodifiableList(sortedVisits); } + public void setVisits(List visits) { + this.visits = new HashSet<>(visits); + } + public void addVisit(Visit visit) { getVisitsInternal().add(visit); visit.setPet(this); } - - - - } diff --git a/src/main/java/org/springframework/samples/petclinic/model/PetType.java b/src/main/java/org/springframework/samples/petclinic/model/PetType.java index f60a5cd2..beecdec0 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/PetType.java +++ b/src/main/java/org/springframework/samples/petclinic/model/PetType.java @@ -15,8 +15,8 @@ */ package org.springframework.samples.petclinic.model; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; /** * @author Juergen Hoeller diff --git a/src/main/java/org/springframework/samples/petclinic/model/Role.java b/src/main/java/org/springframework/samples/petclinic/model/Role.java new file mode 100644 index 00000000..da35c8e2 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/model/Role.java @@ -0,0 +1,39 @@ +package org.springframework.samples.petclinic.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +@Entity +@Table(name = "roles" ,uniqueConstraints = @UniqueConstraint(columnNames = {"username", "role"})) +public class Role extends BaseEntity { + + @ManyToOne + @JoinColumn(name = "username") + @JsonIgnore + private User user; + + @Column( name = "role") + private String name; + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/model/Specialty.java b/src/main/java/org/springframework/samples/petclinic/model/Specialty.java index 6ea209cd..8eefd313 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Specialty.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Specialty.java @@ -15,8 +15,8 @@ */ package org.springframework.samples.petclinic.model; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; /** * Models a {@link Vet Vet's} specialty (for example, dentistry). diff --git a/src/main/java/org/springframework/samples/petclinic/model/User.java b/src/main/java/org/springframework/samples/petclinic/model/User.java new file mode 100644 index 00000000..62d412fa --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/model/User.java @@ -0,0 +1,74 @@ +package org.springframework.samples.petclinic.model; + +import java.util.HashSet; +import java.util.Set; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +@Entity +@Table(name = "users") +public class User { + + @Id + @Column(name = "username") + private String username; + + @Column(name = "password") + private String password; + + @Column(name = "enabled") + private Boolean enabled; + + @OneToMany(cascade = CascadeType.ALL, mappedBy = "user", fetch = FetchType.EAGER) + private Set roles; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public Set getRoles() { + return roles; + } + + public void setRoles(Set roles) { + this.roles = roles; + } + + @JsonIgnore + public void addRole(String roleName) { + if(this.roles == null) { + this.roles = new HashSet<>(); + } + Role role = new Role(); + role.setName(roleName); + this.roles.add(role); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/model/Vet.java b/src/main/java/org/springframework/samples/petclinic/model/Vet.java index 67554e12..3add8c87 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Vet.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Vet.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,24 +15,13 @@ */ package org.springframework.samples.petclinic.model; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.Table; -import javax.xml.bind.annotation.XmlElement; - +import com.fasterxml.jackson.annotation.JsonIgnore; import org.springframework.beans.support.MutableSortDefinition; import org.springframework.beans.support.PropertyComparator; -import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.persistence.*; +import jakarta.xml.bind.annotation.XmlElement; +import java.util.*; /** * Simple JavaBean domain object representing a veterinarian. @@ -51,6 +40,7 @@ public class Vet extends Person { inverseJoinColumns = @JoinColumn(name = "specialty_id")) private Set specialties; + @JsonIgnore protected Set getSpecialtiesInternal() { if (this.specialties == null) { this.specialties = new HashSet<>(); @@ -69,6 +59,10 @@ public List getSpecialties() { return Collections.unmodifiableList(sortedSpecs); } + public void setSpecialties(List specialties) { + this.specialties = new HashSet<>(specialties); + } + @JsonIgnore public int getNrOfSpecialties() { return getSpecialtiesInternal().size(); @@ -78,4 +72,8 @@ public void addSpecialty(Specialty specialty) { getSpecialtiesInternal().add(specialty); } + public void clearSpecialties() { + getSpecialtiesInternal().clear(); + } + } diff --git a/src/main/java/org/springframework/samples/petclinic/model/Visit.java b/src/main/java/org/springframework/samples/petclinic/model/Visit.java index 2141c79c..f98cb458 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Visit.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Visit.java @@ -15,19 +15,11 @@ */ package org.springframework.samples.petclinic.model; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; - -import org.hibernate.annotations.Type; -import org.hibernate.validator.constraints.NotEmpty; -import org.joda.time.LocalDate; import org.springframework.format.annotation.DateTimeFormat; -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotEmpty; +import java.time.LocalDate; /** * Simple JavaBean domain object representing a visit. @@ -41,12 +33,8 @@ public class Visit extends BaseEntity { /** * Holds value of property date. */ - @Column(name = "visit_date") - @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate") - @DateTimeFormat(pattern = "yyyy/MM/dd") - @JsonFormat(pattern = "yyyy/MM/dd") + @Column(name = "visit_date", columnDefinition = "DATE") private LocalDate date; - /** * Holds value of property description. @@ -60,7 +48,6 @@ public class Visit extends BaseEntity { */ @ManyToOne @JoinColumn(name = "pet_id") - @JsonIgnore private Pet pet; @@ -68,7 +55,7 @@ public class Visit extends BaseEntity { * Creates a new instance of Visit for the current date */ public Visit() { - this.date = new LocalDate(); + this.date = LocalDate.now(); } diff --git a/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java index 841d0bcd..feefee86 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,6 @@ import java.util.Collection; import org.springframework.dao.DataAccessException; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.Repository; -import org.springframework.data.repository.query.Param; import org.springframework.samples.petclinic.model.BaseEntity; import org.springframework.samples.petclinic.model.Owner; @@ -32,32 +29,53 @@ * @author Juergen Hoeller * @author Sam Brannen * @author Michael Isvy + * @author Vitaliy Fedoriv */ -public interface OwnerRepository extends Repository { +public interface OwnerRepository { /** - * Retrieve {@link Owner}s from the data store by last name, returning all owners - * whose last name starts with the given name. + * Retrieve Owners from the data store by last name, returning all owners whose last name starts + * with the given name. + * * @param lastName Value to search for - * @return a Collection of matching {@link Owner}s (or an empty Collection if none + * @return a Collection of matching Owners (or an empty Collection if none * found) */ - @Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%") - Collection findByLastName(@Param("lastName") String lastName); + Collection findByLastName(String lastName) throws DataAccessException; /** - * Retrieve an {@link Owner} from the data store by id. + * Retrieve an Owner from the data store by id. + * * @param id the id to search for - * @return the {@link Owner} if found + * @return the Owner if found + * @throws org.springframework.dao.DataRetrievalFailureException if not found */ - @Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id") - Owner findById(@Param("id") int id); + Owner findById(int id) throws DataAccessException; + + /** + * Save an Owner to the data store, either inserting or updating it. + * + * @param owner the Owner to save + * @see BaseEntity#isNew + */ + void save(Owner owner) throws DataAccessException; + + /** + * Retrieve Owners from the data store, returning all owners + * + * @return a Collection of Owners (or an empty Collection if none + * found) + */ + Collection findAll() throws DataAccessException; + /** - * Save an {@link Owner} to the data store, either inserting or updating it. - * @param owner the {@link Owner} to save + * Delete an Owner to the data store by Owner. + * + * @param owner the Owner to delete + * */ - void save(Owner owner); + void delete(Owner owner) throws DataAccessException; } diff --git a/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java index 58e73d7f..f5314905 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,11 +15,10 @@ */ package org.springframework.samples.petclinic.repository; +import java.util.Collection; import java.util.List; import org.springframework.dao.DataAccessException; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.Repository; import org.springframework.samples.petclinic.model.BaseEntity; import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.model.PetType; @@ -32,28 +31,48 @@ * @author Juergen Hoeller * @author Sam Brannen * @author Michael Isvy + * @author Vitaliy Fedoriv */ -public interface PetRepository extends Repository { +public interface PetRepository { /** - * Retrieve all {@link PetType}s from the data store. - * @return a Collection of {@link PetType}s. + * Retrieve all PetTypes from the data store. + * + * @return a Collection of PetTypes */ - @Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name") - List findPetTypes(); + List findPetTypes() throws DataAccessException; /** - * Retrieve a {@link Pet} from the data store by id. + * Retrieve a Pet from the data store by id. + * * @param id the id to search for - * @return the {@link Pet} if found + * @return the Pet if found + * @throws org.springframework.dao.DataRetrievalFailureException if not found */ - Pet findById(int id); + Pet findById(int id) throws DataAccessException; /** - * Save a {@link Pet} to the data store, either inserting or updating it. - * @param pet the {@link Pet} to save + * Save a Pet to the data store, either inserting or updating it. + * + * @param pet the Pet to save + * @see BaseEntity#isNew */ - void save(Pet pet); + void save(Pet pet) throws DataAccessException; + + /** + * Retrieve Pets from the data store, returning all owners + * + * @return a Collection of Pets (or an empty Collection if none + * found) + */ + Collection findAll() throws DataAccessException; -} + /** + * Delete an Pet to the data store by Pet. + * + * @param pet the Pet to delete + * + */ + void delete(Pet pet) throws DataAccessException; +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/PetTypeRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/PetTypeRepository.java new file mode 100644 index 00000000..d1c05e92 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/PetTypeRepository.java @@ -0,0 +1,41 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.repository; + +import java.util.Collection; + +import org.springframework.dao.DataAccessException; +import org.springframework.samples.petclinic.model.PetType; + +/** + * @author Vitaliy Fedoriv + * + */ + +public interface PetTypeRepository { + + PetType findById(int id) throws DataAccessException; + + PetType findByName(String name) throws DataAccessException; + + Collection findAll() throws DataAccessException; + + void save(PetType petType) throws DataAccessException; + + void delete(PetType petType) throws DataAccessException; + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/SpecialtyRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/SpecialtyRepository.java new file mode 100644 index 00000000..256163ce --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/SpecialtyRepository.java @@ -0,0 +1,43 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.repository; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import org.springframework.dao.DataAccessException; +import org.springframework.samples.petclinic.model.Specialty; + +/** + * @author Vitaliy Fedoriv + * + */ + +public interface SpecialtyRepository { + + Specialty findById(int id) throws DataAccessException; + + List findSpecialtiesByNameIn(Set names); + + Collection findAll() throws DataAccessException; + + void save(Specialty specialty) throws DataAccessException; + + void delete(Specialty specialty) throws DataAccessException; + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/UserRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/UserRepository.java new file mode 100644 index 00000000..3e9b45ba --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/UserRepository.java @@ -0,0 +1,9 @@ +package org.springframework.samples.petclinic.repository; + +import org.springframework.dao.DataAccessException; +import org.springframework.samples.petclinic.model.User; + +public interface UserRepository { + + void save(User user) throws DataAccessException; +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java index aabdfd65..0f3a3d1f 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ import java.util.Collection; import org.springframework.dao.DataAccessException; -import org.springframework.data.repository.Repository; import org.springframework.samples.petclinic.model.Vet; /** @@ -29,8 +28,9 @@ * @author Juergen Hoeller * @author Sam Brannen * @author Michael Isvy + * @author Vitaliy Fedoriv */ -public interface VetRepository extends Repository { +public interface VetRepository { /** * Retrieve all Vets from the data store. @@ -38,6 +38,12 @@ public interface VetRepository extends Repository { * @return a Collection of Vets */ Collection findAll() throws DataAccessException; + + Vet findById(int id) throws DataAccessException; + + void save(Vet vet) throws DataAccessException; + + void delete(Vet vet) throws DataAccessException; } diff --git a/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java index e734f327..fac5659f 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,10 @@ */ package org.springframework.samples.petclinic.repository; +import java.util.Collection; import java.util.List; import org.springframework.dao.DataAccessException; -import org.springframework.data.repository.Repository; import org.springframework.samples.petclinic.model.BaseEntity; import org.springframework.samples.petclinic.model.Visit; @@ -30,8 +30,9 @@ * @author Juergen Hoeller * @author Sam Brannen * @author Michael Isvy + * @author Vitaliy Fedoriv */ -public interface VisitRepository extends Repository { +public interface VisitRepository { /** * Save a Visit to the data store, either inserting or updating it. @@ -42,5 +43,11 @@ public interface VisitRepository extends Repository { void save(Visit visit) throws DataAccessException; List findByPetId(Integer petId); + + Visit findById(int id) throws DataAccessException; + + Collection findAll() throws DataAccessException; + + void delete(Visit visit) throws DataAccessException; } diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcOwnerRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcOwnerRepositoryImpl.java new file mode 100644 index 00000000..406286ba --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcOwnerRepositoryImpl.java @@ -0,0 +1,196 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository.jdbc; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.simple.SimpleJdbcInsert; +import org.springframework.orm.ObjectRetrievalFailureException; +import org.springframework.samples.petclinic.model.Owner; +import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.model.Visit; +import org.springframework.samples.petclinic.repository.OwnerRepository; +import org.springframework.samples.petclinic.util.EntityUtils; +import org.springframework.stereotype.Repository; + +import javax.sql.DataSource; +import jakarta.transaction.Transactional; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A simple JDBC-based implementation of the {@link OwnerRepository} interface. + * + * @author Ken Krebs + * @author Juergen Hoeller + * @author Rob Harrop + * @author Sam Brannen + * @author Thomas Risberg + * @author Mark Fisher + * @author Antoine Rey + * @author Vitaliy Fedoriv + */ +@Repository +@Profile("jdbc") +public class JdbcOwnerRepositoryImpl implements OwnerRepository { + + private NamedParameterJdbcTemplate namedParameterJdbcTemplate; + + private SimpleJdbcInsert insertOwner; + + @Autowired + public JdbcOwnerRepositoryImpl(DataSource dataSource) { + + this.insertOwner = new SimpleJdbcInsert(dataSource) + .withTableName("owners") + .usingGeneratedKeyColumns("id"); + + this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); + + } + + + /** + * Loads {@link Owner Owners} from the data store by last name, returning all owners whose last name starts with + * the given name; also loads the {@link Pet Pets} and {@link Visit Visits} for the corresponding owners, if not + * already loaded. + */ + @Override + public Collection findByLastName(String lastName) throws DataAccessException { + Map params = new HashMap<>(); + params.put("lastName", lastName + "%"); + List owners = this.namedParameterJdbcTemplate.query( + "SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE last_name like :lastName", + params, + BeanPropertyRowMapper.newInstance(Owner.class) + ); + loadOwnersPetsAndVisits(owners); + return owners; + } + + /** + * Loads the {@link Owner} with the supplied id; also loads the {@link Pet Pets} and {@link Visit Visits} + * for the corresponding owner, if not already loaded. + */ + @Override + public Owner findById(int id) throws DataAccessException { + Owner owner; + try { + Map params = new HashMap<>(); + params.put("id", id); + owner = this.namedParameterJdbcTemplate.queryForObject( + "SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE id= :id", + params, + BeanPropertyRowMapper.newInstance(Owner.class) + ); + } catch (EmptyResultDataAccessException ex) { + throw new ObjectRetrievalFailureException(Owner.class, id); + } + loadPetsAndVisits(owner); + return owner; + } + + public void loadPetsAndVisits(final Owner owner) { + Map params = new HashMap<>(); + params.put("id", owner.getId()); + final List pets = this.namedParameterJdbcTemplate.query( + "SELECT pets.id as pets_id, name, birth_date, type_id, owner_id, visits.id as visit_id, visit_date, description, visits.pet_id as visits_pet_id FROM pets LEFT OUTER JOIN visits ON pets.id = visits.pet_id WHERE owner_id=:id ORDER BY pets.id", + params, + new JdbcPetVisitExtractor() + ); + Collection petTypes = getPetTypes(); + for (JdbcPet pet : pets) { + pet.setType(EntityUtils.getById(petTypes, PetType.class, pet.getTypeId())); + owner.addPet(pet); + } + } + + @Override + public void save(Owner owner) throws DataAccessException { + BeanPropertySqlParameterSource parameterSource = new BeanPropertySqlParameterSource(owner); + if (owner.isNew()) { + Number newKey = this.insertOwner.executeAndReturnKey(parameterSource); + owner.setId(newKey.intValue()); + } else { + this.namedParameterJdbcTemplate.update( + "UPDATE owners SET first_name=:firstName, last_name=:lastName, address=:address, " + + "city=:city, telephone=:telephone WHERE id=:id", + parameterSource); + } + } + + public Collection getPetTypes() throws DataAccessException { + return this.namedParameterJdbcTemplate.query( + "SELECT id, name FROM types ORDER BY name", new HashMap(), + BeanPropertyRowMapper.newInstance(PetType.class)); + } + + /** + * Loads the {@link Pet} and {@link Visit} data for the supplied {@link List} of {@link Owner Owners}. + * + * @param owners the list of owners for whom the pet and visit data should be loaded + * @see #loadPetsAndVisits(Owner) + */ + private void loadOwnersPetsAndVisits(List owners) { + for (Owner owner : owners) { + loadPetsAndVisits(owner); + } + } + + @Override + public Collection findAll() throws DataAccessException { + List owners = this.namedParameterJdbcTemplate.query( + "SELECT id, first_name, last_name, address, city, telephone FROM owners", + new HashMap(), + BeanPropertyRowMapper.newInstance(Owner.class)); + for (Owner owner : owners) { + loadPetsAndVisits(owner); + } + return owners; + } + + @Override + @Transactional + public void delete(Owner owner) throws DataAccessException { + Map owner_params = new HashMap<>(); + owner_params.put("id", owner.getId()); + List pets = owner.getPets(); + // cascade delete pets + for (Pet pet : pets){ + Map pet_params = new HashMap<>(); + pet_params.put("id", pet.getId()); + // cascade delete visits + List visits = pet.getVisits(); + for (Visit visit : visits){ + Map visit_params = new HashMap<>(); + visit_params.put("id", visit.getId()); + this.namedParameterJdbcTemplate.update("DELETE FROM visits WHERE id=:id", visit_params); + } + this.namedParameterJdbcTemplate.update("DELETE FROM pets WHERE id=:id", pet_params); + } + this.namedParameterJdbcTemplate.update("DELETE FROM owners WHERE id=:id", owner_params); + } + + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPet.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPet.java new file mode 100644 index 00000000..05d048d9 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPet.java @@ -0,0 +1,48 @@ +/* + * Copyright 2002-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository.jdbc; + +import org.springframework.samples.petclinic.model.Pet; + +/** + * Subclass of Pet that carries temporary id properties which are only relevant for a JDBC implementation of the + * PetRepository. + * + * @author Juergen Hoeller + */ +public class JdbcPet extends Pet { + + private int typeId; + + private int ownerId; + + public int getTypeId() { + return this.typeId; + } + + public void setTypeId(int typeId) { + this.typeId = typeId; + } + + public int getOwnerId() { + return this.ownerId; + } + + public void setOwnerId(int ownerId) { + this.ownerId = ownerId; + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRepositoryImpl.java new file mode 100644 index 00000000..9911ff5c --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRepositoryImpl.java @@ -0,0 +1,169 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository.jdbc; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.simple.SimpleJdbcInsert; +import org.springframework.orm.ObjectRetrievalFailureException; +import org.springframework.samples.petclinic.model.Owner; +import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.model.Visit; +import org.springframework.samples.petclinic.repository.OwnerRepository; +import org.springframework.samples.petclinic.repository.PetRepository; +import org.springframework.samples.petclinic.repository.VisitRepository; +import org.springframework.samples.petclinic.util.EntityUtils; +import org.springframework.stereotype.Repository; + +/** + * @author Ken Krebs + * @author Juergen Hoeller + * @author Rob Harrop + * @author Sam Brannen + * @author Thomas Risberg + * @author Mark Fisher + * @author Vitaliy Fedoriv + */ +@Repository +@Profile("jdbc") +public class JdbcPetRepositoryImpl implements PetRepository { + + private NamedParameterJdbcTemplate namedParameterJdbcTemplate; + + private SimpleJdbcInsert insertPet; + + private OwnerRepository ownerRepository; + + private VisitRepository visitRepository; + + + @Autowired + public JdbcPetRepositoryImpl(DataSource dataSource, + OwnerRepository ownerRepository, + VisitRepository visitRepository) { + this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); + + this.insertPet = new SimpleJdbcInsert(dataSource) + .withTableName("pets") + .usingGeneratedKeyColumns("id"); + + this.ownerRepository = ownerRepository; + this.visitRepository = visitRepository; + } + + @Override + public List findPetTypes() throws DataAccessException { + Map params = new HashMap<>(); + return this.namedParameterJdbcTemplate.query( + "SELECT id, name FROM types ORDER BY name", + params, + BeanPropertyRowMapper.newInstance(PetType.class)); + } + + @Override + public Pet findById(int id) throws DataAccessException { + Integer ownerId; + try { + Map params = new HashMap<>(); + params.put("id", id); + ownerId = this.namedParameterJdbcTemplate.queryForObject("SELECT owner_id FROM pets WHERE id=:id", params, Integer.class); + } catch (EmptyResultDataAccessException ex) { + throw new ObjectRetrievalFailureException(Pet.class, id); + } + Owner owner = this.ownerRepository.findById(ownerId); + return EntityUtils.getById(owner.getPets(), Pet.class, id); + } + + @Override + public void save(Pet pet) throws DataAccessException { + if (pet.isNew()) { + Number newKey = this.insertPet.executeAndReturnKey( + createPetParameterSource(pet)); + pet.setId(newKey.intValue()); + } else { + this.namedParameterJdbcTemplate.update( + "UPDATE pets SET name=:name, birth_date=:birth_date, type_id=:type_id, " + + "owner_id=:owner_id WHERE id=:id", + createPetParameterSource(pet)); + } + } + + /** + * Creates a {@link MapSqlParameterSource} based on data values from the supplied {@link Pet} instance. + */ + private MapSqlParameterSource createPetParameterSource(Pet pet) { + return new MapSqlParameterSource() + .addValue("id", pet.getId()) + .addValue("name", pet.getName()) + .addValue("birth_date", pet.getBirthDate()) + .addValue("type_id", pet.getType().getId()) + .addValue("owner_id", pet.getOwner().getId()); + } + + @Override + public Collection findAll() throws DataAccessException { + Map params = new HashMap<>(); + Collection pets = new ArrayList(); + Collection jdbcPets = new ArrayList(); + jdbcPets = this.namedParameterJdbcTemplate + .query("SELECT pets.id as pets_id, name, birth_date, type_id, owner_id FROM pets", + params, + new JdbcPetRowMapper()); + Collection petTypes = this.namedParameterJdbcTemplate.query("SELECT id, name FROM types ORDER BY name", + new HashMap(), BeanPropertyRowMapper.newInstance(PetType.class)); + Collection owners = this.namedParameterJdbcTemplate.query( + "SELECT id, first_name, last_name, address, city, telephone FROM owners ORDER BY last_name", + new HashMap(), + BeanPropertyRowMapper.newInstance(Owner.class)); + for (JdbcPet jdbcPet : jdbcPets) { + jdbcPet.setType(EntityUtils.getById(petTypes, PetType.class, jdbcPet.getTypeId())); + jdbcPet.setOwner(EntityUtils.getById(owners, Owner.class, jdbcPet.getOwnerId())); + // TODO add visits + pets.add(jdbcPet); + } + return pets; + } + + @Override + public void delete(Pet pet) throws DataAccessException { + Map pet_params = new HashMap<>(); + pet_params.put("id", pet.getId()); + List visits = pet.getVisits(); + // cascade delete visits + for (Visit visit : visits) { + Map visit_params = new HashMap<>(); + visit_params.put("id", visit.getId()); + this.namedParameterJdbcTemplate.update("DELETE FROM visits WHERE id=:id", visit_params); + } + this.namedParameterJdbcTemplate.update("DELETE FROM pets WHERE id=:id", pet_params); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRowMapper.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRowMapper.java new file mode 100644 index 00000000..03052632 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRowMapper.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository.jdbc; + +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.LocalDate; +import java.util.Date; + +/** + * {@link RowMapper} implementation mapping data from a {@link ResultSet} to the corresponding properties + * of the {@link JdbcPet} class. + */ +public class JdbcPetRowMapper implements RowMapper { + + @Override + public JdbcPet mapRow(ResultSet rs, int rownum) throws SQLException { + JdbcPet pet = new JdbcPet(); + pet.setId(rs.getInt("pets_id")); + pet.setName(rs.getString("name")); + pet.setBirthDate(rs.getObject("birth_date", LocalDate.class)); + pet.setTypeId(rs.getInt("type_id")); + pet.setOwnerId(rs.getInt("owner_id")); + return pet; + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetTypeRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetTypeRepositoryImpl.java new file mode 100644 index 00000000..1835cb71 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetTypeRepositoryImpl.java @@ -0,0 +1,145 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.repository.jdbc; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.simple.SimpleJdbcInsert; +import org.springframework.orm.ObjectRetrievalFailureException; +import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.model.Visit; +import org.springframework.samples.petclinic.repository.PetTypeRepository; +import org.springframework.stereotype.Repository; + +/** + * @author Vitaliy Fedoriv + * + */ + +@Repository +@Profile("jdbc") +public class JdbcPetTypeRepositoryImpl implements PetTypeRepository { + + private NamedParameterJdbcTemplate namedParameterJdbcTemplate; + + private SimpleJdbcInsert insertPetType; + + @Autowired + public JdbcPetTypeRepositoryImpl(DataSource dataSource) { + this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); + this.insertPetType = new SimpleJdbcInsert(dataSource) + .withTableName("types") + .usingGeneratedKeyColumns("id"); + } + + @Override + public PetType findById(int id) { + PetType petType; + try { + Map params = new HashMap<>(); + params.put("id", id); + petType = this.namedParameterJdbcTemplate.queryForObject( + "SELECT id, name FROM types WHERE id= :id", + params, + BeanPropertyRowMapper.newInstance(PetType.class)); + } catch (EmptyResultDataAccessException ex) { + throw new ObjectRetrievalFailureException(PetType.class, id); + } + return petType; + } + + @Override + public PetType findByName(String name) throws DataAccessException { + PetType petType; + try { + Map params = new HashMap<>(); + params.put("name", name); + petType = this.namedParameterJdbcTemplate.queryForObject( + "SELECT id, name FROM types WHERE name= :name", + params, + BeanPropertyRowMapper.newInstance(PetType.class)); + } catch (EmptyResultDataAccessException ex) { + throw new ObjectRetrievalFailureException(PetType.class, name); + } + return petType; + } + + @Override + public Collection findAll() throws DataAccessException { + Map params = new HashMap<>(); + return this.namedParameterJdbcTemplate.query( + "SELECT id, name FROM types", + params, + BeanPropertyRowMapper.newInstance(PetType.class)); + } + + @Override + public void save(PetType petType) throws DataAccessException { + BeanPropertySqlParameterSource parameterSource = new BeanPropertySqlParameterSource(petType); + if (petType.isNew()) { + Number newKey = this.insertPetType.executeAndReturnKey(parameterSource); + petType.setId(newKey.intValue()); + } else { + this.namedParameterJdbcTemplate.update("UPDATE types SET name=:name WHERE id=:id", + parameterSource); + } + } + + @Override + public void delete(PetType petType) throws DataAccessException { + Map pettype_params = new HashMap<>(); + pettype_params.put("id", petType.getId()); + List pets = new ArrayList(); + pets = this.namedParameterJdbcTemplate. + query("SELECT pets.id, name, birth_date, type_id, owner_id FROM pets WHERE type_id=:id", + pettype_params, + BeanPropertyRowMapper.newInstance(Pet.class)); + // cascade delete pets + for (Pet pet : pets){ + Map pet_params = new HashMap<>(); + pet_params.put("id", pet.getId()); + List visits = new ArrayList(); + visits = this.namedParameterJdbcTemplate.query( + "SELECT id, pet_id, visit_date, description FROM visits WHERE pet_id = :id", + pet_params, + BeanPropertyRowMapper.newInstance(Visit.class)); + // cascade delete visits + for (Visit visit : visits){ + Map visit_params = new HashMap<>(); + visit_params.put("id", visit.getId()); + this.namedParameterJdbcTemplate.update("DELETE FROM visits WHERE id=:id", visit_params); + } + this.namedParameterJdbcTemplate.update("DELETE FROM pets WHERE id=:id", pet_params); + } + this.namedParameterJdbcTemplate.update("DELETE FROM types WHERE id=:id", pettype_params); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetVisitExtractor.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetVisitExtractor.java new file mode 100644 index 00000000..f6483e35 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetVisitExtractor.java @@ -0,0 +1,54 @@ +/* + * Copyright 2002-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository.jdbc; + +import org.springframework.data.jdbc.core.OneToManyResultSetExtractor; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.samples.petclinic.model.Visit; + +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * {@link ResultSetExtractor} implementation by using the + * {@link OneToManyResultSetExtractor} of Spring Data Core JDBC Extensions. + */ +public class JdbcPetVisitExtractor extends + OneToManyResultSetExtractor { + + public JdbcPetVisitExtractor() { + super(new JdbcPetRowMapper(), new JdbcVisitRowMapper()); + } + + @Override + protected Integer mapPrimaryKey(ResultSet rs) throws SQLException { + return rs.getInt("pets_id"); + } + + @Override + protected Integer mapForeignKey(ResultSet rs) throws SQLException { + if (rs.getObject("visits_pet_id") == null) { + return null; + } else { + return rs.getInt("visits_pet_id"); + } + } + + @Override + protected void addChild(JdbcPet root, Visit child) { + root.addVisit(child); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcSpecialtyRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcSpecialtyRepositoryImpl.java new file mode 100644 index 00000000..3f125d92 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcSpecialtyRepositoryImpl.java @@ -0,0 +1,121 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.repository.jdbc; + +import java.util.*; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.simple.SimpleJdbcInsert; +import org.springframework.orm.ObjectRetrievalFailureException; +import org.springframework.samples.petclinic.model.Specialty; +import org.springframework.samples.petclinic.repository.SpecialtyRepository; +import org.springframework.stereotype.Repository; + +/** + * @author Vitaliy Fedoriv + * + */ + +@Repository +@Profile("jdbc") +public class JdbcSpecialtyRepositoryImpl implements SpecialtyRepository { + + private NamedParameterJdbcTemplate namedParameterJdbcTemplate; + + private SimpleJdbcInsert insertSpecialty; + + @Autowired + public JdbcSpecialtyRepositoryImpl(DataSource dataSource) { + this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); + this.insertSpecialty = new SimpleJdbcInsert(dataSource) + .withTableName("specialties") + .usingGeneratedKeyColumns("id"); + } + + @Override + public Specialty findById(int id) { + Specialty specialty; + try { + Map params = new HashMap<>(); + params.put("id", id); + specialty = this.namedParameterJdbcTemplate.queryForObject( + "SELECT id, name FROM specialties WHERE id= :id", + params, + BeanPropertyRowMapper.newInstance(Specialty.class)); + } catch (EmptyResultDataAccessException ex) { + throw new ObjectRetrievalFailureException(Specialty.class, id); + } + return specialty; + } + + @Override + public List findSpecialtiesByNameIn(Set names) { + List specialties; + try{ + String sql = "SELECT id, name FROM specialties WHERE specialties.name IN (:names)"; + Map params = new HashMap<>(); + params.put("names", names); + specialties = this.namedParameterJdbcTemplate.query( + sql, + params, + new BeanPropertyRowMapper<>(Specialty.class)); + } catch (EmptyResultDataAccessException ex){ + throw new ObjectRetrievalFailureException(Specialty.class, names); + } + + return specialties; + } + + @Override + public Collection findAll() throws DataAccessException { + Map params = new HashMap<>(); + return this.namedParameterJdbcTemplate.query( + "SELECT id, name FROM specialties", + params, + BeanPropertyRowMapper.newInstance(Specialty.class)); + } + + @Override + public void save(Specialty specialty) throws DataAccessException { + BeanPropertySqlParameterSource parameterSource = new BeanPropertySqlParameterSource(specialty); + if (specialty.isNew()) { + Number newKey = this.insertSpecialty.executeAndReturnKey(parameterSource); + specialty.setId(newKey.intValue()); + } else { + this.namedParameterJdbcTemplate.update("UPDATE specialties SET name=:name WHERE id=:id", + parameterSource); + } + + } + + @Override + public void delete(Specialty specialty) throws DataAccessException { + Map params = new HashMap<>(); + params.put("id", specialty.getId()); + this.namedParameterJdbcTemplate.update("DELETE FROM vet_specialties WHERE specialty_id=:id", params); + this.namedParameterJdbcTemplate.update("DELETE FROM specialties WHERE id=:id", params); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcUserRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcUserRepositoryImpl.java new file mode 100644 index 00000000..7fc51ecb --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcUserRepositoryImpl.java @@ -0,0 +1,68 @@ +package org.springframework.samples.petclinic.repository.jdbc; + +import java.util.HashMap; +import java.util.Map; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.simple.SimpleJdbcInsert; +import org.springframework.samples.petclinic.model.Role; +import org.springframework.samples.petclinic.model.User; +import org.springframework.samples.petclinic.repository.UserRepository; +import org.springframework.stereotype.Repository; + +@Repository +@Profile("jdbc") +public class JdbcUserRepositoryImpl implements UserRepository { + + private NamedParameterJdbcTemplate namedParameterJdbcTemplate; + private SimpleJdbcInsert insertUser; + + @Autowired + public JdbcUserRepositoryImpl(DataSource dataSource) { + this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); + this.insertUser = new SimpleJdbcInsert(dataSource).withTableName("users"); + } + + @Override + public void save(User user) throws DataAccessException { + + BeanPropertySqlParameterSource parameterSource = new BeanPropertySqlParameterSource(user); + + try { + getByUsername(user.getUsername()); + this.namedParameterJdbcTemplate.update("UPDATE users SET password=:password, enabled=:enabled WHERE username=:username", parameterSource); + } catch (EmptyResultDataAccessException e) { + this.insertUser.execute(parameterSource); + } finally { + updateUserRoles(user); + } + } + + private User getByUsername(String username) { + + Map params = new HashMap<>(); + params.put("username", username); + return this.namedParameterJdbcTemplate.queryForObject("SELECT * FROM users WHERE username=:username", + params, BeanPropertyRowMapper.newInstance(User.class)); + } + + private void updateUserRoles(User user) { + Map params = new HashMap<>(); + params.put("username", user.getUsername()); + this.namedParameterJdbcTemplate.update("DELETE FROM roles WHERE username=:username", params); + for (Role role : user.getRoles()) { + params.put("role", role.getName()); + if (role.getName() != null) { + this.namedParameterJdbcTemplate.update("INSERT INTO roles(username, role) VALUES (:username, :role)", params); + } + } + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVetRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVetRepositoryImpl.java new file mode 100644 index 00000000..c5bc285e --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVetRepositoryImpl.java @@ -0,0 +1,174 @@ +/* + * Copyright 2002-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository.jdbc; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.simple.SimpleJdbcInsert; +import org.springframework.orm.ObjectRetrievalFailureException; +import org.springframework.samples.petclinic.model.Specialty; +import org.springframework.samples.petclinic.model.Vet; +import org.springframework.samples.petclinic.repository.VetRepository; +import org.springframework.samples.petclinic.util.EntityUtils; +import org.springframework.stereotype.Repository; + +/** + * A simple JDBC-based implementation of the {@link VetRepository} interface. + * + * @author Ken Krebs + * @author Juergen Hoeller + * @author Rob Harrop + * @author Sam Brannen + * @author Thomas Risberg + * @author Mark Fisher + * @author Michael Isvy + * @author Vitaliy Fedoriv + */ +@Repository +@Profile("jdbc") +public class JdbcVetRepositoryImpl implements VetRepository { + + private JdbcTemplate jdbcTemplate; + private NamedParameterJdbcTemplate namedParameterJdbcTemplate; + private SimpleJdbcInsert insertVet; + + @Autowired + public JdbcVetRepositoryImpl(DataSource dataSource, JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + this.insertVet = new SimpleJdbcInsert(dataSource).withTableName("vets").usingGeneratedKeyColumns("id"); + this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); + } + + /** + * Refresh the cache of Vets that the ClinicService is holding. + */ + @Override + public Collection findAll() throws DataAccessException { + List vets = new ArrayList<>(); + // Retrieve the list of all vets. + vets.addAll(this.jdbcTemplate.query( + "SELECT id, first_name, last_name FROM vets ORDER BY last_name,first_name", + BeanPropertyRowMapper.newInstance(Vet.class))); + + // Retrieve the list of all possible specialties. + final List specialties = this.jdbcTemplate.query( + "SELECT id, name FROM specialties", + BeanPropertyRowMapper.newInstance(Specialty.class)); + + // Build each vet's list of specialties. + for (Vet vet : vets) { + final List vetSpecialtiesIds = this.jdbcTemplate.query( + "SELECT specialty_id FROM vet_specialties WHERE vet_id=?", + new BeanPropertyRowMapper() { + @Override + public Integer mapRow(ResultSet rs, int row) throws SQLException { + return rs.getInt(1); + } + }, + vet.getId()); + for (int specialtyId : vetSpecialtiesIds) { + Specialty specialty = EntityUtils.getById(specialties, Specialty.class, specialtyId); + vet.addSpecialty(specialty); + } + } + return vets; + } + + @Override + public Vet findById(int id) throws DataAccessException { + Vet vet; + try { + Map vet_params = new HashMap<>(); + vet_params.put("id", id); + vet = this.namedParameterJdbcTemplate.queryForObject( + "SELECT id, first_name, last_name FROM vets WHERE id= :id", + vet_params, + BeanPropertyRowMapper.newInstance(Vet.class)); + + final List specialties = this.namedParameterJdbcTemplate.query( + "SELECT id, name FROM specialties", vet_params, BeanPropertyRowMapper.newInstance(Specialty.class)); + + final List vetSpecialtiesIds = this.namedParameterJdbcTemplate.query( + "SELECT specialty_id FROM vet_specialties WHERE vet_id=:id", + vet_params, + new BeanPropertyRowMapper() { + @Override + public Integer mapRow(ResultSet rs, int row) throws SQLException { + return rs.getInt(1); + } + }); + for (int specialtyId : vetSpecialtiesIds) { + Specialty specialty = EntityUtils.getById(specialties, Specialty.class, specialtyId); + vet.addSpecialty(specialty); + } + + } catch (EmptyResultDataAccessException ex) { + throw new ObjectRetrievalFailureException(Vet.class, id); + } + return vet; + } + + @Override + public void save(Vet vet) throws DataAccessException { + BeanPropertySqlParameterSource parameterSource = new BeanPropertySqlParameterSource(vet); + if (vet.isNew()) { + Number newKey = this.insertVet.executeAndReturnKey(parameterSource); + vet.setId(newKey.intValue()); + updateVetSpecialties(vet); + } else { + this.namedParameterJdbcTemplate + .update("UPDATE vets SET first_name=:firstName, last_name=:lastName WHERE id=:id", parameterSource); + updateVetSpecialties(vet); + } + } + + @Override + public void delete(Vet vet) throws DataAccessException { + Map params = new HashMap<>(); + params.put("id", vet.getId()); + this.namedParameterJdbcTemplate.update("DELETE FROM vet_specialties WHERE vet_id=:id", params); + this.namedParameterJdbcTemplate.update("DELETE FROM vets WHERE id=:id", params); + } + + private void updateVetSpecialties(Vet vet) throws DataAccessException { + Map params = new HashMap<>(); + params.put("id", vet.getId()); + this.namedParameterJdbcTemplate.update("DELETE FROM vet_specialties WHERE vet_id=:id", params); + for (Specialty spec : vet.getSpecialties()) { + params.put("spec_id", spec.getId()); + if(!(spec.getId() == null)) { + this.namedParameterJdbcTemplate.update("INSERT INTO vet_specialties VALUES (:id, :spec_id)", params); + } + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVisitRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVisitRepositoryImpl.java new file mode 100644 index 00000000..b8e6ea91 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVisitRepositoryImpl.java @@ -0,0 +1,177 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository.jdbc; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.simple.SimpleJdbcInsert; +import org.springframework.orm.ObjectRetrievalFailureException; +import org.springframework.samples.petclinic.model.Owner; +import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.model.Visit; +import org.springframework.samples.petclinic.repository.VisitRepository; +import org.springframework.stereotype.Repository; + +import javax.sql.DataSource; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +/** + * A simple JDBC-based implementation of the {@link VisitRepository} interface. + * + * @author Ken Krebs + * @author Juergen Hoeller + * @author Rob Harrop + * @author Sam Brannen + * @author Thomas Risberg + * @author Mark Fisher + * @author Michael Isvy + * @author Vitaliy Fedoriv + */ +@Repository +@Profile("jdbc") +public class JdbcVisitRepositoryImpl implements VisitRepository { + + protected SimpleJdbcInsert insertVisit; + private NamedParameterJdbcTemplate namedParameterJdbcTemplate; + + @Autowired + public JdbcVisitRepositoryImpl(DataSource dataSource) { + this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); + + this.insertVisit = new SimpleJdbcInsert(dataSource) + .withTableName("visits") + .usingGeneratedKeyColumns("id"); + } + + + /** + * Creates a {@link MapSqlParameterSource} based on data values from the supplied {@link Visit} instance. + */ + protected MapSqlParameterSource createVisitParameterSource(Visit visit) { + return new MapSqlParameterSource() + .addValue("id", visit.getId()) + .addValue("visit_date", visit.getDate()) + .addValue("description", visit.getDescription()) + .addValue("pet_id", visit.getPet().getId()); + } + + @Override + public List findByPetId(Integer petId) { + Map params = new HashMap<>(); + params.put("id", petId); + JdbcPet pet = this.namedParameterJdbcTemplate.queryForObject( + "SELECT id as pets_id, name, birth_date, type_id, owner_id FROM pets WHERE id=:id", + params, + new JdbcPetRowMapper()); + + List visits = this.namedParameterJdbcTemplate.query( + "SELECT id as visit_id, visit_date, description FROM visits WHERE pet_id=:id", + params, new JdbcVisitRowMapper()); + + for (Visit visit : visits) { + visit.setPet(pet); + } + + return visits; + } + + @Override + public Visit findById(int id) throws DataAccessException { + Visit visit; + try { + Map params = new HashMap<>(); + params.put("id", id); + visit = this.namedParameterJdbcTemplate.queryForObject( + "SELECT id as visit_id, visits.pet_id as pets_id, visit_date, description FROM visits WHERE id= :id", + params, + new JdbcVisitRowMapperExt()); + } catch (EmptyResultDataAccessException ex) { + throw new ObjectRetrievalFailureException(Visit.class, id); + } + return visit; + } + + @Override + public Collection findAll() throws DataAccessException { + Map params = new HashMap<>(); + return this.namedParameterJdbcTemplate.query( + "SELECT id as visit_id, pets.id as pets_id, visit_date, description FROM visits LEFT JOIN pets ON visits.pet_id = pets.id", + params, new JdbcVisitRowMapperExt()); + } + + @Override + public void save(Visit visit) throws DataAccessException { + if (visit.isNew()) { + Number newKey = this.insertVisit.executeAndReturnKey(createVisitParameterSource(visit)); + visit.setId(newKey.intValue()); + } else { + this.namedParameterJdbcTemplate.update( + "UPDATE visits SET visit_date=:visit_date, description=:description, pet_id=:pet_id WHERE id=:id ", + createVisitParameterSource(visit)); + } + } + + @Override + public void delete(Visit visit) throws DataAccessException { + Map params = new HashMap<>(); + params.put("id", visit.getId()); + this.namedParameterJdbcTemplate.update("DELETE FROM visits WHERE id=:id", params); + } + + protected class JdbcVisitRowMapperExt implements RowMapper { + + @Override + public Visit mapRow(ResultSet rs, int rowNum) throws SQLException { + Visit visit = new Visit(); + JdbcPet pet = new JdbcPet(); + PetType petType = new PetType(); + Owner owner = new Owner(); + visit.setId(rs.getInt("visit_id")); + Date visitDate = rs.getDate("visit_date"); + visit.setDate(new java.sql.Date(visitDate.getTime()).toLocalDate()); + visit.setDescription(rs.getString("description")); + Map params = new HashMap<>(); + params.put("id", rs.getInt("pets_id")); + pet = JdbcVisitRepositoryImpl.this.namedParameterJdbcTemplate.queryForObject( + "SELECT pets.id as pets_id, name, birth_date, type_id, owner_id FROM pets WHERE pets.id=:id", + params, + new JdbcPetRowMapper()); + params.put("type_id", pet.getTypeId()); + petType = JdbcVisitRepositoryImpl.this.namedParameterJdbcTemplate.queryForObject( + "SELECT id, name FROM types WHERE id= :type_id", + params, + BeanPropertyRowMapper.newInstance(PetType.class)); + pet.setType(petType); + params.put("owner_id", pet.getOwnerId()); + owner = JdbcVisitRepositoryImpl.this.namedParameterJdbcTemplate.queryForObject( + "SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE id= :owner_id", + params, + BeanPropertyRowMapper.newInstance(Owner.class)); + pet.setOwner(owner); + visit.setPet(pet); + return visit; + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVisitRowMapper.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVisitRowMapper.java new file mode 100644 index 00000000..9cab6c51 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVisitRowMapper.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository.jdbc; + + +import org.springframework.jdbc.core.RowMapper; +import org.springframework.samples.petclinic.model.Visit; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.LocalDate; +import java.util.Date; + +/** + * {@link RowMapper} implementation mapping data from a {@link ResultSet} to the corresponding properties + * of the {@link Visit} class. + */ +class JdbcVisitRowMapper implements RowMapper { + + @Override + public Visit mapRow(ResultSet rs, int row) throws SQLException { + Visit visit = new Visit(); + visit.setId(rs.getInt("visit_id")); + visit.setDate(rs.getObject("visit_date", LocalDate.class)); + visit.setDescription(rs.getString("description")); + return visit; + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/package-info.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/package-info.java new file mode 100644 index 00000000..d093503f --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/package-info.java @@ -0,0 +1,6 @@ +/** + * The classes in this package represent the JDBC implementation + * of PetClinic's persistence layer. + */ +package org.springframework.samples.petclinic.repository.jdbc; + diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaOwnerRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaOwnerRepositoryImpl.java new file mode 100644 index 00000000..3240d070 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaOwnerRepositoryImpl.java @@ -0,0 +1,96 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository.jpa; + +import java.util.Collection; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.Query; + +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.orm.hibernate5.support.OpenSessionInViewFilter; +import org.springframework.samples.petclinic.model.Owner; +import org.springframework.samples.petclinic.repository.OwnerRepository; +import org.springframework.stereotype.Repository; + +/** + * JPA implementation of the {@link OwnerRepository} interface. + * + * @author Mike Keith + * @author Rod Johnson + * @author Sam Brannen + * @author Michael Isvy + * @author Vitaliy Fedoriv + */ +@Repository +@Profile("jpa") +public class JpaOwnerRepositoryImpl implements OwnerRepository { + + @PersistenceContext + private EntityManager em; + + + /** + * Important: in the current version of this method, we load Owners with all their Pets and Visits while + * we do not need Visits at all and we only need one property from the Pet objects (the 'name' property). + * There are some ways to improve it such as: + * - creating a Ligtweight class (example here: https://community.jboss.org/wiki/LightweightClass) + * - Turning on lazy-loading and using {@link OpenSessionInViewFilter} + */ + @SuppressWarnings("unchecked") + public Collection findByLastName(String lastName) { + // using 'join fetch' because a single query should load both owners and pets + // using 'left join fetch' because it might happen that an owner does not have pets yet + Query query = this.em.createQuery("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName"); + query.setParameter("lastName", lastName + "%"); + return query.getResultList(); + } + + @Override + public Owner findById(int id) { + // using 'join fetch' because a single query should load both owners and pets + // using 'left join fetch' because it might happen that an owner does not have pets yet + Query query = this.em.createQuery("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id"); + query.setParameter("id", id); + return (Owner) query.getSingleResult(); + } + + + @Override + public void save(Owner owner) { + if (owner.getId() == null) { + this.em.persist(owner); + } else { + this.em.merge(owner); + } + + } + + @SuppressWarnings("unchecked") + @Override + public Collection findAll() throws DataAccessException { + Query query = this.em.createQuery("SELECT owner FROM Owner owner"); + return query.getResultList(); + } + + @Override + public void delete(Owner owner) throws DataAccessException { + this.em.remove(this.em.contains(owner) ? owner : this.em.merge(owner)); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaPetRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaPetRepositoryImpl.java new file mode 100644 index 00000000..8b04981b --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaPetRepositoryImpl.java @@ -0,0 +1,84 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository.jpa; + +import java.util.Collection; +import java.util.List; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; + +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.repository.PetRepository; +import org.springframework.stereotype.Repository; + +/** + * JPA implementation of the {@link PetRepository} interface. + * + * @author Mike Keith + * @author Rod Johnson + * @author Sam Brannen + * @author Michael Isvy + * @author Vitaliy Fedoriv + */ +@Repository +@Profile("jpa") +public class JpaPetRepositoryImpl implements PetRepository { + + @PersistenceContext + private EntityManager em; + + @Override + @SuppressWarnings("unchecked") + public List findPetTypes() { + return this.em.createQuery("SELECT ptype FROM PetType ptype ORDER BY ptype.name").getResultList(); + } + + @Override + public Pet findById(int id) { + return this.em.find(Pet.class, id); + } + + @Override + public void save(Pet pet) { + if (pet.getId() == null) { + this.em.persist(pet); + } else { + this.em.merge(pet); + } + } + + @SuppressWarnings("unchecked") + @Override + public Collection findAll() throws DataAccessException { + return this.em.createQuery("SELECT pet FROM Pet pet").getResultList(); + } + + @Override + public void delete(Pet pet) throws DataAccessException { + //this.em.remove(this.em.contains(pet) ? pet : this.em.merge(pet)); + String petId = pet.getId().toString(); + this.em.createQuery("DELETE FROM Visit visit WHERE pet.id=" + petId).executeUpdate(); + this.em.createQuery("DELETE FROM Pet pet WHERE id=" + petId).executeUpdate(); + if (em.contains(pet)) { + em.remove(pet); + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaPetTypeRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaPetTypeRepositoryImpl.java new file mode 100644 index 00000000..184aa382 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaPetTypeRepositoryImpl.java @@ -0,0 +1,92 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.repository.jpa; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; + +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.model.Visit; +import org.springframework.samples.petclinic.repository.PetTypeRepository; +import org.springframework.stereotype.Repository; + +/** + * @author Vitaliy Fedoriv + * + */ + +@Repository +@Profile("jpa") +public class JpaPetTypeRepositoryImpl implements PetTypeRepository { + + @PersistenceContext + private EntityManager em; + + @Override + public PetType findById(int id) { + return this.em.find(PetType.class, id); + } + + @Override + public PetType findByName(String name) throws DataAccessException { + return this.em.createQuery("SELECT p FROM PetType p WHERE p.name = :name", PetType.class) + .setParameter("name", name) + .getSingleResult(); + } + + + @SuppressWarnings("unchecked") + @Override + public Collection findAll() throws DataAccessException { + return this.em.createQuery("SELECT ptype FROM PetType ptype").getResultList(); + } + + @Override + public void save(PetType petType) throws DataAccessException { + if (petType.getId() == null) { + this.em.persist(petType); + } else { + this.em.merge(petType); + } + + } + + @SuppressWarnings("unchecked") + @Override + public void delete(PetType petType) throws DataAccessException { + this.em.remove(this.em.contains(petType) ? petType : this.em.merge(petType)); + Integer petTypeId = petType.getId(); + + List pets = this.em.createQuery("SELECT pet FROM Pet pet WHERE type.id=" + petTypeId).getResultList(); + for (Pet pet : pets){ + List visits = pet.getVisits(); + for (Visit visit : visits){ + this.em.createQuery("DELETE FROM Visit visit WHERE id=" + visit.getId()).executeUpdate(); + } + this.em.createQuery("DELETE FROM Pet pet WHERE id=" + pet.getId()).executeUpdate(); + } + this.em.createQuery("DELETE FROM PetType pettype WHERE id=" + petTypeId).executeUpdate(); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaSpecialtyRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaSpecialtyRepositoryImpl.java new file mode 100644 index 00000000..3c95587a --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaSpecialtyRepositoryImpl.java @@ -0,0 +1,80 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.repository.jpa; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; + +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.samples.petclinic.model.Specialty; +import org.springframework.samples.petclinic.repository.SpecialtyRepository; +import org.springframework.stereotype.Repository; + +/** + * @author Vitaliy Fedoriv + * + */ + +@Repository +@Profile("jpa") +public class JpaSpecialtyRepositoryImpl implements SpecialtyRepository { + + @PersistenceContext + private EntityManager em; + + @Override + public Specialty findById(int id) { + return this.em.find(Specialty.class, id); + } + + @Override + public List findSpecialtiesByNameIn(Set names) { + final String jpql = "SELECT s FROM Specialty s WHERE s.name IN :names"; + return em.createQuery(jpql, Specialty.class) + .setParameter("names", names) + .getResultList(); + } + + @SuppressWarnings("unchecked") + @Override + public Collection findAll() throws DataAccessException { + return this.em.createQuery("SELECT s FROM Specialty s").getResultList(); + } + + @Override + public void save(Specialty specialty) throws DataAccessException { + if (specialty.getId() == null) { + this.em.persist(specialty); + } else { + this.em.merge(specialty); + } + } + + @Override + public void delete(Specialty specialty) throws DataAccessException { + this.em.remove(this.em.contains(specialty) ? specialty : this.em.merge(specialty)); + Integer specId = specialty.getId(); + this.em.createNativeQuery("DELETE FROM vet_specialties WHERE specialty_id=" + specId).executeUpdate(); + this.em.createQuery("DELETE FROM Specialty specialty WHERE id=" + specId).executeUpdate(); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaUserRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaUserRepositoryImpl.java new file mode 100644 index 00000000..de3fd4e6 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaUserRepositoryImpl.java @@ -0,0 +1,27 @@ +package org.springframework.samples.petclinic.repository.jpa; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; + +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.samples.petclinic.model.User; +import org.springframework.samples.petclinic.repository.UserRepository; +import org.springframework.stereotype.Repository; + +@Repository +@Profile("jpa") +public class JpaUserRepositoryImpl implements UserRepository { + + @PersistenceContext + private EntityManager em; + + @Override + public void save(User user) throws DataAccessException { + if (this.em.find(User.class, user.getUsername()) == null) { + this.em.persist(user); + } else { + this.em.merge(user); + } + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVetRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVetRepositoryImpl.java new file mode 100644 index 00000000..eed4dbb2 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVetRepositoryImpl.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository.jpa; + +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.samples.petclinic.model.Vet; +import org.springframework.samples.petclinic.repository.VetRepository; +import org.springframework.stereotype.Repository; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import java.util.Collection; + +/** + * JPA implementation of the {@link VetRepository} interface. + * + * @author Mike Keith + * @author Rod Johnson + * @author Sam Brannen + * @author Michael Isvy + * @author Vitaliy Fedoriv + */ +@Repository +@Profile("jpa") +public class JpaVetRepositoryImpl implements VetRepository { + + @PersistenceContext + private EntityManager em; + + + @Override + public Vet findById(int id) throws DataAccessException { + return this.em.find(Vet.class, id); + } + + @SuppressWarnings("unchecked") + @Override + public Collection findAll() throws DataAccessException { + return this.em.createQuery("SELECT vet FROM Vet vet").getResultList(); + } + + @Override + public void save(Vet vet) throws DataAccessException { + if (vet.getId() == null) { + this.em.persist(vet); + } else { + this.em.merge(vet); + } + } + + @Override + public void delete(Vet vet) throws DataAccessException { + this.em.remove(this.em.contains(vet) ? vet : this.em.merge(vet)); + } + + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVisitRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVisitRepositoryImpl.java new file mode 100644 index 00000000..79d03258 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVisitRepositoryImpl.java @@ -0,0 +1,84 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository.jpa; + +import java.util.Collection; +import java.util.List; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.Query; + +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.samples.petclinic.model.Visit; +import org.springframework.samples.petclinic.repository.VisitRepository; +import org.springframework.stereotype.Repository; + +/** + * JPA implementation of the ClinicService interface using EntityManager. + *

+ *

The mappings are defined in "orm.xml" located in the META-INF directory. + * + * @author Mike Keith + * @author Rod Johnson + * @author Sam Brannen + * @author Michael Isvy + * @author Vitaliy Fedoriv + */ +@Repository +@Profile("jpa") +public class JpaVisitRepositoryImpl implements VisitRepository { + + @PersistenceContext + private EntityManager em; + + + @Override + public void save(Visit visit) { + if (visit.getId() == null) { + this.em.persist(visit); + } else { + this.em.merge(visit); + } + } + + + @Override + @SuppressWarnings("unchecked") + public List findByPetId(Integer petId) { + Query query = this.em.createQuery("SELECT v FROM Visit v where v.pet.id= :id"); + query.setParameter("id", petId); + return query.getResultList(); + } + + @Override + public Visit findById(int id) throws DataAccessException { + return this.em.find(Visit.class, id); + } + + @SuppressWarnings("unchecked") + @Override + public Collection findAll() throws DataAccessException { + return this.em.createQuery("SELECT v FROM Visit v").getResultList(); + } + + @Override + public void delete(Visit visit) throws DataAccessException { + this.em.remove(this.em.contains(visit) ? visit : this.em.merge(visit)); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/package-info.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/package-info.java new file mode 100644 index 00000000..04fd89ba --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/jpa/package-info.java @@ -0,0 +1,6 @@ +/** + * The classes in this package represent the JPA implementation + * of PetClinic's persistence layer. + */ +package org.springframework.samples.petclinic.repository.jpa; + diff --git a/src/main/java/org/springframework/samples/petclinic/web/CustomErrorController.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/PetRepositoryOverride.java similarity index 52% rename from src/main/java/org/springframework/samples/petclinic/web/CustomErrorController.java rename to src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/PetRepositoryOverride.java index 965697c6..78c02b00 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/CustomErrorController.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/PetRepositoryOverride.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,22 +14,19 @@ * limitations under the License. */ -package org.springframework.samples.petclinic.web; +package org.springframework.samples.petclinic.repository.springdatajpa; -import org.springframework.boot.autoconfigure.web.ErrorController; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.context.annotation.Profile; +import org.springframework.samples.petclinic.model.Pet; -@Controller -public class CustomErrorController implements ErrorController { +/** + * @author Vitaliy Fedoriv + * + */ - @RequestMapping(value = "/error") - public String error() { - return "exception"; - } +@Profile("spring-data-jpa") +public interface PetRepositoryOverride { + + void delete(Pet pet); - @Override - public String getErrorPath() { - return "/error"; - } } diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/PetTypeRepositoryOverride.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/PetTypeRepositoryOverride.java new file mode 100644 index 00000000..a3b19e90 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/PetTypeRepositoryOverride.java @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.repository.springdatajpa; + +import org.springframework.context.annotation.Profile; +import org.springframework.samples.petclinic.model.PetType; + +/** + * @author Vitaliy Fedoriv + * + */ + +@Profile("spring-data-jpa") +public interface PetTypeRepositoryOverride { + + void delete(PetType petType); + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpecialtyRepositoryOverride.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpecialtyRepositoryOverride.java new file mode 100644 index 00000000..656d8efe --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpecialtyRepositoryOverride.java @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.repository.springdatajpa; + +import org.springframework.context.annotation.Profile; +import org.springframework.samples.petclinic.model.Specialty; + +/** + * @author Vitaliy Fedoriv + * + */ + +@Profile("spring-data-jpa") +public interface SpecialtyRepositoryOverride { + + void delete(Specialty specialty); + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataOwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataOwnerRepository.java new file mode 100644 index 00000000..78c0093b --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataOwnerRepository.java @@ -0,0 +1,44 @@ +/* + * Copyright 2002-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository.springdatajpa; + +import java.util.Collection; + +import org.springframework.context.annotation.Profile; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.Repository; +import org.springframework.data.repository.query.Param; +import org.springframework.samples.petclinic.model.Owner; +import org.springframework.samples.petclinic.repository.OwnerRepository; + +/** + * Spring Data JPA specialization of the {@link OwnerRepository} interface + * + * @author Michael Isvy + * @since 15.1.2013 + */ + +@Profile("spring-data-jpa") +public interface SpringDataOwnerRepository extends OwnerRepository, Repository { + + @Override + @Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%") + Collection findByLastName(@Param("lastName") String lastName); + + @Override + @Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id") + Owner findById(@Param("id") int id); +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetRepository.java new file mode 100644 index 00000000..501d3981 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetRepository.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository.springdatajpa; + +import java.util.List; + +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.Repository; +import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.repository.PetRepository; + +/** + * Spring Data JPA specialization of the {@link PetRepository} interface + * + * @author Michael Isvy + * @author Vitaliy Fedoriv + */ + +@Profile("spring-data-jpa") +public interface SpringDataPetRepository extends PetRepository, Repository, PetRepositoryOverride { + + @Override + @Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name") + List findPetTypes() throws DataAccessException; +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetRepositoryImpl.java new file mode 100644 index 00000000..42995052 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetRepositoryImpl.java @@ -0,0 +1,46 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.repository.springdatajpa; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; + +import org.springframework.context.annotation.Profile; +import org.springframework.samples.petclinic.model.Pet; + +/** + * @author Vitaliy Fedoriv + * + */ + +@Profile("spring-data-jpa") +public class SpringDataPetRepositoryImpl implements PetRepositoryOverride { + + @PersistenceContext + private EntityManager em; + + @Override + public void delete(Pet pet) { + String petId = pet.getId().toString(); + this.em.createQuery("DELETE FROM Visit visit WHERE pet.id=" + petId).executeUpdate(); + this.em.createQuery("DELETE FROM Pet pet WHERE id=" + petId).executeUpdate(); + if (em.contains(pet)) { + em.remove(pet); + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetTypeRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetTypeRepository.java new file mode 100644 index 00000000..18a69796 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetTypeRepository.java @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.repository.springdatajpa; + +import org.springframework.context.annotation.Profile; +import org.springframework.data.repository.Repository; +import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.repository.PetTypeRepository; + +/** + * @author Vitaliy Fedoriv + * + */ + +@Profile("spring-data-jpa") +public interface SpringDataPetTypeRepository extends PetTypeRepository, Repository, PetTypeRepositoryOverride { + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetTypeRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetTypeRepositoryImpl.java new file mode 100644 index 00000000..5350c4eb --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetTypeRepositoryImpl.java @@ -0,0 +1,56 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.repository.springdatajpa; + +import org.springframework.context.annotation.Profile; +import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.model.Visit; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import java.util.List; + +/** + * @author Vitaliy Fedoriv + * + */ + +@Profile("spring-data-jpa") +public class SpringDataPetTypeRepositoryImpl implements PetTypeRepositoryOverride { + + @PersistenceContext + private EntityManager em; + + @SuppressWarnings("unchecked") + @Override + public void delete(PetType petType) { + this.em.remove(this.em.contains(petType) ? petType : this.em.merge(petType)); + Integer petTypeId = petType.getId(); + + List pets = this.em.createQuery("SELECT pet FROM Pet pet WHERE type.id=" + petTypeId).getResultList(); + for (Pet pet : pets){ + List visits = pet.getVisits(); + for (Visit visit : visits){ + this.em.createQuery("DELETE FROM Visit visit WHERE id=" + visit.getId()).executeUpdate(); + } + this.em.createQuery("DELETE FROM Pet pet WHERE id=" + pet.getId()).executeUpdate(); + } + this.em.createQuery("DELETE FROM PetType pettype WHERE id=" + petTypeId).executeUpdate(); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataSpecialtyRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataSpecialtyRepository.java new file mode 100644 index 00000000..5ec7364b --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataSpecialtyRepository.java @@ -0,0 +1,33 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.repository.springdatajpa; + +import org.springframework.context.annotation.Profile; +import org.springframework.data.repository.Repository; +import org.springframework.samples.petclinic.model.Specialty; +import org.springframework.samples.petclinic.repository.SpecialtyRepository; + + +/** + * @author Vitaliy Fedoriv + * + */ + +@Profile("spring-data-jpa") +public interface SpringDataSpecialtyRepository extends SpecialtyRepository, Repository, SpecialtyRepositoryOverride { + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataSpecialtyRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataSpecialtyRepositoryImpl.java new file mode 100644 index 00000000..940625f7 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataSpecialtyRepositoryImpl.java @@ -0,0 +1,44 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.repository.springdatajpa; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; + +import org.springframework.context.annotation.Profile; +import org.springframework.samples.petclinic.model.Specialty; + +/** + * @author Vitaliy Fedoriv + * + */ + +@Profile("spring-data-jpa") +public class SpringDataSpecialtyRepositoryImpl implements SpecialtyRepositoryOverride { + + @PersistenceContext + private EntityManager em; + + @Override + public void delete(Specialty specialty) { + this.em.remove(this.em.contains(specialty) ? specialty : this.em.merge(specialty)); + Integer specId = specialty.getId(); + this.em.createNativeQuery("DELETE FROM vet_specialties WHERE specialty_id=" + specId).executeUpdate(); + this.em.createQuery("DELETE FROM Specialty specialty WHERE id=" + specId).executeUpdate(); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataUserRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataUserRepository.java new file mode 100644 index 00000000..4219df45 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataUserRepository.java @@ -0,0 +1,11 @@ +package org.springframework.samples.petclinic.repository.springdatajpa; + +import org.springframework.context.annotation.Profile; +import org.springframework.data.repository.Repository; +import org.springframework.samples.petclinic.model.User; +import org.springframework.samples.petclinic.repository.UserRepository; + +@Profile("spring-data-jpa") +public interface SpringDataUserRepository extends UserRepository, Repository { + +} diff --git a/src/main/java/org/springframework/samples/petclinic/model/Vets.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVetRepository.java similarity index 50% rename from src/main/java/org/springframework/samples/petclinic/model/Vets.java rename to src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVetRepository.java index a6f05c60..c52e440b 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Vets.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVetRepository.java @@ -13,31 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.samples.petclinic.model; +package org.springframework.samples.petclinic.repository.springdatajpa; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; +import org.springframework.context.annotation.Profile; +import org.springframework.data.repository.Repository; +import org.springframework.samples.petclinic.model.Vet; +import org.springframework.samples.petclinic.repository.VetRepository; /** - * Simple domain object representing a list of veterinarians. Mostly here to be used for the 'vets' {@link - * org.springframework.web.servlet.view.xml.MarshallingView}. + * Spring Data JPA specialization of the {@link VetRepository} interface * - * @author Arjen Poutsma + * @author Michael Isvy + * @since 15.1.2013 */ -@XmlRootElement -public class Vets { - - private List vets; - - @XmlElement - public List getVetList() { - if (vets == null) { - vets = new ArrayList<>(); - } - return vets; - } +@Profile("spring-data-jpa") +public interface SpringDataVetRepository extends VetRepository, Repository { } diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVisitRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVisitRepository.java new file mode 100644 index 00000000..1b3c6c3f --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVisitRepository.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.repository.springdatajpa; + +import org.springframework.context.annotation.Profile; +import org.springframework.data.repository.Repository; +import org.springframework.samples.petclinic.model.Visit; +import org.springframework.samples.petclinic.repository.VisitRepository; + +/** + * Spring Data JPA specialization of the {@link VisitRepository} interface + * + * @author Michael Isvy + * @author Vitaliy Fedoriv + */ + +@Profile("spring-data-jpa") +public interface SpringDataVisitRepository extends VisitRepository, Repository, VisitRepositoryOverride { +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVisitRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVisitRepositoryImpl.java new file mode 100644 index 00000000..4c2fcc09 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVisitRepositoryImpl.java @@ -0,0 +1,47 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.repository.springdatajpa; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; + +import org.springframework.context.annotation.Profile; +import org.springframework.dao.DataAccessException; +import org.springframework.samples.petclinic.model.Visit; + +/** + * @author Vitaliy Fedoriv + * + */ + +@Profile("spring-data-jpa") +public class SpringDataVisitRepositoryImpl implements VisitRepositoryOverride { + + @PersistenceContext + private EntityManager em; + + @Override + public void delete(Visit visit) throws DataAccessException { + String visitId = visit.getId().toString(); + this.em.createQuery("DELETE FROM Visit visit WHERE id=" + visitId).executeUpdate(); + if (em.contains(visit)) { + em.remove(visit); + } + } + + +} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/VisitRepositoryOverride.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/VisitRepositoryOverride.java new file mode 100644 index 00000000..7a622f3e --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/VisitRepositoryOverride.java @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.repository.springdatajpa; + +import org.springframework.context.annotation.Profile; +import org.springframework.samples.petclinic.model.Visit; + +/** + * @author Vitaliy Fedoriv + * + */ + +@Profile("spring-data-jpa") +public interface VisitRepositoryOverride { + + void delete(Visit visit); + +} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/advice/ExceptionControllerAdvice.java b/src/main/java/org/springframework/samples/petclinic/rest/advice/ExceptionControllerAdvice.java new file mode 100644 index 00000000..a49745d0 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/rest/advice/ExceptionControllerAdvice.java @@ -0,0 +1,85 @@ +/* + * Copyright 2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.rest.advice; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.rest.controller.BindingErrorsResponse; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.context.request.WebRequest; + +import static org.springframework.http.HttpStatus.BAD_REQUEST; + +/** + * @author Vitaliy Fedoriv + */ + +@ControllerAdvice +public class ExceptionControllerAdvice { + + @ExceptionHandler(Exception.class) + public ResponseEntity exception(Exception e) { + ObjectMapper mapper = new ObjectMapper(); + ErrorInfo errorInfo = new ErrorInfo(e); + String respJSONstring = "{}"; + try { + respJSONstring = mapper.writeValueAsString(errorInfo); + } catch (JsonProcessingException e1) { + e1.printStackTrace(); + } + return ResponseEntity.badRequest().body(respJSONstring); + } + + /** + * Handles exception thrown by Bean Validation on controller methods parameters + * + * @param ex The thrown exception + * @param request the current web request + * @return an empty response entity + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + @ResponseStatus(code = BAD_REQUEST) + @ResponseBody + public ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, WebRequest request) { + BindingErrorsResponse errors = new BindingErrorsResponse(); + BindingResult bindingResult = ex.getBindingResult(); + HttpHeaders headers = new HttpHeaders(); + if (bindingResult.hasErrors()) { + errors.addAllErrors(bindingResult); + headers.add("errors", errors.toJSON()); + } + return new ResponseEntity<>(headers, HttpStatus.BAD_REQUEST); + } + + private class ErrorInfo { + public final String className; + public final String exMessage; + + public ErrorInfo(Exception ex) { + this.className = ex.getClass().getName(); + this.exMessage = ex.getLocalizedMessage(); + } + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/controller/BindingErrorsResponse.java b/src/main/java/org/springframework/samples/petclinic/rest/controller/BindingErrorsResponse.java new file mode 100644 index 00000000..0c772847 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/rest/controller/BindingErrorsResponse.java @@ -0,0 +1,137 @@ +/* + * Copyright 2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.rest.controller; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.validation.BindingResult; +import org.springframework.validation.FieldError; + +import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * @author Vitaliy Fedoriv + * + */ + +public class BindingErrorsResponse { + + public BindingErrorsResponse() { + this(null); + } + + public BindingErrorsResponse(Integer id) { + this(null, id); + } + + public BindingErrorsResponse(Integer pathId, Integer bodyId) { + boolean onlyBodyIdSpecified = pathId == null && bodyId != null; + if (onlyBodyIdSpecified) { + addBodyIdError(bodyId, "must not be specified"); + } + boolean bothIdsSpecified = pathId != null && bodyId != null; + if (bothIdsSpecified && !pathId.equals(bodyId)) { + addBodyIdError(bodyId, String.format("does not match pathId: %d", pathId)); + } + } + + private void addBodyIdError(Integer bodyId, String message) { + BindingError error = new BindingError(); + error.setObjectName("body"); + error.setFieldName("id"); + error.setFieldValue(bodyId.toString()); + error.setErrorMessage(message); + addError(error); + } + + private final List bindingErrors = new ArrayList(); + + public void addError(BindingError bindingError) { + this.bindingErrors.add(bindingError); + } + + public void addAllErrors(BindingResult bindingResult) { + for (FieldError fieldError : bindingResult.getFieldErrors()) { + BindingError error = new BindingError(); + error.setObjectName(fieldError.getObjectName()); + error.setFieldName(fieldError.getField()); + error.setFieldValue(String.valueOf(fieldError.getRejectedValue())); + error.setErrorMessage(fieldError.getDefaultMessage()); + addError(error); + } + } + + public String toJSON() { + ObjectMapper mapper = new ObjectMapper(); + mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); + String errorsAsJSON = ""; + try { + errorsAsJSON = mapper.writeValueAsString(bindingErrors); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return errorsAsJSON; + } + + @Override + public String toString() { + return "BindingErrorsResponse [bindingErrors=" + bindingErrors + "]"; + } + + protected static class BindingError { + + private String objectName; + private String fieldName; + private String fieldValue; + private String errorMessage; + + public BindingError() { + this.objectName = ""; + this.fieldName = ""; + this.fieldValue = ""; + this.errorMessage = ""; + } + + protected void setObjectName(String objectName) { + this.objectName = objectName; + } + + protected void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + protected void setFieldValue(String fieldValue) { + this.fieldValue = fieldValue; + } + + protected void setErrorMessage(String error_message) { + this.errorMessage = error_message; + } + + @Override + public String toString() { + return "BindingError [objectName=" + objectName + ", fieldName=" + fieldName + ", fieldValue=" + fieldValue + + ", errorMessage=" + errorMessage + "]"; + } + + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/controller/OwnerRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/controller/OwnerRestController.java new file mode 100644 index 00000000..cb2d0bad --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/rest/controller/OwnerRestController.java @@ -0,0 +1,183 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.rest.controller; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.mapper.OwnerMapper; +import org.springframework.samples.petclinic.mapper.PetMapper; +import org.springframework.samples.petclinic.mapper.VisitMapper; +import org.springframework.samples.petclinic.model.Owner; +import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.model.Visit; +import org.springframework.samples.petclinic.rest.api.OwnersApi; +import org.springframework.samples.petclinic.rest.dto.*; +import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.util.UriComponentsBuilder; + +import jakarta.transaction.Transactional; + +import java.util.Collection; +import java.util.List; + +/** + * @author Vitaliy Fedoriv + */ + +@RestController +@CrossOrigin(exposedHeaders = "errors, content-type") +@RequestMapping("/api") +public class OwnerRestController implements OwnersApi { + + private final ClinicService clinicService; + + private final OwnerMapper ownerMapper; + + private final PetMapper petMapper; + + private final VisitMapper visitMapper; + + public OwnerRestController(ClinicService clinicService, + OwnerMapper ownerMapper, + PetMapper petMapper, + VisitMapper visitMapper) { + this.clinicService = clinicService; + this.ownerMapper = ownerMapper; + this.petMapper = petMapper; + this.visitMapper = visitMapper; + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity> listOwners(String lastName) { + Collection owners; + if (lastName != null) { + owners = this.clinicService.findOwnerByLastName(lastName); + } else { + owners = this.clinicService.findAllOwners(); + } + if (owners.isEmpty()) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<>(ownerMapper.toOwnerDtoCollection(owners), HttpStatus.OK); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity getOwner(Integer ownerId) { + Owner owner = this.clinicService.findOwnerById(ownerId); + if (owner == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<>(ownerMapper.toOwnerDto(owner), HttpStatus.OK); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity addOwner(OwnerFieldsDto ownerFieldsDto) { + HttpHeaders headers = new HttpHeaders(); + Owner owner = ownerMapper.toOwner(ownerFieldsDto); + this.clinicService.saveOwner(owner); + OwnerDto ownerDto = ownerMapper.toOwnerDto(owner); + headers.setLocation(UriComponentsBuilder.newInstance() + .path("/api/owners/{id}").buildAndExpand(owner.getId()).toUri()); + return new ResponseEntity<>(ownerDto, headers, HttpStatus.CREATED); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity updateOwner(Integer ownerId, OwnerFieldsDto ownerFieldsDto) { + Owner currentOwner = this.clinicService.findOwnerById(ownerId); + if (currentOwner == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + currentOwner.setAddress(ownerFieldsDto.getAddress()); + currentOwner.setCity(ownerFieldsDto.getCity()); + currentOwner.setFirstName(ownerFieldsDto.getFirstName()); + currentOwner.setLastName(ownerFieldsDto.getLastName()); + currentOwner.setTelephone(ownerFieldsDto.getTelephone()); + this.clinicService.saveOwner(currentOwner); + return new ResponseEntity<>(ownerMapper.toOwnerDto(currentOwner), HttpStatus.NO_CONTENT); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Transactional + @Override + public ResponseEntity deleteOwner(Integer ownerId) { + Owner owner = this.clinicService.findOwnerById(ownerId); + if (owner == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + this.clinicService.deleteOwner(owner); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity addPetToOwner(Integer ownerId, PetFieldsDto petFieldsDto) { + HttpHeaders headers = new HttpHeaders(); + Pet pet = petMapper.toPet(petFieldsDto); + Owner owner = new Owner(); + owner.setId(ownerId); + pet.setOwner(owner); + PetType petType = this.clinicService.findPetTypeByName(pet.getType().getName()); + pet.setType(petType); + this.clinicService.savePet(pet); + PetDto petDto = petMapper.toPetDto(pet); + headers.setLocation(UriComponentsBuilder.newInstance().path("/api/pets/{id}") + .buildAndExpand(pet.getId()).toUri()); + return new ResponseEntity<>(petDto, headers, HttpStatus.CREATED); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity addVisitToOwner(Integer ownerId, Integer petId, VisitFieldsDto visitFieldsDto) { + HttpHeaders headers = new HttpHeaders(); + Visit visit = visitMapper.toVisit(visitFieldsDto); + Pet pet = new Pet(); + pet.setId(petId); + visit.setPet(pet); + this.clinicService.saveVisit(visit); + VisitDto visitDto = visitMapper.toVisitDto(visit); + headers.setLocation(UriComponentsBuilder.newInstance().path("/api/visits/{id}") + .buildAndExpand(visit.getId()).toUri()); + return new ResponseEntity<>(visitDto, headers, HttpStatus.CREATED); + } + + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity getOwnersPet(Integer ownerId, Integer petId) { + Owner owner = this.clinicService.findOwnerById(ownerId); + Pet pet = this.clinicService.findPetById(petId); + if (owner == null || pet == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } else { + if (!pet.getOwner().equals(owner)) { + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } else { + return new ResponseEntity<>(petMapper.toPetDto(pet), HttpStatus.OK); + } + } + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/controller/PetRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/controller/PetRestController.java new file mode 100644 index 00000000..c249d3aa --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/rest/controller/PetRestController.java @@ -0,0 +1,104 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.rest.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.mapper.PetMapper; +import org.springframework.samples.petclinic.model.Pet; +import org.springframework.samples.petclinic.rest.api.PetsApi; +import org.springframework.samples.petclinic.rest.dto.PetDto; +import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Vitaliy Fedoriv + */ + +@RestController +@CrossOrigin(exposedHeaders = "errors, content-type") +@RequestMapping("api") +public class PetRestController implements PetsApi { + + private final ClinicService clinicService; + + private final PetMapper petMapper; + + public PetRestController(ClinicService clinicService, PetMapper petMapper) { + this.clinicService = clinicService; + this.petMapper = petMapper; + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity getPet(Integer petId) { + PetDto pet = petMapper.toPetDto(this.clinicService.findPetById(petId)); + if (pet == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<>(pet, HttpStatus.OK); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity> listPets() { + List pets = new ArrayList<>(petMapper.toPetsDto(this.clinicService.findAllPets())); + if (pets.isEmpty()) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<>(pets, HttpStatus.OK); + } + + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity updatePet(Integer petId, PetDto petDto) { + Pet currentPet = this.clinicService.findPetById(petId); + if (currentPet == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + currentPet.setBirthDate(petDto.getBirthDate()); + currentPet.setName(petDto.getName()); + currentPet.setType(petMapper.toPetType(petDto.getType())); + this.clinicService.savePet(currentPet); + return new ResponseEntity<>(petMapper.toPetDto(currentPet), HttpStatus.NO_CONTENT); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity deletePet(Integer petId) { + Pet pet = this.clinicService.findPetById(petId); + if (pet == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + this.clinicService.deletePet(pet); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity addPet(PetDto petDto) { + this.clinicService.savePet(petMapper.toPet(petDto)); + return new ResponseEntity<>(petDto, HttpStatus.OK); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/controller/PetTypeRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/controller/PetTypeRestController.java new file mode 100644 index 00000000..870cd661 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/rest/controller/PetTypeRestController.java @@ -0,0 +1,109 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.rest.controller; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.mapper.PetTypeMapper; +import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.rest.api.PettypesApi; +import org.springframework.samples.petclinic.rest.dto.PetTypeDto; +import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.util.UriComponentsBuilder; + +import jakarta.transaction.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@RestController +@CrossOrigin(exposedHeaders = "errors, content-type") +@RequestMapping("api") +public class PetTypeRestController implements PettypesApi { + + private final ClinicService clinicService; + private final PetTypeMapper petTypeMapper; + + + public PetTypeRestController(ClinicService clinicService, PetTypeMapper petTypeMapper) { + this.clinicService = clinicService; + this.petTypeMapper = petTypeMapper; + } + + @PreAuthorize("hasAnyRole(@roles.OWNER_ADMIN, @roles.VET_ADMIN)") + @Override + public ResponseEntity> listPetTypes() { + List petTypes = new ArrayList<>(this.clinicService.findAllPetTypes()); + if (petTypes.isEmpty()) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<>(petTypeMapper.toPetTypeDtos(petTypes), HttpStatus.OK); + } + + @PreAuthorize("hasAnyRole(@roles.OWNER_ADMIN, @roles.VET_ADMIN)") + @Override + public ResponseEntity getPetType(Integer petTypeId) { + PetType petType = this.clinicService.findPetTypeById(petTypeId); + if (petType == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<>(petTypeMapper.toPetTypeDto(petType), HttpStatus.OK); + } + + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @Override + public ResponseEntity addPetType(PetTypeDto petTypeDto) { + HttpHeaders headers = new HttpHeaders(); + if (Objects.nonNull(petTypeDto.getId()) && !petTypeDto.getId().equals(0)) { + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } else { + final PetType type = petTypeMapper.toPetType(petTypeDto); + this.clinicService.savePetType(type); + headers.setLocation(UriComponentsBuilder.newInstance().path("/api/pettypes/{id}").buildAndExpand(type.getId()).toUri()); + return new ResponseEntity<>(petTypeMapper.toPetTypeDto(type), headers, HttpStatus.CREATED); + } + } + + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @Override + public ResponseEntity updatePetType(Integer petTypeId, PetTypeDto petTypeDto) { + PetType currentPetType = this.clinicService.findPetTypeById(petTypeId); + if (currentPetType == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + currentPetType.setName(petTypeDto.getName()); + this.clinicService.savePetType(currentPetType); + return new ResponseEntity<>(petTypeMapper.toPetTypeDto(currentPetType), HttpStatus.NO_CONTENT); + } + + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @Transactional + @Override + public ResponseEntity deletePetType(Integer petTypeId) { + PetType petType = this.clinicService.findPetTypeById(petTypeId); + if (petType == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + this.clinicService.deletePetType(petType); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/controller/RootRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/controller/RootRestController.java new file mode 100644 index 00000000..7984f66a --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/rest/controller/RootRestController.java @@ -0,0 +1,47 @@ +/* + * Copyright 2016-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.rest.controller; + +import java.io.IOException; + +import jakarta.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author Vitaliy Fedoriv + * + */ + +@RestController +@CrossOrigin(exposedHeaders = "errors, content-type") +@RequestMapping("/") +public class RootRestController { + + @Value("#{servletContext.contextPath}") + private String servletContextPath; + + @RequestMapping(value = "/") + public void redirectToSwagger(HttpServletResponse response) throws IOException { + response.sendRedirect(this.servletContextPath + "/swagger-ui/index.html"); + } + +} + diff --git a/src/main/java/org/springframework/samples/petclinic/rest/controller/SpecialtyRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/controller/SpecialtyRestController.java new file mode 100644 index 00000000..0b82e818 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/rest/controller/SpecialtyRestController.java @@ -0,0 +1,108 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.rest.controller; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.mapper.SpecialtyMapper; +import org.springframework.samples.petclinic.model.Specialty; +import org.springframework.samples.petclinic.rest.api.SpecialtiesApi; +import org.springframework.samples.petclinic.rest.dto.SpecialtyDto; +import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.util.UriComponentsBuilder; + +import jakarta.transaction.Transactional; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Vitaliy Fedoriv + */ + +@RestController +@CrossOrigin(exposedHeaders = "errors, content-type") +@RequestMapping("api") +public class SpecialtyRestController implements SpecialtiesApi { + + private final ClinicService clinicService; + + private final SpecialtyMapper specialtyMapper; + + public SpecialtyRestController(ClinicService clinicService, SpecialtyMapper specialtyMapper) { + this.clinicService = clinicService; + this.specialtyMapper = specialtyMapper; + } + + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @Override + public ResponseEntity> listSpecialties() { + List specialties = new ArrayList<>(); + specialties.addAll(specialtyMapper.toSpecialtyDtos(this.clinicService.findAllSpecialties())); + if (specialties.isEmpty()) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<>(specialties, HttpStatus.OK); + } + + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @Override + public ResponseEntity getSpecialty(Integer specialtyId) { + Specialty specialty = this.clinicService.findSpecialtyById(specialtyId); + if (specialty == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<>(specialtyMapper.toSpecialtyDto(specialty), HttpStatus.OK); + } + + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @Override + public ResponseEntity addSpecialty(SpecialtyDto specialtyDto) { + HttpHeaders headers = new HttpHeaders(); + Specialty specialty = specialtyMapper.toSpecialty(specialtyDto); + this.clinicService.saveSpecialty(specialty); + headers.setLocation(UriComponentsBuilder.newInstance().path("/api/specialties/{id}").buildAndExpand(specialty.getId()).toUri()); + return new ResponseEntity<>(specialtyMapper.toSpecialtyDto(specialty), headers, HttpStatus.CREATED); + } + + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @Override + public ResponseEntity updateSpecialty(Integer specialtyId, SpecialtyDto specialtyDto) { + Specialty currentSpecialty = this.clinicService.findSpecialtyById(specialtyId); + if (currentSpecialty == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + currentSpecialty.setName(specialtyDto.getName()); + this.clinicService.saveSpecialty(currentSpecialty); + return new ResponseEntity<>(specialtyMapper.toSpecialtyDto(currentSpecialty), HttpStatus.NO_CONTENT); + } + + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @Transactional + @Override + public ResponseEntity deleteSpecialty(Integer specialtyId) { + Specialty specialty = this.clinicService.findSpecialtyById(specialtyId); + if (specialty == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + this.clinicService.deleteSpecialty(specialty); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/controller/UserRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/controller/UserRestController.java new file mode 100644 index 00000000..ce1d8434 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/rest/controller/UserRestController.java @@ -0,0 +1,57 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.rest.controller; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.mapper.UserMapper; +import org.springframework.samples.petclinic.model.User; +import org.springframework.samples.petclinic.rest.api.UsersApi; +import org.springframework.samples.petclinic.rest.dto.UserDto; +import org.springframework.samples.petclinic.service.UserService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import jakarta.validation.Valid; + +@RestController +@CrossOrigin(exposedHeaders = "errors, content-type") +@RequestMapping("api") +public class UserRestController implements UsersApi { + + private final UserService userService; + private final UserMapper userMapper; + + public UserRestController(UserService userService, UserMapper userMapper) { + this.userService = userService; + this.userMapper = userMapper; + } + + + @PreAuthorize( "hasRole(@roles.ADMIN)" ) + @Override + public ResponseEntity addUser(UserDto userDto) { + HttpHeaders headers = new HttpHeaders(); + User user = userMapper.toUser(userDto); + this.userService.saveUser(user); + return new ResponseEntity<>(userMapper.toUserDto(user), headers, HttpStatus.CREATED); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/controller/VetRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/controller/VetRestController.java new file mode 100644 index 00000000..531dede5 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/rest/controller/VetRestController.java @@ -0,0 +1,123 @@ +/* + * Copyright 2016-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.rest.controller; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.mapper.SpecialtyMapper; +import org.springframework.samples.petclinic.mapper.VetMapper; +import org.springframework.samples.petclinic.model.Specialty; +import org.springframework.samples.petclinic.model.Vet; +import org.springframework.samples.petclinic.rest.api.VetsApi; +import org.springframework.samples.petclinic.rest.dto.VetDto; +import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.util.UriComponentsBuilder; + +import jakarta.transaction.Transactional; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Vitaliy Fedoriv + */ + +@RestController +@CrossOrigin(exposedHeaders = "errors, content-type") +@RequestMapping("api") +public class VetRestController implements VetsApi { + + private final ClinicService clinicService; + private final VetMapper vetMapper; + private final SpecialtyMapper specialtyMapper; + + public VetRestController(ClinicService clinicService, VetMapper vetMapper, SpecialtyMapper specialtyMapper) { + this.clinicService = clinicService; + this.vetMapper = vetMapper; + this.specialtyMapper = specialtyMapper; + } + + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @Override + public ResponseEntity> listVets() { + List vets = new ArrayList<>(); + vets.addAll(vetMapper.toVetDtos(this.clinicService.findAllVets())); + if (vets.isEmpty()) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<>(vets, HttpStatus.OK); + } + + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @Override + public ResponseEntity getVet(Integer vetId) { + Vet vet = this.clinicService.findVetById(vetId); + if (vet == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<>(vetMapper.toVetDto(vet), HttpStatus.OK); + } + + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @Override + public ResponseEntity addVet(VetDto vetDto) { + HttpHeaders headers = new HttpHeaders(); + Vet vet = vetMapper.toVet(vetDto); + if(vet.getNrOfSpecialties() > 0){ + List vetSpecialities = this.clinicService.findSpecialtiesByNameIn(vet.getSpecialties().stream().map(Specialty::getName).collect(Collectors.toSet())); + vet.setSpecialties(vetSpecialities); + } + this.clinicService.saveVet(vet); + headers.setLocation(UriComponentsBuilder.newInstance().path("/api/vets/{id}").buildAndExpand(vet.getId()).toUri()); + return new ResponseEntity<>(vetMapper.toVetDto(vet), headers, HttpStatus.CREATED); + } + + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @Override + public ResponseEntity updateVet(Integer vetId,VetDto vetDto) { + Vet currentVet = this.clinicService.findVetById(vetId); + if (currentVet == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + currentVet.setFirstName(vetDto.getFirstName()); + currentVet.setLastName(vetDto.getLastName()); + currentVet.clearSpecialties(); + for (Specialty spec : specialtyMapper.toSpecialtys(vetDto.getSpecialties())) { + currentVet.addSpecialty(spec); + } + if(currentVet.getNrOfSpecialties() > 0){ + List vetSpecialities = this.clinicService.findSpecialtiesByNameIn(currentVet.getSpecialties().stream().map(Specialty::getName).collect(Collectors.toSet())); + currentVet.setSpecialties(vetSpecialities); + } + this.clinicService.saveVet(currentVet); + return new ResponseEntity<>(vetMapper.toVetDto(currentVet), HttpStatus.NO_CONTENT); + } + + @PreAuthorize("hasRole(@roles.VET_ADMIN)") + @Transactional + @Override + public ResponseEntity deleteVet(Integer vetId) { + Vet vet = this.clinicService.findVetById(vetId); + if (vet == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + this.clinicService.deleteVet(vet); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/controller/VisitRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/controller/VisitRestController.java new file mode 100644 index 00000000..138f040c --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/rest/controller/VisitRestController.java @@ -0,0 +1,110 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.samples.petclinic.rest.controller; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.mapper.VisitMapper; +import org.springframework.samples.petclinic.model.Visit; +import org.springframework.samples.petclinic.rest.api.VisitsApi; +import org.springframework.samples.petclinic.rest.dto.VisitDto; +import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.util.UriComponentsBuilder; + +import jakarta.transaction.Transactional; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Vitaliy Fedoriv + */ + +@RestController +@CrossOrigin(exposedHeaders = "errors, content-type") +@RequestMapping("api") +public class VisitRestController implements VisitsApi { + + private final ClinicService clinicService; + + private final VisitMapper visitMapper; + + public VisitRestController(ClinicService clinicService, VisitMapper visitMapper) { + this.clinicService = clinicService; + this.visitMapper = visitMapper; + } + + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity> listVisits() { + List visits = new ArrayList<>(this.clinicService.findAllVisits()); + if (visits.isEmpty()) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<>(new ArrayList<>(visitMapper.toVisitsDto(visits)), HttpStatus.OK); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity getVisit( Integer visitId) { + Visit visit = this.clinicService.findVisitById(visitId); + if (visit == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity<>(visitMapper.toVisitDto(visit), HttpStatus.OK); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity addVisit(VisitDto visitDto) { + HttpHeaders headers = new HttpHeaders(); + Visit visit = visitMapper.toVisit(visitDto); + this.clinicService.saveVisit(visit); + visitDto = visitMapper.toVisitDto(visit); + headers.setLocation(UriComponentsBuilder.newInstance().path("/api/visits/{id}").buildAndExpand(visit.getId()).toUri()); + return new ResponseEntity<>(visitDto, headers, HttpStatus.CREATED); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Override + public ResponseEntity updateVisit(Integer visitId, VisitDto visitDto) { + Visit currentVisit = this.clinicService.findVisitById(visitId); + if (currentVisit == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + currentVisit.setDate(visitDto.getDate()); + currentVisit.setDescription(visitDto.getDescription()); + this.clinicService.saveVisit(currentVisit); + return new ResponseEntity<>(visitMapper.toVisitDto(currentVisit), HttpStatus.NO_CONTENT); + } + + @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") + @Transactional + @Override + public ResponseEntity deleteVisit(Integer visitId) { + Visit visit = this.clinicService.findVisitById(visitId); + if (visit == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + this.clinicService.deleteVisit(visit); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/package-info.java b/src/main/java/org/springframework/samples/petclinic/rest/package-info.java new file mode 100644 index 00000000..dfae7ea5 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/rest/package-info.java @@ -0,0 +1,5 @@ +/** + * The classes in this package represent PetClinic's REST API. + */ + +package org.springframework.samples.petclinic.rest; \ No newline at end of file diff --git a/src/main/java/org/springframework/samples/petclinic/security/BasicAuthenticationConfig.java b/src/main/java/org/springframework/samples/petclinic/security/BasicAuthenticationConfig.java new file mode 100644 index 00000000..2d2e6aed --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/security/BasicAuthenticationConfig.java @@ -0,0 +1,50 @@ +package org.springframework.samples.petclinic.security; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; + +@Configuration +@EnableGlobalMethodSecurity(prePostEnabled = true) // Enable @PreAuthorize method-level security +@ConditionalOnProperty(name = "petclinic.security.enable", havingValue = "true") +public class BasicAuthenticationConfig { + + @Autowired + private DataSource dataSource; + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + // @formatter:off + http + .authorizeHttpRequests((authz) -> authz + .anyRequest().authenticated() + ) + .httpBasic() + .and() + .csrf() + .disable(); + // @formatter:on + return http.build(); + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + // @formatter:off + auth + .jdbcAuthentication() + .dataSource(dataSource) + .usersByUsernameQuery("select username,password,enabled from users where username=?") + .authoritiesByUsernameQuery("select username,role from roles where username=?"); + // @formatter:on + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/security/DisableSecurityConfig.java b/src/main/java/org/springframework/samples/petclinic/security/DisableSecurityConfig.java new file mode 100644 index 00000000..6de93b6e --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/security/DisableSecurityConfig.java @@ -0,0 +1,29 @@ +package org.springframework.samples.petclinic.security; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.SecurityFilterChain; + +/** + * Starting from Spring Boot 2, if Spring Security is present, endpoints are secured by default + * using Spring Security’s content-negotiation strategy. + */ +@Configuration +@ConditionalOnProperty(name = "petclinic.security.enable", havingValue = "false") +public class DisableSecurityConfig { + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + // @formatter:off + http + .authorizeHttpRequests((authz) -> authz + .anyRequest().permitAll() + ) + .csrf() + .disable(); + // @formatter:on + return http.build(); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/security/Roles.java b/src/main/java/org/springframework/samples/petclinic/security/Roles.java new file mode 100644 index 00000000..d60f0497 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/security/Roles.java @@ -0,0 +1,11 @@ +package org.springframework.samples.petclinic.security; + +import org.springframework.stereotype.Component; + +@Component +public class Roles { + + public final String OWNER_ADMIN = "ROLE_OWNER_ADMIN"; + public final String VET_ADMIN = "ROLE_VET_ADMIN"; + public final String ADMIN = "ROLE_ADMIN"; +} diff --git a/src/main/java/org/springframework/samples/petclinic/security/WebSecurityConfig.java b/src/main/java/org/springframework/samples/petclinic/security/WebSecurityConfig.java new file mode 100644 index 00000000..8583c5ad --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/security/WebSecurityConfig.java @@ -0,0 +1,38 @@ +package org.springframework.samples.petclinic.security; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import java.util.List; + +import static java.util.Arrays.asList; +import static org.springframework.security.config.Customizer.withDefaults; + +@Configuration +@EnableWebSecurity +public class WebSecurityConfig { + + @Bean + public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception { + http.authorizeHttpRequests(authz -> authz.anyRequest().permitAll()) + .csrf(csrf -> csrf.disable()) + .cors(cors -> cors.configurationSource(apiConfigurationSource())); + return http.build(); + } + + private CorsConfigurationSource apiConfigurationSource() { + CorsConfiguration configuration = new CorsConfiguration(); + configuration.setAllowedOrigins(List.of("http://localhost:4444")); + configuration.setAllowedMethods(List.of("OPTIONS", "GET","POST","PUT")); + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", configuration); + return source; + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/service/ClinicService.java b/src/main/java/org/springframework/samples/petclinic/service/ClinicService.java index 44b5ed97..6b01f1a9 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/ClinicService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/ClinicService.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,38 +16,57 @@ package org.springframework.samples.petclinic.service; import java.util.Collection; +import java.util.List; +import java.util.Set; import org.springframework.dao.DataAccessException; import org.springframework.samples.petclinic.model.Owner; import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.model.Specialty; import org.springframework.samples.petclinic.model.Vet; import org.springframework.samples.petclinic.model.Visit; - /** * Mostly used as a facade so all controllers have a single point of entry * * @author Michael Isvy + * @author Vitaliy Fedoriv */ public interface ClinicService { - Collection findPetTypes() throws DataAccessException; - - Owner findOwnerById(int id) throws DataAccessException; - - Pet findPetById(int id) throws DataAccessException; - - void savePet(Pet pet) throws DataAccessException; + Pet findPetById(int id) throws DataAccessException; + Collection findAllPets() throws DataAccessException; + void savePet(Pet pet) throws DataAccessException; + void deletePet(Pet pet) throws DataAccessException; - void saveVisit(Visit visit) throws DataAccessException; - - Collection findVets() throws DataAccessException; - - void saveOwner(Owner owner) throws DataAccessException; + Collection findVisitsByPetId(int petId); + Visit findVisitById(int visitId) throws DataAccessException; + Collection findAllVisits() throws DataAccessException; + void saveVisit(Visit visit) throws DataAccessException; + void deleteVisit(Visit visit) throws DataAccessException; + Vet findVetById(int id) throws DataAccessException; + Collection findVets() throws DataAccessException; + Collection findAllVets() throws DataAccessException; + void saveVet(Vet vet) throws DataAccessException; + void deleteVet(Vet vet) throws DataAccessException; + Owner findOwnerById(int id) throws DataAccessException; + Collection findAllOwners() throws DataAccessException; + void saveOwner(Owner owner) throws DataAccessException; + void deleteOwner(Owner owner) throws DataAccessException; + Collection findOwnerByLastName(String lastName) throws DataAccessException; - Collection findOwnerByLastName(String lastName) throws DataAccessException; + PetType findPetTypeById(int petTypeId); + Collection findAllPetTypes() throws DataAccessException; + Collection findPetTypes() throws DataAccessException; + void savePetType(PetType petType) throws DataAccessException; + void deletePetType(PetType petType) throws DataAccessException; + Specialty findSpecialtyById(int specialtyId); + Collection findAllSpecialties() throws DataAccessException; + void saveSpecialty(Specialty specialty) throws DataAccessException; + void deleteSpecialty(Specialty specialty) throws DataAccessException; - Collection findVisitsByPetId(int petId); + List findSpecialtiesByNameIn(Set names) throws DataAccessException; + PetType findPetTypeByName(String name) throws DataAccessException; } diff --git a/src/main/java/org/springframework/samples/petclinic/service/ClinicServiceImpl.java b/src/main/java/org/springframework/samples/petclinic/service/ClinicServiceImpl.java index 4c2360e6..001fb4ae 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/ClinicServiceImpl.java +++ b/src/main/java/org/springframework/samples/petclinic/service/ClinicServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,18 +15,25 @@ */ package org.springframework.samples.petclinic.service; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; +import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cache.annotation.Cacheable; import org.springframework.dao.DataAccessException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.orm.ObjectRetrievalFailureException; import org.springframework.samples.petclinic.model.Owner; import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.model.PetType; +import org.springframework.samples.petclinic.model.Specialty; import org.springframework.samples.petclinic.model.Vet; import org.springframework.samples.petclinic.model.Visit; import org.springframework.samples.petclinic.repository.OwnerRepository; import org.springframework.samples.petclinic.repository.PetRepository; +import org.springframework.samples.petclinic.repository.PetTypeRepository; +import org.springframework.samples.petclinic.repository.SpecialtyRepository; import org.springframework.samples.petclinic.repository.VetRepository; import org.springframework.samples.petclinic.repository.VisitRepository; import org.springframework.stereotype.Service; @@ -37,6 +44,7 @@ * Also a placeholder for @Transactional and @Cacheable annotations * * @author Michael Isvy + * @author Vitaliy Fedoriv */ @Service public class ClinicServiceImpl implements ClinicService { @@ -45,70 +53,260 @@ public class ClinicServiceImpl implements ClinicService { private VetRepository vetRepository; private OwnerRepository ownerRepository; private VisitRepository visitRepository; + private SpecialtyRepository specialtyRepository; + private PetTypeRepository petTypeRepository; @Autowired - public ClinicServiceImpl(PetRepository petRepository, VetRepository vetRepository, OwnerRepository ownerRepository, VisitRepository visitRepository) { + public ClinicServiceImpl( + PetRepository petRepository, + VetRepository vetRepository, + OwnerRepository ownerRepository, + VisitRepository visitRepository, + SpecialtyRepository specialtyRepository, + PetTypeRepository petTypeRepository) { this.petRepository = petRepository; this.vetRepository = vetRepository; this.ownerRepository = ownerRepository; this.visitRepository = visitRepository; + this.specialtyRepository = specialtyRepository; + this.petTypeRepository = petTypeRepository; } - @Override - @Transactional(readOnly = true) - public Collection findPetTypes() throws DataAccessException { - return petRepository.findPetTypes(); - } + @Override + @Transactional(readOnly = true) + public Collection findAllPets() throws DataAccessException { + return petRepository.findAll(); + } - @Override - @Transactional(readOnly = true) - public Owner findOwnerById(int id) throws DataAccessException { - return ownerRepository.findById(id); - } + @Override + @Transactional + public void deletePet(Pet pet) throws DataAccessException { + petRepository.delete(pet); + } - @Override - @Transactional(readOnly = true) - public Collection findOwnerByLastName(String lastName) throws DataAccessException { - return ownerRepository.findByLastName(lastName); - } + @Override + @Transactional(readOnly = true) + public Visit findVisitById(int visitId) throws DataAccessException { + Visit visit = null; + try { + visit = visitRepository.findById(visitId); + } catch (ObjectRetrievalFailureException|EmptyResultDataAccessException e) { + // just ignore not found exceptions for Jdbc/Jpa realization + return null; + } + return visit; + } - @Override - @Transactional - public void saveOwner(Owner owner) throws DataAccessException { - ownerRepository.save(owner); - } + @Override + @Transactional(readOnly = true) + public Collection findAllVisits() throws DataAccessException { + return visitRepository.findAll(); + } + @Override + @Transactional + public void deleteVisit(Visit visit) throws DataAccessException { + visitRepository.delete(visit); + } - @Override - @Transactional - public void saveVisit(Visit visit) throws DataAccessException { - visitRepository.save(visit); - } + @Override + @Transactional(readOnly = true) + public Vet findVetById(int id) throws DataAccessException { + Vet vet = null; + try { + vet = vetRepository.findById(id); + } catch (ObjectRetrievalFailureException|EmptyResultDataAccessException e) { + // just ignore not found exceptions for Jdbc/Jpa realization + return null; + } + return vet; + } + @Override + @Transactional(readOnly = true) + public Collection findAllVets() throws DataAccessException { + return vetRepository.findAll(); + } - @Override - @Transactional(readOnly = true) - public Pet findPetById(int id) throws DataAccessException { - return petRepository.findById(id); - } + @Override + @Transactional + public void saveVet(Vet vet) throws DataAccessException { + vetRepository.save(vet); + } - @Override - @Transactional - public void savePet(Pet pet) throws DataAccessException { - petRepository.save(pet); - } + @Override + @Transactional + public void deleteVet(Vet vet) throws DataAccessException { + vetRepository.delete(vet); + } - @Override + @Override + @Transactional(readOnly = true) + public Collection findAllOwners() throws DataAccessException { + return ownerRepository.findAll(); + } + + @Override + @Transactional + public void deleteOwner(Owner owner) throws DataAccessException { + ownerRepository.delete(owner); + } + + @Override @Transactional(readOnly = true) - @Cacheable(value = "vets") - public Collection findVets() throws DataAccessException { - return vetRepository.findAll(); - } + public PetType findPetTypeById(int petTypeId) { + PetType petType = null; + try { + petType = petTypeRepository.findById(petTypeId); + } catch (ObjectRetrievalFailureException|EmptyResultDataAccessException e) { + // just ignore not found exceptions for Jdbc/Jpa realization + return null; + } + return petType; + } + + @Override + @Transactional(readOnly = true) + public Collection findAllPetTypes() throws DataAccessException { + return petTypeRepository.findAll(); + } @Override + @Transactional + public void savePetType(PetType petType) throws DataAccessException { + petTypeRepository.save(petType); + } + + @Override + @Transactional + public void deletePetType(PetType petType) throws DataAccessException { + petTypeRepository.delete(petType); + } + + @Override + @Transactional(readOnly = true) + public Specialty findSpecialtyById(int specialtyId) { + Specialty specialty = null; + try { + specialty = specialtyRepository.findById(specialtyId); + } catch (ObjectRetrievalFailureException|EmptyResultDataAccessException e) { + // just ignore not found exceptions for Jdbc/Jpa realization + return null; + } + return specialty; + } + + @Override + @Transactional(readOnly = true) + public Collection findAllSpecialties() throws DataAccessException { + return specialtyRepository.findAll(); + } + + @Override + @Transactional + public void saveSpecialty(Specialty specialty) throws DataAccessException { + specialtyRepository.save(specialty); + } + + @Override + @Transactional + public void deleteSpecialty(Specialty specialty) throws DataAccessException { + specialtyRepository.delete(specialty); + } + + @Override + @Transactional(readOnly = true) + public Collection findPetTypes() throws DataAccessException { + return petRepository.findPetTypes(); + } + + @Override + @Transactional(readOnly = true) + public Owner findOwnerById(int id) throws DataAccessException { + Owner owner = null; + try { + owner = ownerRepository.findById(id); + } catch (ObjectRetrievalFailureException|EmptyResultDataAccessException e) { + // just ignore not found exceptions for Jdbc/Jpa realization + return null; + } + return owner; + } + + @Override + @Transactional(readOnly = true) + public Pet findPetById(int id) throws DataAccessException { + Pet pet = null; + try { + pet = petRepository.findById(id); + } catch (ObjectRetrievalFailureException|EmptyResultDataAccessException e) { + // just ignore not found exceptions for Jdbc/Jpa realization + return null; + } + return pet; + } + + @Override + @Transactional + public void savePet(Pet pet) throws DataAccessException { + petRepository.save(pet); + } + + @Override + @Transactional + public void saveVisit(Visit visit) throws DataAccessException { + visitRepository.save(visit); + + } + + @Override + @Transactional(readOnly = true) + public Collection findVets() throws DataAccessException { + return vetRepository.findAll(); + } + + @Override + @Transactional + public void saveOwner(Owner owner) throws DataAccessException { + ownerRepository.save(owner); + + } + + @Override + @Transactional(readOnly = true) + public Collection findOwnerByLastName(String lastName) throws DataAccessException { + return ownerRepository.findByLastName(lastName); + } + + @Override + @Transactional(readOnly = true) public Collection findVisitsByPetId(int petId) { return visitRepository.findByPetId(petId); } + @Override + @Transactional(readOnly = true) + public List findSpecialtiesByNameIn(Set names){ + List specialties = new ArrayList<>(); + try { + specialties = specialtyRepository.findSpecialtiesByNameIn(names); + } catch (ObjectRetrievalFailureException|EmptyResultDataAccessException e) { + // just ignore not found exceptions for Jdbc/Jpa realization + return specialties; + } + return specialties; + } + @Override + @Transactional(readOnly = true) + public PetType findPetTypeByName(String name){ + PetType petType; + try { + petType = petTypeRepository.findByName(name); + } catch (ObjectRetrievalFailureException|EmptyResultDataAccessException e) { + // just ignore not found exceptions for Jdbc/Jpa realization + return null; + } + return petType; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/service/UserService.java b/src/main/java/org/springframework/samples/petclinic/service/UserService.java new file mode 100644 index 00000000..352605af --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/service/UserService.java @@ -0,0 +1,8 @@ +package org.springframework.samples.petclinic.service; + +import org.springframework.samples.petclinic.model.User; + +public interface UserService { + + void saveUser(User user) ; +} diff --git a/src/main/java/org/springframework/samples/petclinic/service/UserServiceImpl.java b/src/main/java/org/springframework/samples/petclinic/service/UserServiceImpl.java new file mode 100644 index 00000000..fb099e1e --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/service/UserServiceImpl.java @@ -0,0 +1,36 @@ +package org.springframework.samples.petclinic.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.model.User; +import org.springframework.samples.petclinic.model.Role; +import org.springframework.samples.petclinic.repository.UserRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class UserServiceImpl implements UserService { + + @Autowired + private UserRepository userRepository; + + @Override + @Transactional + public void saveUser(User user) { + + if(user.getRoles() == null || user.getRoles().isEmpty()) { + throw new IllegalArgumentException("User must have at least a role set!"); + } + + for (Role role : user.getRoles()) { + if(!role.getName().startsWith("ROLE_")) { + role.setName("ROLE_" + role.getName()); + } + + if(role.getUser() == null) { + role.setUser(user); + } + } + + userRepository.save(user); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/util/CallMonitoringAspect.java b/src/main/java/org/springframework/samples/petclinic/util/CallMonitoringAspect.java new file mode 100644 index 00000000..fddf17df --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/util/CallMonitoringAspect.java @@ -0,0 +1,97 @@ +/* + * Copyright 2002-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.util; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.jmx.export.annotation.ManagedAttribute; +import org.springframework.jmx.export.annotation.ManagedOperation; +import org.springframework.jmx.export.annotation.ManagedResource; +import org.springframework.util.StopWatch; + +/** + * Simple aspect that monitors call count and call invocation time. It uses JMX annotations and therefore can be + * monitored using any JMX console such as the jConsole + *

+ * This is only useful if you use JPA or JDBC. Spring-data-jpa doesn't have any correctly annotated classes to join on + * + * @author Rob Harrop + * @author Juergen Hoeller + * @author Michael Isvy + * @since 2.5 + */ +@ManagedResource("petclinic:type=CallMonitor") +@Aspect +public class CallMonitoringAspect { + + private boolean enabled = true; + + private int callCount = 0; + + private long accumulatedCallTime = 0; + + @ManagedAttribute + public boolean isEnabled() { + return enabled; + } + + @ManagedAttribute + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + @ManagedOperation + public void reset() { + this.callCount = 0; + this.accumulatedCallTime = 0; + } + + @ManagedAttribute + public int getCallCount() { + return callCount; + } + + @ManagedAttribute + public long getCallTime() { + if (this.callCount > 0) + return this.accumulatedCallTime / this.callCount; + else + return 0; + } + + + @Around("within(@org.springframework.stereotype.Repository *)") + public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable { + if (this.enabled) { + StopWatch sw = new StopWatch(joinPoint.toShortString()); + + sw.start("invoke"); + try { + return joinPoint.proceed(); + } finally { + sw.stop(); + synchronized (this) { + this.callCount++; + this.accumulatedCallTime += sw.getTotalTimeMillis(); + } + } + } else { + return joinPoint.proceed(); + } + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/web/CrashController.java b/src/main/java/org/springframework/samples/petclinic/web/CrashController.java deleted file mode 100644 index 29c55c1c..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/CrashController.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.samples.petclinic.web; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -/** - * Controller used to showcase what happens when an exception is thrown - * - * @author Michael Isvy - *

- * Also see how the bean of type 'SimpleMappingExceptionResolver' has been declared inside - * /WEB-INF/mvc-core-config.xml - */ -@Controller -public class CrashController { - - @RequestMapping(value = "/oups", method = RequestMethod.GET) - public String triggerException() { - throw new RuntimeException("Expected: controller used to showcase what " + - "happens when an exception is thrown"); - } - - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/web/OwnerController.java deleted file mode 100644 index dfc8d0b7..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/OwnerController.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.samples.petclinic.web; - -import java.util.Collection; -import java.util.Map; - -import javax.validation.Valid; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.validation.BindingResult; -import org.springframework.web.bind.WebDataBinder; -import org.springframework.web.bind.annotation.InitBinder; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -/** - * @author Juergen Hoeller - * @author Ken Krebs - * @author Arjen Poutsma - * @author Michael Isvy - */ -@Controller -public class OwnerController { - - private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm"; - private final ClinicService clinicService; - - - @Autowired - public OwnerController(ClinicService clinicService) { - this.clinicService = clinicService; - } - - @InitBinder - public void setAllowedFields(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } - - @RequestMapping(value = "/owners/new", method = RequestMethod.GET) - public String initCreationForm(Map model) { - Owner owner = new Owner(); - model.put("owner", owner); - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; - } - - @RequestMapping(value = "/owners/new", method = RequestMethod.POST) - public String processCreationForm(@Valid Owner owner, BindingResult result) { - if (result.hasErrors()) { - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; - } else { - this.clinicService.saveOwner(owner); - return "redirect:/owners/" + owner.getId(); - } - } - - @RequestMapping(value = "/owners/find", method = RequestMethod.GET) - public String initFindForm(Map model) { - model.put("owner", new Owner()); - return "owners/findOwners"; - } - - @RequestMapping(value = "/owners", method = RequestMethod.GET) - public String processFindForm(Owner owner, BindingResult result, Map model) { - - // allow parameterless GET request for /owners to return all records - if (owner.getLastName() == null) { - owner.setLastName(""); // empty string signifies broadest possible search - } - - // find owners by last name - Collection results = this.clinicService.findOwnerByLastName(owner.getLastName()); - if (results.isEmpty()) { - // no owners found - result.rejectValue("lastName", "notFound", "not found"); - return "owners/findOwners"; - } else if (results.size() == 1) { - // 1 owner found - owner = results.iterator().next(); - return "redirect:/owners/" + owner.getId(); - } else { - // multiple owners found - model.put("selections", results); - return "owners/ownersList"; - } - } - - @RequestMapping(value = "/owners/{ownerId}/edit", method = RequestMethod.GET) - public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) { - Owner owner = this.clinicService.findOwnerById(ownerId); - model.addAttribute(owner); - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; - } - - @RequestMapping(value = "/owners/{ownerId}/edit", method = RequestMethod.POST) - public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result, @PathVariable("ownerId") int ownerId) { - if (result.hasErrors()) { - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; - } else { - owner.setId(ownerId); - this.clinicService.saveOwner(owner); - return "redirect:/owners/{ownerId}"; - } - } - - /** - * Custom handler for displaying an owner. - * - * @param ownerId the ID of the owner to display - * @return a ModelMap with the model attributes for the view - */ - @RequestMapping("/owners/{ownerId}") - public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) { - ModelAndView mav = new ModelAndView("owners/ownerDetails"); - mav.addObject(this.clinicService.findOwnerById(ownerId)); - return mav; - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/PetController.java b/src/main/java/org/springframework/samples/petclinic/web/PetController.java deleted file mode 100644 index 6e2a59b9..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/PetController.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.samples.petclinic.web; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; -import org.springframework.util.StringUtils; -import org.springframework.validation.BindingResult; -import org.springframework.web.bind.WebDataBinder; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; - -import java.util.Collection; - -/** - * @author Juergen Hoeller - * @author Ken Krebs - * @author Arjen Poutsma - */ -@Controller -@RequestMapping("/owners/{ownerId}") -public class PetController { - - private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm"; - private final ClinicService clinicService; - - @Autowired - public PetController(ClinicService clinicService) { - this.clinicService = clinicService; - } - - @ModelAttribute("types") - public Collection populatePetTypes() { - return this.clinicService.findPetTypes(); - } - - @ModelAttribute("owner") - public Owner findOwner(@PathVariable("ownerId") int ownerId) { - return this.clinicService.findOwnerById(ownerId); - } - - @InitBinder("owner") - public void initOwnerBinder(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } - - @InitBinder("pet") - public void initPetBinder(WebDataBinder dataBinder) { - dataBinder.setValidator(new PetValidator()); - } - - @RequestMapping(value = "/pets/new", method = RequestMethod.GET) - public String initCreationForm(Owner owner, ModelMap model) { - Pet pet = new Pet(); - owner.addPet(pet); - model.put("pet", pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; - } - - @RequestMapping(value = "/pets/new", method = RequestMethod.POST) - public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) { - if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null){ - result.rejectValue("name", "duplicate", "already exists"); - } - if (result.hasErrors()) { - model.put("pet", pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; - } else { - owner.addPet(pet); - this.clinicService.savePet(pet); - return "redirect:/owners/{ownerId}"; - } - } - - @RequestMapping(value = "/pets/{petId}/edit", method = RequestMethod.GET) - public String initUpdateForm(@PathVariable("petId") int petId, ModelMap model) { - Pet pet = this.clinicService.findPetById(petId); - model.put("pet", pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; - } - - @RequestMapping(value = "/pets/{petId}/edit", method = RequestMethod.POST) - public String processUpdateForm(@Valid Pet pet, BindingResult result, Owner owner, ModelMap model) { - if (result.hasErrors()) { - model.put("pet", pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; - } else { - owner.addPet(pet); - this.clinicService.savePet(pet); - return "redirect:/owners/{ownerId}"; - } - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/PetTypeFormatter.java b/src/main/java/org/springframework/samples/petclinic/web/PetTypeFormatter.java deleted file mode 100644 index 71a060ca..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/PetTypeFormatter.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.samples.petclinic.web; - - -import java.text.ParseException; -import java.util.Collection; -import java.util.Locale; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.format.Formatter; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.stereotype.Component; - -/** - * Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting from Spring 3.0, Formatters have - * come as an improvement in comparison to legacy PropertyEditors. See the following links for more details: - The - * Spring ref doc: http://static.springsource.org/spring/docs/current/spring-framework-reference/html/validation.html#format-Formatter-SPI - * - A nice blog entry from Gordon Dickens: http://gordondickens.com/wordpress/2010/09/30/using-spring-3-0-custom-type-converter/ - *

- * Also see how the bean 'conversionService' has been declared inside /WEB-INF/mvc-core-config.xml - * - * @author Mark Fisher - * @author Juergen Hoeller - * @author Michael Isvy - */ -@Component -public class PetTypeFormatter implements Formatter { - - private final ClinicService clinicService; - - - @Autowired - public PetTypeFormatter(ClinicService clinicService) { - this.clinicService = clinicService; - } - - @Override - public String print(PetType petType, Locale locale) { - return petType.getName(); - } - - @Override - public PetType parse(String text, Locale locale) throws ParseException { - Collection findPetTypes = this.clinicService.findPetTypes(); - for (PetType type : findPetTypes) { - if (type.getName().equals(text)) { - return type; - } - } - throw new ParseException("type not found: " + text, 0); - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/PetValidator.java b/src/main/java/org/springframework/samples/petclinic/web/PetValidator.java deleted file mode 100644 index 3c04793b..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/PetValidator.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.samples.petclinic.web; - -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.util.StringUtils; -import org.springframework.validation.Errors; -import org.springframework.validation.Validator; - -/** - * Validator for Pet forms. - *

- * We're not using Bean Validation annotations here because it is easier to define such validation rule in Java. - *

- * - * @author Ken Krebs - * @author Juergen Hoeller - */ -public class PetValidator implements Validator { - - private static final String REQUIRED = "required"; - - @Override - public void validate(Object obj, Errors errors) { - Pet pet = (Pet) obj; - String name = pet.getName(); - // name validation - if (!StringUtils.hasLength(name)) { - errors.rejectValue("name", REQUIRED, REQUIRED); - } - - // type validation - if (pet.isNew() && pet.getType() == null) { - errors.rejectValue("type", REQUIRED, REQUIRED); - } - - // birth date validation - if (pet.getBirthDate() == null) { - errors.rejectValue("birthDate", REQUIRED, REQUIRED); - } - } - - /** - * This Validator validates *just* Pet instances - */ - @Override - public boolean supports(Class clazz) { - return Pet.class.isAssignableFrom(clazz); - } - - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/VetController.java b/src/main/java/org/springframework/samples/petclinic/web/VetController.java deleted file mode 100644 index 54baf395..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/VetController.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.samples.petclinic.web; - -import java.util.Map; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.samples.petclinic.model.Vets; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -/** - * @author Juergen Hoeller - * @author Mark Fisher - * @author Ken Krebs - * @author Arjen Poutsma - */ -@Controller -public class VetController { - - private final ClinicService clinicService; - - - @Autowired - public VetController(ClinicService clinicService) { - this.clinicService = clinicService; - } - - @RequestMapping(value = {"/vets.html"}) - public String showVetList(Map model) { - // Here we are returning an object of type 'Vets' rather than a collection of Vet objects - // so it is simpler for Object-Xml mapping - Vets vets = new Vets(); - vets.getVetList().addAll(this.clinicService.findVets()); - model.put("vets", vets); - return "vets/vetList"; - } - - @RequestMapping(value = {"/vets.json", "/vets.xml"}) - public - @ResponseBody - Vets showResourcesVetList() { - // Here we are returning an object of type 'Vets' rather than a collection of Vet objects - // so it is simpler for JSon/Object mapping - Vets vets = new Vets(); - vets.getVetList().addAll(this.clinicService.findVets()); - return vets; - } - - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/VisitController.java b/src/main/java/org/springframework/samples/petclinic/web/VisitController.java deleted file mode 100644 index 144eba2d..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/VisitController.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.samples.petclinic.web; - -import java.util.Map; - -import javax.validation.Valid; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.Visit; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.stereotype.Controller; -import org.springframework.validation.BindingResult; -import org.springframework.web.bind.WebDataBinder; -import org.springframework.web.bind.annotation.InitBinder; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -/** - * @author Juergen Hoeller - * @author Ken Krebs - * @author Arjen Poutsma - * @author Michael Isvy - */ -@Controller -public class VisitController { - - private final ClinicService clinicService; - - - @Autowired - public VisitController(ClinicService clinicService) { - this.clinicService = clinicService; - } - - @InitBinder - public void setAllowedFields(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } - - /** - * Called before each and every @RequestMapping annotated method. - * 2 goals: - * - Make sure we always have fresh data - * - Since we do not use the session scope, make sure that Pet object always has an id - * (Even though id is not part of the form fields) - * - * @param petId - * @return Pet - */ - @ModelAttribute("visit") - public Visit loadPetWithVisit(@PathVariable("petId") int petId) { - Pet pet = this.clinicService.findPetById(petId); - Visit visit = new Visit(); - pet.addVisit(visit); - return visit; - } - - // Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is called - @RequestMapping(value = "/owners/*/pets/{petId}/visits/new", method = RequestMethod.GET) - public String initNewVisitForm(@PathVariable("petId") int petId, Map model) { - return "pets/createOrUpdateVisitForm"; - } - - // Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called - @RequestMapping(value = "/owners/{ownerId}/pets/{petId}/visits/new", method = RequestMethod.POST) - public String processNewVisitForm(@Valid Visit visit, BindingResult result) { - if (result.hasErrors()) { - return "pets/createOrUpdateVisitForm"; - } else { - this.clinicService.saveVisit(visit); - return "redirect:/owners/{ownerId}"; - } - } - - @RequestMapping(value = "/owners/*/pets/{petId}/visits", method = RequestMethod.GET) - public String showVisits(@PathVariable int petId, Map model) { - model.put("visits", this.clinicService.findPetById(petId).getVisits()); - return "visitList"; - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/WelcomeController.java b/src/main/java/org/springframework/samples/petclinic/web/WelcomeController.java deleted file mode 100644 index efa9c323..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/WelcomeController.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.springframework.samples.petclinic.web; - - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; - -@Controller -public class WelcomeController { - - @RequestMapping("/") - public String welcome() { - return "welcome"; - } -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/api/AbstractResourceController.java b/src/main/java/org/springframework/samples/petclinic/web/api/AbstractResourceController.java deleted file mode 100644 index 9cc705cb..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/api/AbstractResourceController.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.springframework.samples.petclinic.web.api; - -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RequestMapping; - -@RequestMapping("/api") -@CrossOrigin -public class AbstractResourceController { - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/api/ApiExceptionHandler.java b/src/main/java/org/springframework/samples/petclinic/web/api/ApiExceptionHandler.java deleted file mode 100644 index 092a7cd4..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/api/ApiExceptionHandler.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.springframework.samples.petclinic.web.api; - -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.FieldError; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.context.request.WebRequest; -import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; - -@ControllerAdvice -public class ApiExceptionHandler extends ResponseEntityExceptionHandler { - private final Logger logger = LoggerFactory.getLogger(getClass()); - @ExceptionHandler({SuperFatalErrorException.class}) - public ResponseEntity badRequest(HttpServletRequest req, Exception exception) { - Map result = new Hashtable<>(); - result.put("status", HttpStatus.BAD_REQUEST); - result.put("message", exception.getMessage()); - return ResponseEntity.badRequest().body(result); - } - - /** - * Credits to: Willie Wheeler (http://springinpractice.com/2013/10/09/generating-json-error-object-responses-with-spring-web-mvc) - * - * @author Willie Wheeler (@williewheeler) - */ - @ExceptionHandler({ InvalidRequestException.class }) - protected ResponseEntity handleInvalidRequest(InvalidRequestException ire, WebRequest request) { - logger.info("InvalidRequestException caught", ire); - List fieldErrorResources = new ArrayList<>(); - - List fieldErrors = ire.getErrors().getFieldErrors(); - for (FieldError fieldError : fieldErrors) { - FieldErrorResource fieldErrorResource = new FieldErrorResource(); - fieldErrorResource.setResource(fieldError.getObjectName()); - fieldErrorResource.setField(fieldError.getField()); - fieldErrorResource.setCode(fieldError.getCode()); - fieldErrorResource.setMessage(fieldError.getDefaultMessage()); - fieldErrorResources.add(fieldErrorResource); - } - - ErrorResource error = new ErrorResource("InvalidRequest", ire.getMessage()); - error.setFieldErrors(fieldErrorResources); - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - - return handleExceptionInternal(ire, error, headers, HttpStatus.UNPROCESSABLE_ENTITY, request); - } - - @ExceptionHandler( { BadRequestException.class } ) - protected ResponseEntity handleBadRequest(BadRequestException bre, WebRequest request) { - logger.info("BadRequestException caught", bre); - - ErrorResource error = new ErrorResource("BadRequest", bre.getMessage()); - error.addGlobalError(bre.getMessage()); - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - - return handleExceptionInternal(bre, error, headers, HttpStatus.BAD_REQUEST, request); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/samples/petclinic/web/api/BadRequestException.java b/src/main/java/org/springframework/samples/petclinic/web/api/BadRequestException.java deleted file mode 100644 index 0f082499..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/api/BadRequestException.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.springframework.samples.petclinic.web.api; - -public class BadRequestException extends RuntimeException { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public BadRequestException(String message) { - super(message); - } - - - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/api/ErrorResource.java b/src/main/java/org/springframework/samples/petclinic/web/api/ErrorResource.java deleted file mode 100644 index d752841d..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/api/ErrorResource.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.springframework.samples.petclinic.web.api; -import java.util.Hashtable; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -/** - * Credits to: Willie Wheeler (http://springinpractice.com/2013/10/09/generating-json-error-object-responses-with-spring-web-mvc) - * - * @author Willie Wheeler (@williewheeler) - * @author Nils Hartmann - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class ErrorResource { - private String code; - private String message; - private List globalErrors; - private Map fieldErrors; - - public ErrorResource() { } - - public ErrorResource(String code, String message) { - this.code = code; - this.message = message; - } - - public String getCode() { return code; } - - public void setCode(String code) { this.code = code; } - - public String getMessage() { return message; } - - public void setMessage(String message) { this.message = message; } - - public Map getFieldErrors() { return fieldErrors; } - - public void setFieldErrors(List fieldErrors) { - this.fieldErrors = new LinkedHashMap<>(); - for (FieldErrorResource fieldErrorResource : fieldErrors) { - this.fieldErrors.put(fieldErrorResource.getField(), fieldErrorResource); - } - } - - public void addGlobalError(String message) { - if (globalErrors == null) { - globalErrors = new LinkedList(); - } - - globalErrors.add(message); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/samples/petclinic/web/api/FailingApiController.java b/src/main/java/org/springframework/samples/petclinic/web/api/FailingApiController.java deleted file mode 100644 index ee0d13d5..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/api/FailingApiController.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.springframework.samples.petclinic.web.api; - -import org.springframework.samples.petclinic.web.CrashController; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.RestController; - -/** -* Controller used to showcase what happens when an exception is thrown -* -* @author NilsHartmann -* @see CrashController -*/ -@RestController -public class FailingApiController extends AbstractResourceController { - - @GetMapping("/oups") - @ResponseBody - String failingRequest() { - throw new SuperFatalErrorException("Expected: controller used to showcase what " + - "happens when an exception is thrown"); - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/api/FieldErrorResource.java b/src/main/java/org/springframework/samples/petclinic/web/api/FieldErrorResource.java deleted file mode 100644 index 53c7b168..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/api/FieldErrorResource.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.springframework.samples.petclinic.web.api; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -/** - * Credits to: Willie Wheeler (http://springinpractice.com/2013/10/09/generating-json-error-object-responses-with-spring-web-mvc) - * - * @author Willie Wheeler (@williewheeler) - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class FieldErrorResource { - private String resource; - private String field; - private String code; - private String message; - - public String getResource() { - return resource; - } - - public void setResource(String resource) { - this.resource = resource; - } - - public String getField() { - return field; - } - - public void setField(String field) { - this.field = field; - } - - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/samples/petclinic/web/api/InvalidRequestException.java b/src/main/java/org/springframework/samples/petclinic/web/api/InvalidRequestException.java deleted file mode 100644 index e2d26f48..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/api/InvalidRequestException.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.springframework.samples.petclinic.web.api; - -import org.springframework.validation.Errors; - -/** - * Credits to: Willie Wheeler (http://springinpractice.com/2013/10/09/generating-json-error-object-responses-with-spring-web-mvc) - * - * @author Willie Wheeler (@williewheeler) - */ -public class InvalidRequestException extends RuntimeException { - /** - * - */ - private static final long serialVersionUID = 1L; - private Errors errors; - - public InvalidRequestException(String message, Errors errors) { - super(message); - this.errors = errors; - } - - public Errors getErrors() { - return errors; - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/api/OwnerResource.java b/src/main/java/org/springframework/samples/petclinic/web/api/OwnerResource.java deleted file mode 100755 index 74369307..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/api/OwnerResource.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.samples.petclinic.web.api; - -import java.util.Collection; - -import javax.validation.Valid; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; - -/** - * @author Juergen Hoeller - * @author Ken Krebs - * @author Arjen Poutsma - * @author Michael Isvy - */ -@RestController -public class OwnerResource extends AbstractResourceController { - - private final ClinicService clinicService; - - @Autowired - public OwnerResource(ClinicService clinicService) { - this.clinicService = clinicService; - } - - private Owner retrieveOwner(int ownerId) { - Owner owner = this.clinicService.findOwnerById(ownerId); - if (owner == null) { - throw new BadRequestException("Owner with Id '" + ownerId + "' is unknown."); - } - return owner; - } - - /** - * Create Owner - */ - @RequestMapping(value = "/owner", method = RequestMethod.POST) - @ResponseStatus(HttpStatus.CREATED) - public Owner createOwner(@RequestBody @Valid Owner owner, BindingResult bindingResult) { - if (bindingResult.hasErrors()) { - throw new InvalidRequestException("Invalid Owner", bindingResult); - } - - this.clinicService.saveOwner(owner); - - return owner; - } - - /** - * Read single Owner - */ - @RequestMapping(value = "/owner/{ownerId}", method = RequestMethod.GET) - public Owner findOwner(@PathVariable("ownerId") int ownerId) { - return retrieveOwner(ownerId); - } - - /** - * Read List of Owners - */ - @RequestMapping(value = "/owner/list", method = RequestMethod.GET) - public Collection findOwnerCollection(@RequestParam("lastName") String ownerLastName) { - - if (ownerLastName == null) { - ownerLastName = ""; - } - - return this.clinicService.findOwnerByLastName(ownerLastName); - } - - /** - * Update Owner - */ - @RequestMapping(value = "/owner/{ownerId}", method = RequestMethod.PUT) - public Owner updateOwner(@PathVariable("ownerId") int ownerId, @Valid @RequestBody Owner ownerRequest, - final BindingResult bindingResult) { - if (bindingResult.hasErrors()) { - throw new InvalidRequestException("Invalid Owner", bindingResult); - } - - Owner ownerModel = retrieveOwner(ownerId); - // This is done by hand for simplicity purpose. In a real life use-case we - // should consider using MapStruct. - ownerModel.setFirstName(ownerRequest.getFirstName()); - ownerModel.setLastName(ownerRequest.getLastName()); - ownerModel.setCity(ownerRequest.getCity()); - ownerModel.setAddress(ownerRequest.getAddress()); - ownerModel.setTelephone(ownerRequest.getTelephone()); - this.clinicService.saveOwner(ownerModel); - return ownerModel; - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/api/PetRequest.java b/src/main/java/org/springframework/samples/petclinic/web/api/PetRequest.java deleted file mode 100755 index 8f5010bc..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/api/PetRequest.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.springframework.samples.petclinic.web.api; - -import javax.validation.constraints.Min; -import javax.validation.constraints.Size; -import javax.validation.constraints.NotNull; - -import org.joda.time.LocalDate; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class PetRequest { - private Integer id; - @JsonFormat(pattern = "yyyy/MM/dd") - - @NotNull - private LocalDate birthDate; - @Size(min = 2, max = 14 ) - private String name; - - Integer typeId; - - - public LocalDate getBirthDate() { - return birthDate; - } - - public void setBirthDate(LocalDate birthDate) { - this.birthDate = birthDate; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getTypeId() { - return typeId; - } - - public void setTypeId(int typeId) { - this.typeId = typeId; - } - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - @JsonProperty("isNew") - public boolean isNew() { - return this.id == null; - } - - @Override - public String toString() { - return "PetRequest [id=" + id + ", birthDate=" + birthDate + ", name=" + name + ", typeId=" + typeId + "]"; - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/api/PetResource.java b/src/main/java/org/springframework/samples/petclinic/web/api/PetResource.java deleted file mode 100644 index 56797707..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/api/PetResource.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.samples.petclinic.web.api; - -import javax.validation.Valid; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; - -/** - * @author Nils Hartmann - */ -@RestController -public class PetResource extends AbstractResourceController { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private final ClinicService clinicService; - - @Autowired - public PetResource(ClinicService clinicService) { - this.clinicService = clinicService; - } - - @GetMapping("/pettypes") - Object getPetTypes() { - return clinicService.findPetTypes(); - } - - @PostMapping("/owners/{ownerId}/pets") - @ResponseStatus(HttpStatus.NO_CONTENT) - public void addNewPet(final @PathVariable("ownerId") int ownerId, final @Valid @RequestBody PetRequest petRequest, - final BindingResult bindingResult) { - - logger.info("PetRequest: {}", petRequest); - - if (bindingResult.hasErrors()) { - throw new InvalidRequestException("Submitted Pet invalid", bindingResult); - } - - Pet pet = new Pet(); - Owner owner = this.clinicService.findOwnerById(ownerId); - if (owner == null) { - throw new BadRequestException("Owner with Id '" + ownerId + "' is unknown."); - } - owner.addPet(pet); - - save(pet, petRequest); - } - - @PutMapping("/owners/{ownerId}/pets/{petId}") - @ResponseStatus(HttpStatus.NO_CONTENT) - public void processUpdateForm(final @PathVariable("petId") int petId, final @Valid @RequestBody PetRequest petRequest, final BindingResult bindingResult) { - - if (bindingResult.hasErrors()) { - throw new InvalidRequestException("Submitted Pet invalid", bindingResult); - } - - save(clinicService.findPetById(petId), petRequest); - } - - private void save(Pet pet, PetRequest petRequest) { - - pet.setName(petRequest.getName()); - pet.setBirthDate(petRequest.getBirthDate()); - - for (PetType petType : clinicService.findPetTypes()) { - if (petType.getId() == petRequest.getTypeId()) { - pet.setType(petType); - break; - } - } - - clinicService.savePet(pet); - } - - @GetMapping("/owners/*/pets/{petId}") - public PetRequest findPet(@PathVariable("petId") int petId) { - final Pet pet = this.clinicService.findPetById(petId); - - final PetRequest petRequest = new PetRequest(); - petRequest.setId(pet.getId()); - petRequest.setBirthDate(pet.getBirthDate()); - petRequest.setName(pet.getName()); - petRequest.setTypeId(pet.getType().getId()); - - return petRequest; - } - - // @Getter - // static class PetDetails { - // - // long id; - // String name; - // String owner; - // @DateTimeFormat(pattern = "yyyy-MM-dd") - // Date birthDate; - // PetType type; - // - // PetDetails(Pet pet) { - // this.id = pet.getId(); - // this.name = pet.getName(); - // this.owner = pet.getOwner().getFirstName() + " " + - // pet.getOwner().getLastName(); - // this.birthDate = pet.getBirthDate(); - // this.type = pet.getType(); - // } - // - // } - -} \ No newline at end of file diff --git a/src/main/java/org/springframework/samples/petclinic/web/api/SuperFatalErrorException.java b/src/main/java/org/springframework/samples/petclinic/web/api/SuperFatalErrorException.java deleted file mode 100644 index 8ad97760..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/api/SuperFatalErrorException.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.springframework.samples.petclinic.web.api; - -public class SuperFatalErrorException extends RuntimeException { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public SuperFatalErrorException(String message) { - super(message); - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/api/VetResource.java b/src/main/java/org/springframework/samples/petclinic/web/api/VetResource.java deleted file mode 100644 index 23893c88..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/api/VetResource.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.samples.petclinic.web.api; - -import java.util.Collection; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.samples.petclinic.model.Vet; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - */ -@RestController -public class VetResource extends AbstractResourceController { - - private final ClinicService clinicService; - - @Autowired - public VetResource(ClinicService clinicService) { - this.clinicService = clinicService; - } - - @GetMapping(value="/vets") - public Collection showResourcesVetList() { - return this.clinicService.findVets(); - } -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/api/VisitResource.java b/src/main/java/org/springframework/samples/petclinic/web/api/VisitResource.java deleted file mode 100755 index 3be999ff..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/api/VisitResource.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.samples.petclinic.web.api; - -import javax.validation.Valid; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.Visit; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; - -/** - * @author Juergen Hoeller - * @author Ken Krebs - * @author Arjen Poutsma - * @author Michael Isvy - */ -@RestController -public class VisitResource extends AbstractResourceController { - - private final ClinicService clinicService; - - @Autowired - public VisitResource(ClinicService clinicService) { - this.clinicService = clinicService; - } - - @PostMapping("/owners/{ownerId}/pets/{petId}/visits") - @ResponseStatus(HttpStatus.NO_CONTENT) - public void createÏ(@PathVariable("petId") int petId, @Valid @RequestBody Visit visit, BindingResult bindingResult) { - if (bindingResult.hasErrors()) { - throw new InvalidRequestException("Visit is invalid", bindingResult); - } - - final Pet pet = clinicService.findPetById(petId); - if (pet == null) { - throw new BadRequestException("Pet with Id '" + petId + "' is unknown."); - } - - pet.addVisit(visit); - - clinicService.saveVisit(visit); - } -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/api/petclinic.less b/src/main/java/org/springframework/samples/petclinic/web/api/petclinic.less deleted file mode 100644 index ebab7e18..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/api/petclinic.less +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2016 the original author or authors. - * - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -@import "../generated/META-INF/resources/webjars/bootstrap/3.3.6/less/bootstrap.less"; - -@icon-font-path: "../../webjars/bootstrap/3.3.6/fonts/"; - -@spring-green: #6db33f; -@spring-dark-green: #5fa134; -@spring-brown: #34302D; -@spring-grey: #838789; -@spring-light-grey: #f1f1f1; - -@body-bg: @spring-light-grey; -@text-color: @spring-brown; -@link-color: @spring-dark-green; -@link-hover-color: @spring-dark-green; - -@navbar-default-link-color: @spring-light-grey; -@navbar-default-link-active-color: @spring-light-grey; -@navbar-default-link-hover-color: @spring-light-grey; -@navbar-default-link-hover-bg: @spring-green; -@navbar-default-toggle-icon-bar-bg: @spring-light-grey; -@navbar-default-toggle-hover-bg: transparent; -@navbar-default-link-active-bg: @spring-green; - -@border-radius-base: 0; -@border-radius-large: 0; -@border-radius-small: 0; - -@btn-default-color: @spring-light-grey; -@btn-default-bg: @spring-brown; -@btn-default-border: @spring-green; - -@nav-tabs-active-link-hover-color: @spring-light-grey; -@nav-tabs-active-link-hover-bg: @spring-brown; -@nav-tabs-active-link-hover-border-color: @spring-brown; -@nav-tabs-border-color: @spring-brown; - -@pagination-active-bg: @spring-brown; -@pagination-active-border: @spring-green; -@table-border-color: @spring-brown; - -.table > thead > tr > th { - background-color: lighten(@spring-brown, 3%); - color: @spring-light-grey; -} - -.table-filter { - background-color: @spring-brown; - padding: 9px 12px; -} - -.nav > li > a { - color: @spring-grey; -} - -.btn-default { - border-width: 2px; - transition: border 0.15s; - -webkit-transition: border 0.15s; - -moz-transition: border 0.15s; - -o-transition: border 0.15s; - -ms-transition: border 0.15s; - - &:hover, - &:focus, - &:active, - &.active, - .open .dropdown-toggle& { - background-color: @spring-brown; - border-color: @spring-brown; - } -} - - -.container .text-muted { - margin: 20px 0; -} - -code { - font-size: 80%; -} - -.xd-container { - margin-top: 40px; - margin-bottom: 100px; - padding-left: 5px; - padding-right: 5px; -} - -h1 { - margin-bottom: 15px -} - -.index-page--subtitle { - font-size: 16px; - line-height: 24px; - margin: 0 0 30px; -} - -.form-horizontal button.btn-inverse { - margin-left: 32px; -} - -#job-params-modal .modal-dialog { - width: 90%; - margin-left:auto; - margin-right:auto; -} - -[ng-cloak].splash { - display: block !important; -} -[ng-cloak] { - display: none; -} - -.splash { - background: @spring-green; - color: @spring-brown; - display: none; -} - -.error-page { - margin-top: 100px; - text-align: center; -} - -.error-page .error-title { - font-size: 24px; - line-height: 24px; - margin: 30px 0 0; -} - -table td { - vertical-align: middle; -} - -table td .progress { - margin-bottom: 0; -} - -table td.action-column { - width: 1px; -} - -.help-block { - color: lighten(@text-color, 50%); // lighten the text some for contrast -} - -.xd-containers { - font-size: 15px; -} - -.cluster-view > table td { - vertical-align: top; -} - -.cluster-view .label, .cluster-view .column-block { - display: block; -} - -.cluster-view .input-group-addon { - width: 0%; -} - -.cluster-view { - margin-bottom: 0; -} - -.deployment-status-deployed { - .label-success; -} - -.deployment-status-incomplete { - .label-warning; -} - -.deployment-status-failed { - .label-danger; -} - -.deployment-status-deploying { - .label-info -} -.deployment-status-na { -} - -.container-details-table th { - background-color: lighten(@spring-brown, 3%); - color: @spring-light-grey; -} - -.status-help-content-table td { - color: @spring-brown; -} - -.alert-success { - .alert-variant(fade(@alert-success-bg, 70%); @alert-success-border; @alert-success-text); -} -.alert-info { - .alert-variant(fade(@alert-info-bg, 70%); @alert-info-border; @alert-info-text); -} -.alert-warning { - .alert-variant(fade(@alert-warning-bg, 70%); @alert-warning-border; @alert-warning-text); -} -.alert-danger { - .alert-variant(fade(@alert-danger-bg, 70%); @alert-danger-border; @alert-danger-text); -} - -.myspinner { - animation-name: spinner; - animation-duration: 2s; - animation-iteration-count: infinite; - animation-timing-function: linear; - - -webkit-transform-origin: 49% 50%; - -webkit-animation-name: spinner; - -webkit-animation-duration: 2s; - -webkit-animation-iteration-count: infinite; - -webkit-animation-timing-function: linear; -} - -hr { - border-top: 1px dotted @spring-brown; -} - -@import "typography.less"; -@import "header.less"; -@import "responsive.less"; diff --git a/src/main/java/org/springframework/samples/petclinic/web/package-info.java b/src/main/java/org/springframework/samples/petclinic/web/package-info.java deleted file mode 100644 index ca189f19..00000000 --- a/src/main/java/org/springframework/samples/petclinic/web/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * The classes in this package represent PetClinic's web presentation layer. - */ -package org.springframework.samples.petclinic.web; - diff --git a/src/main/resources/application-hsqldb.properties b/src/main/resources/application-hsqldb.properties new file mode 100644 index 00000000..5a915662 --- /dev/null +++ b/src/main/resources/application-hsqldb.properties @@ -0,0 +1,14 @@ +# HSQLDB config start +#---------------------------------------------------------------- + +spring.sql.init.schema-locations=classpath*:db/hsqldb/initDB.sql +spring.sql.init.data-locations=classpath*:db/hsqldb/populateDB.sql + +spring.datasource.url=jdbc:hsqldb:mem:petclinic +spring.datasource.username=sa +spring.datasource.password= +spring.jpa.database=HSQL +spring.jpa.database-platform=org.hibernate.dialect.HSQLDialect +spring.jpa.hibernate.ddl-auto=none +#---------------------------------------------------------------- +# HSQLDB config end diff --git a/src/main/resources/application-mysql.properties b/src/main/resources/application-mysql.properties new file mode 100644 index 00000000..daffa4ab --- /dev/null +++ b/src/main/resources/application-mysql.properties @@ -0,0 +1,16 @@ +# uncomment for init database (first start) +#spring.sql.init.mode=always +#spring.sql.init.schema-locations=classpath*:db/mysql/initDB.sql +#spring.sql.init.data-locations=classpath*:db/mysql/populateDB.sql + +# MySQL config start +#---------------------------------------------------------------- +spring.datasource.url = jdbc:mysql://localhost:3306/petclinic?useUnicode=true +spring.datasource.username=pc +spring.datasource.password=petclinic +spring.datasource.driver-class-name=com.mysql.jdbc.Driver +spring.jpa.database=MYSQL +spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect +spring.jpa.hibernate.ddl-auto=none +#---------------------------------------------------------------- +# MySQL config end diff --git a/src/main/resources/application-postgresql.properties b/src/main/resources/application-postgresql.properties new file mode 100644 index 00000000..456b590e --- /dev/null +++ b/src/main/resources/application-postgresql.properties @@ -0,0 +1,16 @@ +# uncomment for init database (first start) +#spring.sql.init.mode=always +#spring.sql.init.schema-locations=classpath*:db/postgresql/initDB.sql +#spring.sql.init.data-locations=classpath*:db/postgresql/populateDB.sql + +# PostgreSQL config start +#---------------------------------------------------------------- +spring.datasource.url=jdbc:postgresql://localhost:5432/petclinic +spring.datasource.username=postgres +spring.datasource.password=petclinic +spring.datasource.driver-class-name=org.postgresql.Driver +spring.jpa.database=POSTGRESQL +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect +spring.jpa.hibernate.ddl-auto=none +#---------------------------------------------------------------- +# PostgreSQL config end diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 55e21303..3c5cbfaf 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,25 +1,38 @@ -# database init, supports mysql too -database=hsqldb -spring.datasource.schema=classpath*:db/${database}/schema.sql -spring.datasource.data=classpath*:db/${database}/data.sql +# active profiles config +# +# application use two active profiles +# +# one - for select database +# ------------------------------------------------ +# When using HSQL, use: hsqldb +# When using MySQL, use: mysql +# When using PostgeSQL, use: postgresql +# ------------------------------------------------ +# +# one for select repository layer +# ------------------------------------------------ +# When using Spring jpa, use: jpa +# When using Spring JDBC, use: jdbc +# When using Spring Data JPA, use: spring-data-jpa +# ------------------------------------------------ -# Web -spring.mvc.view.prefix=/WEB-INF/jsp/ -spring.mvc.view.suffix=.jsp +spring.profiles.active=hsqldb,spring-data-jpa -# JPA -spring.jpa.hibernate.ddl-auto=none +# ------------------------------------------------ + +server.port=9966 +server.servlet.context-path=/petclinic/ -# Internationalization spring.messages.basename=messages/messages +spring.jpa.open-in-view=false -# Actuator / Management -management.contextPath=/manage +logging.level.org.springframework=DEBUG +#logging.level.org.springframework=DEBUG -# Logging -logging.level.org.springframework=INFO +#logging.level.org.hibernate.SQL=DEBUG +#logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE -# Active Spring profiles -spring.profiles.active=production +# enable the desired authentication type +# by default the authentication is disabled +petclinic.security.enable=false -spring.jackson.serialization.write_dates_as_timestamps=false diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt deleted file mode 100644 index 6225d120..00000000 --- a/src/main/resources/banner.txt +++ /dev/null @@ -1,15 +0,0 @@ - - - |\ _,,,--,,_ - /,`.-'`' ._ \-;;,_ - _______ __|,4- ) )_ .;.(__`'-'__ ___ __ _ ___ _______ - | | '---''(_/._)-'(_\_) | | | | | | | | | - | _ | ___|_ _| | | | | |_| | | | __ _ _ - | |_| | |___ | | | | | | | | | | \ \ \ \ - | ___| ___| | | | _| |___| | _ | | _| \ \ \ \ - | | | |___ | | | |_| | | | | | | |_ ) ) ) ) - |___| |_______| |___| |_______|_______|___|_| |__|___|_______| / / / / - ==================================================================/_/_/_/ - -:: Built with Spring Boot :: ${spring-boot.version} - diff --git a/src/main/resources/db/hsqldb/schema.sql b/src/main/resources/db/hsqldb/initDB.sql similarity index 78% rename from src/main/resources/db/hsqldb/schema.sql rename to src/main/resources/db/hsqldb/initDB.sql index f3c6947b..d14ecf3c 100644 --- a/src/main/resources/db/hsqldb/schema.sql +++ b/src/main/resources/db/hsqldb/initDB.sql @@ -5,6 +5,8 @@ DROP TABLE visits IF EXISTS; DROP TABLE pets IF EXISTS; DROP TABLE types IF EXISTS; DROP TABLE owners IF EXISTS; +DROP TABLE roles IF EXISTS; +DROP TABLE users IF EXISTS; CREATE TABLE vets ( @@ -62,3 +64,19 @@ CREATE TABLE visits ( ); ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets (id); CREATE INDEX visits_pet_id ON visits (pet_id); + +CREATE TABLE users ( + username VARCHAR(20) NOT NULL , + password VARCHAR(20) NOT NULL , + enabled BOOLEAN DEFAULT TRUE NOT NULL , + PRIMARY KEY (username) +); + +CREATE TABLE roles ( + id INTEGER IDENTITY PRIMARY KEY, + username VARCHAR(20) NOT NULL, + role VARCHAR(20) NOT NULL +); +ALTER TABLE roles ADD CONSTRAINT fk_username FOREIGN KEY (username) REFERENCES users (username); +CREATE INDEX fk_username_idx ON roles (username); + diff --git a/src/main/resources/db/hsqldb/data.sql b/src/main/resources/db/hsqldb/populateDB.sql similarity index 90% rename from src/main/resources/db/hsqldb/data.sql rename to src/main/resources/db/hsqldb/populateDB.sql index 16dda3e8..e5ee7b90 100644 --- a/src/main/resources/db/hsqldb/data.sql +++ b/src/main/resources/db/hsqldb/populateDB.sql @@ -51,3 +51,9 @@ INSERT INTO visits VALUES (1, 7, '2013-01-01', 'rabies shot'); INSERT INTO visits VALUES (2, 8, '2013-01-02', 'rabies shot'); INSERT INTO visits VALUES (3, 8, '2013-01-03', 'neutered'); INSERT INTO visits VALUES (4, 7, '2013-01-04', 'spayed'); + +INSERT INTO users(username,password,enabled) VALUES ('admin','{noop}admin', true); + +INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_OWNER_ADMIN'); +INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_VET_ADMIN'); +INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_ADMIN'); diff --git a/src/main/resources/db/mysql/schema.sql b/src/main/resources/db/mysql/initDB.sql similarity index 77% rename from src/main/resources/db/mysql/schema.sql rename to src/main/resources/db/mysql/initDB.sql index 6a982598..b7ab4c82 100644 --- a/src/main/resources/db/mysql/schema.sql +++ b/src/main/resources/db/mysql/initDB.sql @@ -63,3 +63,20 @@ CREATE TABLE IF NOT EXISTS visits ( description VARCHAR(255), FOREIGN KEY (pet_id) REFERENCES pets(id) ) engine=InnoDB; + +CREATE TABLE IF NOT EXISTS users ( + username VARCHAR(20) NOT NULL , + password VARCHAR(20) NOT NULL , + enabled TINYINT NOT NULL DEFAULT 1 , + PRIMARY KEY (username) +) engine=InnoDB; + +CREATE TABLE IF NOT EXISTS roles ( + id int(11) NOT NULL AUTO_INCREMENT, + username varchar(20) NOT NULL, + role varchar(20) NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY uni_username_role (role,username), + KEY fk_username_idx (username), + CONSTRAINT fk_username FOREIGN KEY (username) REFERENCES users (username) +) engine=InnoDB; diff --git a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt index 251562eb..49aa57e7 100644 --- a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt +++ b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt @@ -7,18 +7,14 @@ -------------------------------------------------------------------------------- -1) Download and install the MySQL database (e.g., MySQL Community Server 5.1.x), - which can be found here: http://dev.mysql.com/downloads/ +1) Download and install the MySQL database (e.g., MySQL Community Server 5.7.x), + which can be found here: http://dev.mysql.com/downloads/mysql/ + Alternatively, you may use the official MySQL docker image. Refer to the + README.md for the Docker command line. -2) Download Connector/J, the MySQL JDBC driver (e.g., Connector/J 5.1.x), which - can be found here: http://dev.mysql.com/downloads/connector/j/ - Copy the Connector/J JAR file (e.g., mysql-connector-java-5.1.5-bin.jar) into - the db/mysql directory. Alternatively, uncomment the mysql-connector from the - Petclinic pom. -3) Create the PetClinic database and user by executing the "db/mysql/initDB.sql" - script. - -4) Open "src/main/resources/spring/data-access.properties"; comment out all properties in the - "HSQL Settings" section; uncomment all properties in the "MySQL Settings" - section. +2) Create the PetClinic database and user by executing the "db/mysql/initDB.sql" +and "db/mysql/populateDB.sql" scripts. Or uncomment strings +#spring.datasource.schema=classpath*:db/mysql/initDB.sql +#spring.datasource.data=classpath*:db/mysql/populateDB.sql + in application-mysql.properties file at the first time you run the app. \ No newline at end of file diff --git a/src/main/resources/db/mysql/data.sql b/src/main/resources/db/mysql/populateDB.sql similarity index 90% rename from src/main/resources/db/mysql/data.sql rename to src/main/resources/db/mysql/populateDB.sql index 3f1dcf8e..0bbcf4a8 100644 --- a/src/main/resources/db/mysql/data.sql +++ b/src/main/resources/db/mysql/populateDB.sql @@ -51,3 +51,9 @@ INSERT IGNORE INTO visits VALUES (1, 7, '2010-03-04', 'rabies shot'); INSERT IGNORE INTO visits VALUES (2, 8, '2011-03-04', 'rabies shot'); INSERT IGNORE INTO visits VALUES (3, 8, '2009-06-04', 'neutered'); INSERT IGNORE INTO visits VALUES (4, 7, '2008-09-04', 'spayed'); + +INSERT IGNORE INTO users(username,password,enabled) VALUES ('admin','{noop}admin', true); + +INSERT IGNORE INTO roles (username, role) VALUES ('admin', 'ROLE_OWNER_ADMIN'); +INSERT IGNORE INTO roles (username, role) VALUES ('admin', 'ROLE_VET_ADMIN'); +INSERT IGNORE INTO roles (username, role) VALUES ('admin', 'ROLE_ADMIN'); diff --git a/src/main/resources/db/postgresql/initDB.sql b/src/main/resources/db/postgresql/initDB.sql new file mode 100644 index 00000000..49f997b7 --- /dev/null +++ b/src/main/resources/db/postgresql/initDB.sql @@ -0,0 +1,102 @@ +CREATE TABLE IF NOT EXISTS vets ( + id SERIAL, + first_name VARCHAR(30), + last_name VARCHAR(30), + CONSTRAINT pk_vets PRIMARY KEY (id) +); + +CREATE INDEX IF NOT EXISTS idx_vets_last_name ON vets (last_name); + +ALTER SEQUENCE vets_id_seq RESTART WITH 100; + + +CREATE TABLE IF NOT EXISTS specialties ( + id SERIAL, + name VARCHAR(80), + CONSTRAINT pk_specialties PRIMARY KEY (id) +); + +CREATE INDEX IF NOT EXISTS idx_specialties_name ON specialties (name); + +ALTER SEQUENCE specialties_id_seq RESTART WITH 100; + + +CREATE TABLE IF NOT EXISTS vet_specialties ( + vet_id INT NOT NULL, + specialty_id INT NOT NULL, + FOREIGN KEY (vet_id) REFERENCES vets(id), + FOREIGN KEY (specialty_id) REFERENCES specialties(id), + CONSTRAINT unique_ids UNIQUE (vet_id,specialty_id) +); + + + +CREATE TABLE IF NOT EXISTS types ( + id SERIAL, + name VARCHAR(80), + CONSTRAINT pk_types PRIMARY KEY (id) +); + +CREATE INDEX IF NOT EXISTS idx_types_name ON types (name); + +ALTER SEQUENCE types_id_seq RESTART WITH 100; + +CREATE TABLE IF NOT EXISTS owners ( + id SERIAL, + first_name VARCHAR(30), + last_name VARCHAR(30), + address VARCHAR(255), + city VARCHAR(80), + telephone VARCHAR(20), + CONSTRAINT pk_owners PRIMARY KEY (id) +); + +CREATE INDEX IF NOT EXISTS idx_owners_last_name ON owners (last_name); + +ALTER SEQUENCE owners_id_seq RESTART WITH 100; + + +CREATE TABLE IF NOT EXISTS pets ( + id SERIAL, + name VARCHAR(30), + birth_date DATE, + type_id INT NOT NULL, + owner_id INT NOT NULL, + FOREIGN KEY (owner_id) REFERENCES owners(id), + FOREIGN KEY (type_id) REFERENCES types(id), + CONSTRAINT pk_pets PRIMARY KEY (id) +); + +CREATE INDEX IF NOT EXISTS idx_pets_name ON pets (name); + +ALTER SEQUENCE pets_id_seq RESTART WITH 100; + + +CREATE TABLE IF NOT EXISTS visits ( + id SERIAL, + pet_id INT NOT NULL, + visit_date DATE, + description VARCHAR(255), + FOREIGN KEY (pet_id) REFERENCES pets(id), + CONSTRAINT pk_visits PRIMARY KEY (id) +); + +ALTER SEQUENCE visits_id_seq RESTART WITH 100; + +CREATE TABLE IF NOT EXISTS users ( + username VARCHAR(20) NOT NULL , + password VARCHAR(20) NOT NULL , + enabled boolean NOT NULL DEFAULT true , + CONSTRAINT pk_users PRIMARY KEY (username) +); + +CREATE TABLE IF NOT EXISTS roles ( + id SERIAL, + username varchar(20) NOT NULL, + role varchar(20) NOT NULL, + CONSTRAINT pk_roles PRIMARY KEY (id), + FOREIGN KEY (username) REFERENCES users (username) +); + +ALTER TABLE roles ADD CONSTRAINT uni_username_role UNIQUE (role,username); +ALTER SEQUENCE roles_id_seq RESTART WITH 100; diff --git a/src/main/resources/db/postgresql/petclinic_db_setup_postgresql.txt b/src/main/resources/db/postgresql/petclinic_db_setup_postgresql.txt new file mode 100644 index 00000000..e07e1ecc --- /dev/null +++ b/src/main/resources/db/postgresql/petclinic_db_setup_postgresql.txt @@ -0,0 +1,27 @@ +================================================================================ +=== Spring PetClinic sample application - PostgreSQL Configuration === +================================================================================ + +@author Vitaliy Fedoriv +@autor Antoine Rey + +-------------------------------------------------------------------------------- + +1) Download and install the PostgreSQL database, + which can be found here: https://www.postgresql.org/download/ + + +2) Open psql and create the PetClinic database: + + CREATE DATABASE petclinic + WITH OWNER = postgres + ENCODING = 'UTF8' + TABLESPACE = pg_default + CONNECTION LIMIT = -1; + +3) Create the PetClinic tables by executing the "db/postgresql/initDB.sql". +Then execute "db/mysql/populateDB.sql" script. +Or uncomment strings +#spring.datasource.schema=classpath*:db/postgresql/initDB.sql +#spring.datasource.data=classpath*:db/postgresql/populateDB.sql + in application-postgresql.properties file at the first time you run the app. \ No newline at end of file diff --git a/src/main/resources/db/postgresql/populateDB.sql b/src/main/resources/db/postgresql/populateDB.sql new file mode 100644 index 00000000..b1dfda8b --- /dev/null +++ b/src/main/resources/db/postgresql/populateDB.sql @@ -0,0 +1,59 @@ +INSERT INTO vets VALUES (1, 'James', 'Carter') ON CONFLICT DO NOTHING; +INSERT INTO vets VALUES (2, 'Helen', 'Leary') ON CONFLICT DO NOTHING; +INSERT INTO vets VALUES (3, 'Linda', 'Douglas') ON CONFLICT DO NOTHING; +INSERT INTO vets VALUES (4, 'Rafael', 'Ortega') ON CONFLICT DO NOTHING; +INSERT INTO vets VALUES (5, 'Henry', 'Stevens') ON CONFLICT DO NOTHING; +INSERT INTO vets VALUES (6, 'Sharon', 'Jenkins') ON CONFLICT DO NOTHING; + +INSERT INTO specialties VALUES (1, 'radiology') ON CONFLICT DO NOTHING; +INSERT INTO specialties VALUES (2, 'surgery') ON CONFLICT DO NOTHING; +INSERT INTO specialties VALUES (3, 'dentistry') ON CONFLICT DO NOTHING; + +INSERT INTO vet_specialties VALUES (2, 1) ON CONFLICT DO NOTHING; +INSERT INTO vet_specialties VALUES (3, 2) ON CONFLICT DO NOTHING; +INSERT INTO vet_specialties VALUES (3, 3) ON CONFLICT DO NOTHING; +INSERT INTO vet_specialties VALUES (4, 2) ON CONFLICT DO NOTHING; +INSERT INTO vet_specialties VALUES (5, 1) ON CONFLICT DO NOTHING; + +INSERT INTO types VALUES (1, 'cat') ON CONFLICT DO NOTHING; +INSERT INTO types VALUES (2, 'dog') ON CONFLICT DO NOTHING; +INSERT INTO types VALUES (3, 'lizard') ON CONFLICT DO NOTHING; +INSERT INTO types VALUES (4, 'snake') ON CONFLICT DO NOTHING; +INSERT INTO types VALUES (5, 'bird') ON CONFLICT DO NOTHING; +INSERT INTO types VALUES (6, 'hamster') ON CONFLICT DO NOTHING; + +INSERT INTO owners VALUES (1, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023') ON CONFLICT DO NOTHING; +INSERT INTO owners VALUES (2, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749') ON CONFLICT DO NOTHING; +INSERT INTO owners VALUES (3, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763') ON CONFLICT DO NOTHING; +INSERT INTO owners VALUES (4, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198') ON CONFLICT DO NOTHING; +INSERT INTO owners VALUES (5, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765') ON CONFLICT DO NOTHING; +INSERT INTO owners VALUES (6, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654') ON CONFLICT DO NOTHING; +INSERT INTO owners VALUES (7, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387') ON CONFLICT DO NOTHING; +INSERT INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683') ON CONFLICT DO NOTHING; +INSERT INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435') ON CONFLICT DO NOTHING; +INSERT INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487') ON CONFLICT DO NOTHING; + +INSERT INTO pets VALUES (1, 'Leo', '2000-09-07', 1, 1) ON CONFLICT DO NOTHING; +INSERT INTO pets VALUES (2, 'Basil', '2002-08-06', 6, 2) ON CONFLICT DO NOTHING; +INSERT INTO pets VALUES (3, 'Rosy', '2001-04-17', 2, 3) ON CONFLICT DO NOTHING; +INSERT INTO pets VALUES (4, 'Jewel', '2000-03-07', 2, 3) ON CONFLICT DO NOTHING; +INSERT INTO pets VALUES (5, 'Iggy', '2000-11-30', 3, 4) ON CONFLICT DO NOTHING; +INSERT INTO pets VALUES (6, 'George', '2000-01-20', 4, 5) ON CONFLICT DO NOTHING; +INSERT INTO pets VALUES (7, 'Samantha', '1995-09-04', 1, 6) ON CONFLICT DO NOTHING; +INSERT INTO pets VALUES (8, 'Max', '1995-09-04', 1, 6) ON CONFLICT DO NOTHING; +INSERT INTO pets VALUES (9, 'Lucky', '1999-08-06', 5, 7) ON CONFLICT DO NOTHING; +INSERT INTO pets VALUES (10, 'Mulligan', '1997-02-24', 2, 8) ON CONFLICT DO NOTHING; +INSERT INTO pets VALUES (11, 'Freddy', '2000-03-09', 5, 9) ON CONFLICT DO NOTHING; +INSERT INTO pets VALUES (12, 'Lucky', '2000-06-24', 2, 10) ON CONFLICT DO NOTHING; +INSERT INTO pets VALUES (13, 'Sly', '2002-06-08', 1, 10) ON CONFLICT DO NOTHING; + +INSERT INTO visits VALUES (1, 7, '2010-03-04', 'rabies shot') ON CONFLICT DO NOTHING; +INSERT INTO visits VALUES (2, 8, '2011-03-04', 'rabies shot') ON CONFLICT DO NOTHING; +INSERT INTO visits VALUES (3, 8, '2009-06-04', 'neutered') ON CONFLICT DO NOTHING; +INSERT INTO visits VALUES (4, 7, '2008-09-04', 'spayed') ON CONFLICT DO NOTHING; + +INSERT INTO users(username,password,enabled) VALUES ('admin','{noop}admin', true) ON CONFLICT DO NOTHING; + +INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_OWNER_ADMIN') ON CONFLICT DO NOTHING; +INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_VET_ADMIN') ON CONFLICT DO NOTHING; +INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_ADMIN') ON CONFLICT DO NOTHING; diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 00000000..54bfd5f2 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,22 @@ + + + + + + + true + + + + + %-5level %logger{0} - %msg%n + + + + + + + + + + diff --git a/src/main/resources/openapi.yml b/src/main/resources/openapi.yml new file mode 100644 index 00000000..c49fe496 --- /dev/null +++ b/src/main/resources/openapi.yml @@ -0,0 +1,2221 @@ +openapi: 3.0.1 +info: + title: Spring PetClinic + description: Spring PetClinic Sample Application. + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0 + version: '1.0' +servers: + - url: http://localhost:9966/petclinic/api +tags: + - name: failing + description: Endpoint which always returns an error. + - name: owner + description: Endpoints related to pet owners. + - name: user + description: Endpoints related to users. + - name: pet + description: Endpoints related to pets. + - name: vet + description: Endpoints related to vets. + - name: visit + description: Endpoints related to vet visits. + - name: pettypes + description: Endpoints related to pet types. + - name: specialty + description: Endpoints related to vet specialties. +paths: + /oops: + get: + tags: + - failing + operationId: failingRequest + summary: Always fails + description: Produces sample error response. + responses: + 200: + description: Never returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + text/plain: + schema: + type: string + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /owners: + post: + tags: + - owner + operationId: addOwner + summary: Adds a pet owner + description: Records the details of a new pet owner. + requestBody: + description: The pet owner + content: + application/json: + schema: + $ref: '#/components/schemas/OwnerFields' + required: true + responses: + 201: + description: The pet owner was sucessfully added. + content: + application/json: + schema: + $ref: '#/components/schemas/Owner' + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + get: + tags: + - owner + operationId: listOwners + summary: Lists pet owners + description: Returns an array of pet owners. + parameters: + - name: lastName + in: query + description: Last name. + required: false + schema: + type: string + example: Davis + responses: + 200: + description: Owner details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Owner' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /owners/{ownerId}: + get: + tags: + - owner + operationId: getOwner + summary: Get a pet owner by ID + description: Returns the pet owner or a 404 error. + parameters: + - name: ownerId + in: path + description: The ID of the pet owner. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + responses: + 200: + description: Owner details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Owner' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Owner not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + put: + tags: + - owner + operationId: updateOwner + summary: Update a pet owner's details + description: Updates the pet owner record with the specified details. + parameters: + - name: ownerId + in: path + description: The ID of the pet owner. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + requestBody: + description: The pet owner details to use for the update. + content: + application/json: + schema: + $ref: '#/components/schemas/OwnerFields' + required: true + responses: + 200: + description: Update successful. + content: + application/json: + schema: + $ref: '#/components/schemas/Owner' + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Owner not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + + delete: + tags: + - owner + operationId: deleteOwner + summary: Delete an owner by ID + description: Returns the owner or a 404 error. + parameters: + - name: ownerId + in: path + description: The ID of the owner. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + responses: + 200: + description: Owner details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Owner' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Owner not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /owners/{ownerId}/pets: + post: + tags: + - pet + operationId: addPetToOwner + summary: Adds a pet to an owner + description: Records the details of a new pet. + parameters: + - name: ownerId + in: path + description: The ID of the pet owner. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + requestBody: + description: The details of the new pet. + content: + application/json: + schema: + $ref: '#/components/schemas/PetFields' + required: true + responses: + 201: + description: The pet was sucessfully added. + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Pet not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /owners/{ownerId}/pets/{petId}: + get: + tags: + - pet + operationId: getOwnersPet + summary: Get a pet by ID + description: Returns the pet or a 404 error. + parameters: + - name: ownerId + in: path + description: The ID of the pet owner. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + - name: petId + in: path + description: The ID of the pet. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + responses: + 200: + description: Pet details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Pet not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + put: + tags: + - pet + operationId: updateOwnersPet + + summary: Update a pet's details + description: Updates the pet record with the specified details. + parameters: + - name: ownerId + in: path + description: The ID of the pet owner. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + - name: petId + in: path + description: The ID of the pet. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + requestBody: + description: The pet details to use for the update. + content: + application/json: + schema: + $ref: '#/components/schemas/PetFields' + required: true + responses: + 204: + description: Update successful. + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Pet not found for this owner. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /owners/{ownerId}/pets/{petId}/visits: + post: + tags: + - visit + operationId: addVisitToOwner + summary: Adds a vet visit + description: Records the details of a new vet visit. + parameters: + - name: ownerId + in: path + description: The ID of the pet owner. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + - name: petId + in: path + description: The ID of the pet. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + requestBody: + description: The details of the new vet visit. + content: + application/json: + schema: + $ref: '#/components/schemas/VisitFields' + required: true + responses: + 201: + description: The vet visit was sucessfully added. + content: + application/json: + schema: + $ref: '#/components/schemas/Visit' + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Pet not found for this owner. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /pettypes: + get: + tags: + - pettypes + operationId: listPetTypes + summary: Lists pet types + description: Returns an array of pet types. + responses: + 200: + description: Pet types found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/PetType' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + post: + tags: + - pettypes + operationId: addPetType + summary: Create a pet type + description: Creates a pet type . + requestBody: + description: The pet type + content: + application/json: + schema: + $ref: '#/components/schemas/PetType' + required: true + responses: + 200: + description: Pet type created successfully. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/PetType' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Pet Type not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /pettypes/{petTypeId}: + get: + tags: + - pettypes + operationId: getPetType + summary: Get a pet type by ID + description: Returns the pet type or a 404 error. + parameters: + - name: petTypeId + in: path + description: The ID of the pet type. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + responses: + 200: + description: Pet type details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/PetType' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Pet Type not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + put: + tags: + - pettypes + operationId: updatePetType + summary: Update a pet type by ID + description: Returns the pet type or a 404 error. + parameters: + - name: petTypeId + in: path + description: The ID of the pet type. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + requestBody: + description: The pet type + content: + application/json: + schema: + $ref: '#/components/schemas/PetType' + required: true + responses: + 200: + description: Pet type details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/PetType' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Pet Type not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + delete: + tags: + - pettypes + operationId: deletePetType + summary: Delete a pet type by ID + description: Returns the pet type or a 404 error. + parameters: + - name: petTypeId + in: path + description: The ID of the pet type. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + responses: + 200: + description: Pet type details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/PetType' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Pet type not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + + /pets: + get: + tags: + - pet + operationId: listPets + summary: Lists pet + description: Returns an array of pet . + responses: + 200: + description: Pet types found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + post: + tags: + - pet + operationId: addPet + summary: Create a pet + description: Creates a pet . + requestBody: + description: The pet + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + required: true + responses: + 200: + description: Pet type created successfully. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Pet not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /pets/{petId}: + get: + tags: + - pet + operationId: getPet + summary: Get a pet by ID + description: Returns the pet or a 404 error. + parameters: + - name: petId + in: path + description: The ID of the pet. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + responses: + 200: + description: Pet details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Pet not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + put: + tags: + - pet + operationId: updatePet + summary: Update a pet by ID + description: Returns the pet or a 404 error. + parameters: + - name: petId + in: path + description: The ID of the pet. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + requestBody: + description: The pet + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + required: true + responses: + 200: + description: Pet details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Pet not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + delete: + tags: + - pet + operationId: deletePet + summary: Delete a pet by ID + description: Returns the pet or a 404 error. + parameters: + - name: petId + in: path + description: The ID of the pet. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + responses: + 200: + description: Pet details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Pet not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /visits: + get: + tags: + - visit + operationId: listVisits + summary: Lists visits + description: Returns an array of visit . + responses: + 200: + description: visits found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Visit' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + post: + tags: + - visit + operationId: addVisit + summary: Create a visit + description: Creates a visit. + requestBody: + description: The visit + content: + application/json: + schema: + $ref: '#/components/schemas/Visit' + required: true + responses: + 200: + description: visit created successfully. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Visit' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Visit not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /visits/{visitId}: + get: + tags: + - visit + operationId: getVisit + summary: Get a visit by ID + description: Returns the visit or a 404 error. + parameters: + - name: visitId + in: path + description: The ID of the visit. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + responses: + 200: + description: Visit details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Visit' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Visit not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + put: + tags: + - visit + operationId: updateVisit + summary: Update a visit by ID + description: Returns the visit or a 404 error. + parameters: + - name: visitId + in: path + description: The ID of the visit. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + requestBody: + description: The visit + content: + application/json: + schema: + $ref: '#/components/schemas/Visit' + required: true + responses: + 200: + description: Visit details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Visit' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Visit not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + delete: + tags: + - visit + operationId: deleteVisit + summary: Delete a visit by ID + description: Returns the visit or a 404 error. + parameters: + - name: visitId + in: path + description: The ID of the visit. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + responses: + 200: + description: Visit details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Visit' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Visit not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /specialties: + get: + tags: + - specialty + operationId: listSpecialties + summary: Lists specialties + description: Returns an array of specialty . + responses: + 200: + description: Specialties found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Specialty' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + post: + tags: + - specialty + operationId: addSpecialty + summary: Create a specialty + description: Creates a specialty . + requestBody: + description: The specialty + content: + application/json: + schema: + $ref: '#/components/schemas/Specialty' + required: true + responses: + 200: + description: Specialty created successfully. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Specialty' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Specialty not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /specialties/{specialtyId}: + get: + tags: + - specialty + operationId: getSpecialty + summary: Get a specialty by ID + description: Returns the specialty or a 404 error. + parameters: + - name: specialtyId + in: path + description: The ID of the speciality. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + responses: + 200: + description: Specialty details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Specialty' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Specialty not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + put: + tags: + - specialty + operationId: updateSpecialty + summary: Update a specialty by ID + description: Returns the specialty or a 404 error. + parameters: + - name: specialtyId + in: path + description: The ID of the specialty. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + requestBody: + description: The pet + content: + application/json: + schema: + $ref: '#/components/schemas/Specialty' + required: true + responses: + 200: + description: Specialty details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Specialty' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Specialty not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + delete: + tags: + - specialty + operationId: deleteSpecialty + summary: Delete a specialty by ID + description: Returns the specialty or a 404 error. + parameters: + - name: specialtyId + in: path + description: The ID of the specialty. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + responses: + 200: + description: Specialty details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Specialty' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Specialty not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /vets: + get: + tags: + - vet + operationId: listVets + summary: Lists vets + description: Returns an array of vets. + responses: + 200: + description: Vets found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Vet' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + + post: + tags: + - vet + operationId: addVet + summary: Create a Vet + description: Creates a vet . + requestBody: + description: The vet + content: + application/json: + schema: + $ref: '#/components/schemas/Vet' + required: true + responses: + 200: + description: Vet created successfully. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Vet' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Vet not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /vets/{vetId}: + get: + tags: + - vet + operationId: getVet + summary: Get a vet by ID + description: Returns the vet or a 404 error. + parameters: + - name: vetId + in: path + description: The ID of the vet. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + responses: + 200: + description: Vet details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Vet' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Vet not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + put: + tags: + - vet + operationId: updateVet + summary: Update a vet by ID + description: Returns the vet or a 404 error. + parameters: + - name: vetId + in: path + description: The ID of the vet. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + requestBody: + description: The vet + content: + application/json: + schema: + $ref: '#/components/schemas/Vet' + required: true + responses: + 200: + description: Pet type details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Vet' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Vet not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + delete: + tags: + - vet + operationId: deleteVet + summary: Delete a vet by ID + description: Returns the vet or a 404 error. + parameters: + - name: vetId + in: path + description: The ID of the vet. + required: true + schema: + type: integer + format: int32 + minimum: 0 + example: 1 + responses: + 200: + description: Vet details found and returned. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/Vet' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: Vet not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + /users: + post: + tags: + - user + operationId: addUser + summary: Create a user + description: Creates a user. + requestBody: + description: The user + content: + application/json: + schema: + $ref: '#/components/schemas/User' + required: true + responses: + 200: + description: User created successfully. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/User' + 304: + description: Not modified. + headers: + ETag: + description: An ID for this version of the response. + schema: + type: string + 400: + description: Bad request. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 404: + description: User not found. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' + 500: + description: Server error. + content: + application/json: + schema: + $ref: '#/components/schemas/RestError' +components: + schemas: + RestError: + title: REST Error + description: The schema for all error responses. + type: object + properties: + status: + title: Status + description: The HTTP status code. + type: integer + format: int32 + example: 400 + readOnly: true + error: + title: Error + description: The short error message. + type: string + example: Bad Request + readOnly: true + path: + title: Path + description: The path of the URL for this request. + type: string + format: uri + example: '/api/owners' + readOnly: true + timestamp: + title: Timestamp + description: The time the error occured. + type: string + format: date-time + example: '2019-08-21T21:41:46.158+0000' + readOnly: true + message: + title: Message + description: The long error message. + type: string + example: 'Request failed schema validation' + readOnly: true + schemaValidationErrors: + title: Schema validation errors + description: Validation errors against the OpenAPI schema. + type: array + items: + $ref: '#/components/schemas/ValidationMessage' + trace: + title: Trace + description: The stacktrace for this error. + type: string + example: 'com.atlassian.oai.validator.springmvc.InvalidRequestException: ...' + readOnly: true + required: + - status + - error + - path + - timestamp + - message + - schemaValidationErrors + ValidationMessage: + title: Validation message + description: Messages describing a validation error. + type: object + properties: + message: + title: Message + description: The valiation message. + type: string + example: "[Path '/lastName'] Instance type (null) does not match any allowed primitive type (allowed: [\"string\"])" + readOnly: true + required: + - message + additionalProperties: true + Specialty: + title: Specialty + description: Fields of specialty of vets. + type: object + properties: + id: + title: ID + description: The ID of the specialty. + type: integer + format: int32 + minimum: 0 + example: 1 + readOnly: true + name: + title: Name + description: The name of the specialty. + type: string + maxLength: 80 + minLength: 1 + example: radiology + required: + - id + - name + OwnerFields: + title: Owner fields + description: Editable fields of a pet owner. + type: object + properties: + firstName: + title: First name + description: The first name of the pet owner. + type: string + minLength: 1 + maxLength: 30 + pattern: '^[a-zA-Z]*$' + example: George + lastName: + title: Last name + description: The last name of the pet owner. + type: string + minLength: 1 + maxLength: 30 + pattern: '^[a-zA-Z]*$' + example: Franklin + address: + title: Address + description: The postal address of the pet owner. + type: string + minLength: 1 + maxLength: 255 + example: '110 W. Liberty St.' + city: + title: City + description: The city of the pet owner. + type: string + minLength: 1 + maxLength: 80 + example: Madison + telephone: + title: Telephone number + description: The telephone number of the pet owner. + type: string + minLength: 1 + maxLength: 20 + pattern: '^[0-9]*$' + example: '6085551023' + required: + - firstName + - lastName + - address + - city + - telephone + Owner: + title: Owner + description: A pet owner. + allOf: + - $ref: '#/components/schemas/OwnerFields' + - type: object + properties: + id: + title: ID + description: The ID of the pet owner. + type: integer + format: int32 + minimum: 0 + example: 1 + readOnly: true + pets: + title: Pets + description: The pets owned by this individual including any booked vet visits. + type: array + items: + $ref: '#/components/schemas/Pet' + readOnly: true + required: + - pets + PetFields: + title: Pet fields + description: Editable fields of a pet. + type: object + properties: + name: + title: Name + description: The name of the pet. + type: string + maxLength: 30 + example: Leo + birthDate: + title: Birth date + description: The date of birth of the pet. + type: string + format: date + example: '2010-09-07' + type: + $ref: '#/components/schemas/PetType' + required: + - name + - birthDate + - type + Pet: + title: Pet + description: A pet. + allOf: + - $ref: '#/components/schemas/PetFields' + - type: object + properties: + id: + title: ID + description: The ID of the pet. + type: integer + format: int32 + minimum: 0 + example: 1 + readOnly: true + ownerId: + title: Owner ID + description: The ID of the pet's owner. + type: integer + format: int32 + minimum: 0 + example: 1 + readOnly: true + visits: + title: Visits + description: Vet visit bookings for this pet. + type: array + items: + $ref: '#/components/schemas/Visit' + readOnly: true + required: + - id + - type + - visits + VetFields: + title: VetFields + description: Editable fields of a veterinarian. + type: object + properties: + firstName: + title: First name + description: The first name of the vet. + type: string + minLength: 1 + maxLength: 30 + pattern: '^[a-zA-Z]*$' + example: 'James' + lastName: + title: Last name + description: The last name of the vet. + type: string + minLength: 1 + maxLength: 30 + pattern: '^[a-zA-Z]*$' + example: 'Carter' + specialties: + title: Specialties + description: The specialties of the vet. + type: array + items: + $ref: '#/components/schemas/Specialty' + required: + - firstName + - lastName + - specialties + Vet: + title: Vet + description: A veterinarian. + allOf: + - $ref: '#/components/schemas/VetFields' + - type: object + properties: + id: + title: ID + description: The ID of the vet. + type: integer + format: int32 + minimum: 0 + example: 1 + readOnly: true + required: + - id + - firstName + - lastName + - specialties + VisitFields: + title: Visit fields + description: Editable fields of a vet visit. + type: object + properties: + date: + title: Date + description: The date of the visit. + type: string + format: date + example: '2013-01-01' + description: + title: Description + description: The description for the visit. + type: string + minLength: 1 + maxLength: 255 + example: 'rabies shot' + required: + - description + Visit: + title: Visit + description: A booking for a vet visit. + allOf: + - $ref: '#/components/schemas/VisitFields' + - type: object + properties: + id: + title: ID + description: The ID of the visit. + type: integer + format: int32 + minimum: 0 + example: 1 + readOnly: true + petId: + title: Pet ID + description: The ID of the pet. + type: integer + format: int32 + minimum: 0 + example: 1 + readOnly: true + required: + - id + PetTypeFields: + title: PetType fields + description: Editable fields of a pet type. + type: object + properties: + name: + title: Name + description: The name of the pet type. + type: string + maxLength: 80 + minLength: 1 + example: cat + required: + - name + PetType: + title: Pet type + description: A pet type. + allOf: + - $ref: '#/components/schemas/PetTypeFields' + - type: object + properties: + id: + title: ID + description: The ID of the pet type. + type: integer + format: int32 + minimum: 0 + example: 1 + readOnly: true + required: + - id + User: + title: User + description: An user. + type: object + properties: + username: + title: username + description: The username + type: string + maxLength: 80 + minLength: 1 + example: john.doe + password: + title: Password + description: The password + type: string + maxLength: 80 + minLength: 1 + example: 1234abc + enabled: + title: enabled + description: Indicates if the user is enabled + type: boolean + example: true + roles: + title: Roles + description: The roles of an user + type: array + items: + $ref: '#/components/schemas/Role' + required: + - username + Role: + title: Role + description: A role. + type: object + properties: + name: + title: name + description: The role's name + type: string + maxLength: 80 + minLength: 1 + example: admin + required: + - name diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/alerts.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/alerts.less deleted file mode 100644 index c4199db9..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/alerts.less +++ /dev/null @@ -1,73 +0,0 @@ -// -// Alerts -// -------------------------------------------------- - - -// Base styles -// ------------------------- - -.alert { - padding: @alert-padding; - margin-bottom: @line-height-computed; - border: 1px solid transparent; - border-radius: @alert-border-radius; - - // Headings for larger alerts - h4 { - margin-top: 0; - // Specified for the h4 to prevent conflicts of changing @headings-color - color: inherit; - } - - // Provide class for links that match alerts - .alert-link { - font-weight: @alert-link-font-weight; - } - - // Improve alignment and spacing of inner content - > p, - > ul { - margin-bottom: 0; - } - - > p + p { - margin-top: 5px; - } -} - -// Dismissible alerts -// -// Expand the right padding and account for the close button's positioning. - -.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0. -.alert-dismissible { - padding-right: (@alert-padding + 20); - - // Adjust close link position - .close { - position: relative; - top: -2px; - right: -21px; - color: inherit; - } -} - -// Alternate styles -// -// Generate contextual modifier classes for colorizing the alert. - -.alert-success { - .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text); -} - -.alert-info { - .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text); -} - -.alert-warning { - .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text); -} - -.alert-danger { - .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text); -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/badges.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/badges.less deleted file mode 100644 index 6ee16dca..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/badges.less +++ /dev/null @@ -1,66 +0,0 @@ -// -// Badges -// -------------------------------------------------- - - -// Base class -.badge { - display: inline-block; - min-width: 10px; - padding: 3px 7px; - font-size: @font-size-small; - font-weight: @badge-font-weight; - color: @badge-color; - line-height: @badge-line-height; - vertical-align: middle; - white-space: nowrap; - text-align: center; - background-color: @badge-bg; - border-radius: @badge-border-radius; - - // Empty badges collapse automatically (not available in IE8) - &:empty { - display: none; - } - - // Quick fix for badges in buttons - .btn & { - position: relative; - top: -1px; - } - - .btn-xs &, - .btn-group-xs > .btn & { - top: 0; - padding: 1px 5px; - } - - // Hover state, but only for links - a& { - &:hover, - &:focus { - color: @badge-link-hover-color; - text-decoration: none; - cursor: pointer; - } - } - - // Account for badges in navs - .list-group-item.active > &, - .nav-pills > .active > a > & { - color: @badge-active-color; - background-color: @badge-active-bg; - } - - .list-group-item > & { - float: right; - } - - .list-group-item > & + & { - margin-right: 5px; - } - - .nav-pills > li > a > & { - margin-left: 3px; - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/bootstrap.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/bootstrap.less deleted file mode 100644 index 1c047780..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/bootstrap.less +++ /dev/null @@ -1,56 +0,0 @@ -/*! - * Bootstrap v3.3.6 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ - -// Core variables and mixins -@import "variables.less"; -@import "mixins.less"; - -// Reset and dependencies -@import "normalize.less"; -@import "print.less"; -@import "glyphicons.less"; - -// Core CSS -@import "scaffolding.less"; -@import "type.less"; -@import "code.less"; -@import "grid.less"; -@import "tables.less"; -@import "forms.less"; -@import "buttons.less"; - -// Components -@import "component-animations.less"; -@import "dropdowns.less"; -@import "button-groups.less"; -@import "input-groups.less"; -@import "navs.less"; -@import "navbar.less"; -@import "breadcrumbs.less"; -@import "pagination.less"; -@import "pager.less"; -@import "labels.less"; -@import "badges.less"; -@import "jumbotron.less"; -@import "thumbnails.less"; -@import "alerts.less"; -@import "progress-bars.less"; -@import "media.less"; -@import "list-group.less"; -@import "panels.less"; -@import "responsive-embed.less"; -@import "wells.less"; -@import "close.less"; - -// Components w/ JavaScript -@import "modals.less"; -@import "tooltip.less"; -@import "popovers.less"; -@import "carousel.less"; - -// Utility classes -@import "utilities.less"; -@import "responsive-utilities.less"; diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/breadcrumbs.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/breadcrumbs.less deleted file mode 100644 index cb01d503..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/breadcrumbs.less +++ /dev/null @@ -1,26 +0,0 @@ -// -// Breadcrumbs -// -------------------------------------------------- - - -.breadcrumb { - padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal; - margin-bottom: @line-height-computed; - list-style: none; - background-color: @breadcrumb-bg; - border-radius: @border-radius-base; - - > li { - display: inline-block; - - + li:before { - content: "@{breadcrumb-separator}\00a0"; // Unicode space added since inline-block means non-collapsing white-space - padding: 0 5px; - color: @breadcrumb-color; - } - } - - > .active { - color: @breadcrumb-active-color; - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/button-groups.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/button-groups.less deleted file mode 100644 index 293245a6..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/button-groups.less +++ /dev/null @@ -1,244 +0,0 @@ -// -// Button groups -// -------------------------------------------------- - -// Make the div behave like a button -.btn-group, -.btn-group-vertical { - position: relative; - display: inline-block; - vertical-align: middle; // match .btn alignment given font-size hack above - > .btn { - position: relative; - float: left; - // Bring the "active" button to the front - &:hover, - &:focus, - &:active, - &.active { - z-index: 2; - } - } -} - -// Prevent double borders when buttons are next to each other -.btn-group { - .btn + .btn, - .btn + .btn-group, - .btn-group + .btn, - .btn-group + .btn-group { - margin-left: -1px; - } -} - -// Optional: Group multiple button groups together for a toolbar -.btn-toolbar { - margin-left: -5px; // Offset the first child's margin - &:extend(.clearfix all); - - .btn, - .btn-group, - .input-group { - float: left; - } - > .btn, - > .btn-group, - > .input-group { - margin-left: 5px; - } -} - -.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { - border-radius: 0; -} - -// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match -.btn-group > .btn:first-child { - margin-left: 0; - &:not(:last-child):not(.dropdown-toggle) { - .border-right-radius(0); - } -} -// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it -.btn-group > .btn:last-child:not(:first-child), -.btn-group > .dropdown-toggle:not(:first-child) { - .border-left-radius(0); -} - -// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group) -.btn-group > .btn-group { - float: left; -} -.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} -.btn-group > .btn-group:first-child:not(:last-child) { - > .btn:last-child, - > .dropdown-toggle { - .border-right-radius(0); - } -} -.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { - .border-left-radius(0); -} - -// On active and open, don't show outline -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0; -} - - -// Sizing -// -// Remix the default button sizing classes into new ones for easier manipulation. - -.btn-group-xs > .btn { &:extend(.btn-xs); } -.btn-group-sm > .btn { &:extend(.btn-sm); } -.btn-group-lg > .btn { &:extend(.btn-lg); } - - -// Split button dropdowns -// ---------------------- - -// Give the line between buttons some depth -.btn-group > .btn + .dropdown-toggle { - padding-left: 8px; - padding-right: 8px; -} -.btn-group > .btn-lg + .dropdown-toggle { - padding-left: 12px; - padding-right: 12px; -} - -// The clickable button for toggling the menu -// Remove the gradient and set the same inset shadow as the :active state -.btn-group.open .dropdown-toggle { - .box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); - - // Show no shadow for `.btn-link` since it has no other button styles. - &.btn-link { - .box-shadow(none); - } -} - - -// Reposition the caret -.btn .caret { - margin-left: 0; -} -// Carets in other button sizes -.btn-lg .caret { - border-width: @caret-width-large @caret-width-large 0; - border-bottom-width: 0; -} -// Upside down carets for .dropup -.dropup .btn-lg .caret { - border-width: 0 @caret-width-large @caret-width-large; -} - - -// Vertical button groups -// ---------------------- - -.btn-group-vertical { - > .btn, - > .btn-group, - > .btn-group > .btn { - display: block; - float: none; - width: 100%; - max-width: 100%; - } - - // Clear floats so dropdown menus can be properly placed - > .btn-group { - &:extend(.clearfix all); - > .btn { - float: none; - } - } - - > .btn + .btn, - > .btn + .btn-group, - > .btn-group + .btn, - > .btn-group + .btn-group { - margin-top: -1px; - margin-left: 0; - } -} - -.btn-group-vertical > .btn { - &:not(:first-child):not(:last-child) { - border-radius: 0; - } - &:first-child:not(:last-child) { - .border-top-radius(@btn-border-radius-base); - .border-bottom-radius(0); - } - &:last-child:not(:first-child) { - .border-top-radius(0); - .border-bottom-radius(@btn-border-radius-base); - } -} -.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} -.btn-group-vertical > .btn-group:first-child:not(:last-child) { - > .btn:last-child, - > .dropdown-toggle { - .border-bottom-radius(0); - } -} -.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { - .border-top-radius(0); -} - - -// Justified button groups -// ---------------------- - -.btn-group-justified { - display: table; - width: 100%; - table-layout: fixed; - border-collapse: separate; - > .btn, - > .btn-group { - float: none; - display: table-cell; - width: 1%; - } - > .btn-group .btn { - width: 100%; - } - - > .btn-group .dropdown-menu { - left: auto; - } -} - - -// Checkbox and radio options -// -// In order to support the browser's form validation feedback, powered by the -// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use -// `display: none;` or `visibility: hidden;` as that also hides the popover. -// Simply visually hiding the inputs via `opacity` would leave them clickable in -// certain cases which is prevented by using `clip` and `pointer-events`. -// This way, we ensure a DOM element is visible to position the popover from. -// -// See https://github.com/twbs/bootstrap/pull/12794 and -// https://github.com/twbs/bootstrap/pull/14559 for more information. - -[data-toggle="buttons"] { - > .btn, - > .btn-group > .btn { - input[type="radio"], - input[type="checkbox"] { - position: absolute; - clip: rect(0,0,0,0); - pointer-events: none; - } - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/buttons.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/buttons.less deleted file mode 100644 index 9cbb8f41..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/buttons.less +++ /dev/null @@ -1,166 +0,0 @@ -// -// Buttons -// -------------------------------------------------- - - -// Base styles -// -------------------------------------------------- - -.btn { - display: inline-block; - margin-bottom: 0; // For input.btn - font-weight: @btn-font-weight; - text-align: center; - vertical-align: middle; - touch-action: manipulation; - cursor: pointer; - background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 - border: 1px solid transparent; - white-space: nowrap; - .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base); - .user-select(none); - - &, - &:active, - &.active { - &:focus, - &.focus { - .tab-focus(); - } - } - - &:hover, - &:focus, - &.focus { - color: @btn-default-color; - text-decoration: none; - } - - &:active, - &.active { - outline: 0; - background-image: none; - .box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); - } - - &.disabled, - &[disabled], - fieldset[disabled] & { - cursor: @cursor-disabled; - .opacity(.65); - .box-shadow(none); - } - - a& { - &.disabled, - fieldset[disabled] & { - pointer-events: none; // Future-proof disabling of clicks on `` elements - } - } -} - - -// Alternate buttons -// -------------------------------------------------- - -.btn-default { - .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border); -} -.btn-primary { - .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border); -} -// Success appears as green -.btn-success { - .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border); -} -// Info appears as blue-green -.btn-info { - .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border); -} -// Warning appears as orange -.btn-warning { - .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border); -} -// Danger and error appear as red -.btn-danger { - .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border); -} - - -// Link buttons -// ------------------------- - -// Make a button look and behave like a link -.btn-link { - color: @link-color; - font-weight: normal; - border-radius: 0; - - &, - &:active, - &.active, - &[disabled], - fieldset[disabled] & { - background-color: transparent; - .box-shadow(none); - } - &, - &:hover, - &:focus, - &:active { - border-color: transparent; - } - &:hover, - &:focus { - color: @link-hover-color; - text-decoration: @link-hover-decoration; - background-color: transparent; - } - &[disabled], - fieldset[disabled] & { - &:hover, - &:focus { - color: @btn-link-disabled-color; - text-decoration: none; - } - } -} - - -// Button Sizes -// -------------------------------------------------- - -.btn-lg { - // line-height: ensure even-numbered height of button next to large input - .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @btn-border-radius-large); -} -.btn-sm { - // line-height: ensure proper height of button next to small input - .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small); -} -.btn-xs { - .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small); -} - - -// Block button -// -------------------------------------------------- - -.btn-block { - display: block; - width: 100%; -} - -// Vertically space out multiple block buttons -.btn-block + .btn-block { - margin-top: 5px; -} - -// Specificity overrides -input[type="submit"], -input[type="reset"], -input[type="button"] { - &.btn-block { - width: 100%; - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/carousel.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/carousel.less deleted file mode 100644 index 252011e9..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/carousel.less +++ /dev/null @@ -1,270 +0,0 @@ -// -// Carousel -// -------------------------------------------------- - - -// Wrapper for the slide container and indicators -.carousel { - position: relative; -} - -.carousel-inner { - position: relative; - overflow: hidden; - width: 100%; - - > .item { - display: none; - position: relative; - .transition(.6s ease-in-out left); - - // Account for jankitude on images - > img, - > a > img { - &:extend(.img-responsive); - line-height: 1; - } - - // WebKit CSS3 transforms for supported devices - @media all and (transform-3d), (-webkit-transform-3d) { - .transition-transform(~'0.6s ease-in-out'); - .backface-visibility(~'hidden'); - .perspective(1000px); - - &.next, - &.active.right { - .translate3d(100%, 0, 0); - left: 0; - } - &.prev, - &.active.left { - .translate3d(-100%, 0, 0); - left: 0; - } - &.next.left, - &.prev.right, - &.active { - .translate3d(0, 0, 0); - left: 0; - } - } - } - - > .active, - > .next, - > .prev { - display: block; - } - - > .active { - left: 0; - } - - > .next, - > .prev { - position: absolute; - top: 0; - width: 100%; - } - - > .next { - left: 100%; - } - > .prev { - left: -100%; - } - > .next.left, - > .prev.right { - left: 0; - } - - > .active.left { - left: -100%; - } - > .active.right { - left: 100%; - } - -} - -// Left/right controls for nav -// --------------------------- - -.carousel-control { - position: absolute; - top: 0; - left: 0; - bottom: 0; - width: @carousel-control-width; - .opacity(@carousel-control-opacity); - font-size: @carousel-control-font-size; - color: @carousel-control-color; - text-align: center; - text-shadow: @carousel-text-shadow; - background-color: rgba(0, 0, 0, 0); // Fix IE9 click-thru bug - // We can't have this transition here because WebKit cancels the carousel - // animation if you trip this while in the middle of another animation. - - // Set gradients for backgrounds - &.left { - #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001)); - } - &.right { - left: auto; - right: 0; - #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5)); - } - - // Hover/focus state - &:hover, - &:focus { - outline: 0; - color: @carousel-control-color; - text-decoration: none; - .opacity(.9); - } - - // Toggles - .icon-prev, - .icon-next, - .glyphicon-chevron-left, - .glyphicon-chevron-right { - position: absolute; - top: 50%; - margin-top: -10px; - z-index: 5; - display: inline-block; - } - .icon-prev, - .glyphicon-chevron-left { - left: 50%; - margin-left: -10px; - } - .icon-next, - .glyphicon-chevron-right { - right: 50%; - margin-right: -10px; - } - .icon-prev, - .icon-next { - width: 20px; - height: 20px; - line-height: 1; - font-family: serif; - } - - - .icon-prev { - &:before { - content: '\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039) - } - } - .icon-next { - &:before { - content: '\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A) - } - } -} - -// Optional indicator pips -// -// Add an unordered list with the following class and add a list item for each -// slide your carousel holds. - -.carousel-indicators { - position: absolute; - bottom: 10px; - left: 50%; - z-index: 15; - width: 60%; - margin-left: -30%; - padding-left: 0; - list-style: none; - text-align: center; - - li { - display: inline-block; - width: 10px; - height: 10px; - margin: 1px; - text-indent: -999px; - border: 1px solid @carousel-indicator-border-color; - border-radius: 10px; - cursor: pointer; - - // IE8-9 hack for event handling - // - // Internet Explorer 8-9 does not support clicks on elements without a set - // `background-color`. We cannot use `filter` since that's not viewed as a - // background color by the browser. Thus, a hack is needed. - // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer - // - // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we - // set alpha transparency for the best results possible. - background-color: #000 \9; // IE8 - background-color: rgba(0,0,0,0); // IE9 - } - .active { - margin: 0; - width: 12px; - height: 12px; - background-color: @carousel-indicator-active-bg; - } -} - -// Optional captions -// ----------------------------- -// Hidden by default for smaller viewports -.carousel-caption { - position: absolute; - left: 15%; - right: 15%; - bottom: 20px; - z-index: 10; - padding-top: 20px; - padding-bottom: 20px; - color: @carousel-caption-color; - text-align: center; - text-shadow: @carousel-text-shadow; - & .btn { - text-shadow: none; // No shadow for button elements in carousel-caption - } -} - - -// Scale up controls for tablets and up -@media screen and (min-width: @screen-sm-min) { - - // Scale up the controls a smidge - .carousel-control { - .glyphicon-chevron-left, - .glyphicon-chevron-right, - .icon-prev, - .icon-next { - width: (@carousel-control-font-size * 1.5); - height: (@carousel-control-font-size * 1.5); - margin-top: (@carousel-control-font-size / -2); - font-size: (@carousel-control-font-size * 1.5); - } - .glyphicon-chevron-left, - .icon-prev { - margin-left: (@carousel-control-font-size / -2); - } - .glyphicon-chevron-right, - .icon-next { - margin-right: (@carousel-control-font-size / -2); - } - } - - // Show and left align the captions - .carousel-caption { - left: 20%; - right: 20%; - padding-bottom: 30px; - } - - // Move up the indicators - .carousel-indicators { - bottom: 20px; - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/close.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/close.less deleted file mode 100644 index 6d5bfe08..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/close.less +++ /dev/null @@ -1,34 +0,0 @@ -// -// Close icons -// -------------------------------------------------- - - -.close { - float: right; - font-size: (@font-size-base * 1.5); - font-weight: @close-font-weight; - line-height: 1; - color: @close-color; - text-shadow: @close-text-shadow; - .opacity(.2); - - &:hover, - &:focus { - color: @close-color; - text-decoration: none; - cursor: pointer; - .opacity(.5); - } - - // Additional properties for button version - // iOS requires the button element instead of an anchor tag. - // If you want the anchor version, it requires `href="#"`. - // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile - button& { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/code.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/code.less deleted file mode 100644 index a08b4d48..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/code.less +++ /dev/null @@ -1,69 +0,0 @@ -// -// Code (inline and block) -// -------------------------------------------------- - - -// Inline and block code styles -code, -kbd, -pre, -samp { - font-family: @font-family-monospace; -} - -// Inline code -code { - padding: 2px 4px; - font-size: 90%; - color: @code-color; - background-color: @code-bg; - border-radius: @border-radius-base; -} - -// User input typically entered via keyboard -kbd { - padding: 2px 4px; - font-size: 90%; - color: @kbd-color; - background-color: @kbd-bg; - border-radius: @border-radius-small; - box-shadow: inset 0 -1px 0 rgba(0,0,0,.25); - - kbd { - padding: 0; - font-size: 100%; - font-weight: bold; - box-shadow: none; - } -} - -// Blocks of code -pre { - display: block; - padding: ((@line-height-computed - 1) / 2); - margin: 0 0 (@line-height-computed / 2); - font-size: (@font-size-base - 1); // 14px to 13px - line-height: @line-height-base; - word-break: break-all; - word-wrap: break-word; - color: @pre-color; - background-color: @pre-bg; - border: 1px solid @pre-border-color; - border-radius: @border-radius-base; - - // Account for some code outputs that place code tags in pre tags - code { - padding: 0; - font-size: inherit; - color: inherit; - white-space: pre-wrap; - background-color: transparent; - border-radius: 0; - } -} - -// Enable scrollable blocks of code -.pre-scrollable { - max-height: @pre-scrollable-max-height; - overflow-y: scroll; -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/component-animations.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/component-animations.less deleted file mode 100644 index 0bcee910..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/component-animations.less +++ /dev/null @@ -1,33 +0,0 @@ -// -// Component animations -// -------------------------------------------------- - -// Heads up! -// -// We don't use the `.opacity()` mixin here since it causes a bug with text -// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552. - -.fade { - opacity: 0; - .transition(opacity .15s linear); - &.in { - opacity: 1; - } -} - -.collapse { - display: none; - - &.in { display: block; } - tr&.in { display: table-row; } - tbody&.in { display: table-row-group; } -} - -.collapsing { - position: relative; - height: 0; - overflow: hidden; - .transition-property(~"height, visibility"); - .transition-duration(.35s); - .transition-timing-function(ease); -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/dropdowns.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/dropdowns.less deleted file mode 100644 index f6876c1a..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/dropdowns.less +++ /dev/null @@ -1,216 +0,0 @@ -// -// Dropdown menus -// -------------------------------------------------- - - -// Dropdown arrow/caret -.caret { - display: inline-block; - width: 0; - height: 0; - margin-left: 2px; - vertical-align: middle; - border-top: @caret-width-base dashed; - border-top: @caret-width-base solid ~"\9"; // IE8 - border-right: @caret-width-base solid transparent; - border-left: @caret-width-base solid transparent; -} - -// The dropdown wrapper (div) -.dropup, -.dropdown { - position: relative; -} - -// Prevent the focus on the dropdown toggle when closing dropdowns -.dropdown-toggle:focus { - outline: 0; -} - -// The dropdown menu (ul) -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: @zindex-dropdown; - display: none; // none by default, but block on "open" of the menu - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; // override default ul - list-style: none; - font-size: @font-size-base; - text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer) - background-color: @dropdown-bg; - border: 1px solid @dropdown-fallback-border; // IE8 fallback - border: 1px solid @dropdown-border; - border-radius: @border-radius-base; - .box-shadow(0 6px 12px rgba(0,0,0,.175)); - background-clip: padding-box; - - // Aligns the dropdown menu to right - // - // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]` - &.pull-right { - right: 0; - left: auto; - } - - // Dividers (basically an hr) within the dropdown - .divider { - .nav-divider(@dropdown-divider-bg); - } - - // Links within the dropdown menu - > li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: @line-height-base; - color: @dropdown-link-color; - white-space: nowrap; // prevent links from randomly breaking onto new lines - } -} - -// Hover/Focus state -.dropdown-menu > li > a { - &:hover, - &:focus { - text-decoration: none; - color: @dropdown-link-hover-color; - background-color: @dropdown-link-hover-bg; - } -} - -// Active state -.dropdown-menu > .active > a { - &, - &:hover, - &:focus { - color: @dropdown-link-active-color; - text-decoration: none; - outline: 0; - background-color: @dropdown-link-active-bg; - } -} - -// Disabled state -// -// Gray out text and ensure the hover/focus state remains gray - -.dropdown-menu > .disabled > a { - &, - &:hover, - &:focus { - color: @dropdown-link-disabled-color; - } - - // Nuke hover/focus effects - &:hover, - &:focus { - text-decoration: none; - background-color: transparent; - background-image: none; // Remove CSS gradient - .reset-filter(); - cursor: @cursor-disabled; - } -} - -// Open state for the dropdown -.open { - // Show the menu - > .dropdown-menu { - display: block; - } - - // Remove the outline when :focus is triggered - > a { - outline: 0; - } -} - -// Menu positioning -// -// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown -// menu with the parent. -.dropdown-menu-right { - left: auto; // Reset the default from `.dropdown-menu` - right: 0; -} -// With v3, we enabled auto-flipping if you have a dropdown within a right -// aligned nav component. To enable the undoing of that, we provide an override -// to restore the default dropdown menu alignment. -// -// This is only for left-aligning a dropdown menu within a `.navbar-right` or -// `.pull-right` nav component. -.dropdown-menu-left { - left: 0; - right: auto; -} - -// Dropdown section headers -.dropdown-header { - display: block; - padding: 3px 20px; - font-size: @font-size-small; - line-height: @line-height-base; - color: @dropdown-header-color; - white-space: nowrap; // as with > li > a -} - -// Backdrop to catch body clicks on mobile, etc. -.dropdown-backdrop { - position: fixed; - left: 0; - right: 0; - bottom: 0; - top: 0; - z-index: (@zindex-dropdown - 10); -} - -// Right aligned dropdowns -.pull-right > .dropdown-menu { - right: 0; - left: auto; -} - -// Allow for dropdowns to go bottom up (aka, dropup-menu) -// -// Just add .dropup after the standard .dropdown class and you're set, bro. -// TODO: abstract this so that the navbar fixed styles are not placed here? - -.dropup, -.navbar-fixed-bottom .dropdown { - // Reverse the caret - .caret { - border-top: 0; - border-bottom: @caret-width-base dashed; - border-bottom: @caret-width-base solid ~"\9"; // IE8 - content: ""; - } - // Different positioning for bottom up menu - .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 2px; - } -} - - -// Component alignment -// -// Reiterate per navbar.less and the modified component alignment there. - -@media (min-width: @grid-float-breakpoint) { - .navbar-right { - .dropdown-menu { - .dropdown-menu-right(); - } - // Necessary for overrides of the default right aligned menu. - // Will remove come v4 in all likelihood. - .dropdown-menu-left { - .dropdown-menu-left(); - } - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/forms.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/forms.less deleted file mode 100644 index e8b071a1..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/forms.less +++ /dev/null @@ -1,613 +0,0 @@ -// -// Forms -// -------------------------------------------------- - - -// Normalize non-controls -// -// Restyle and baseline non-control form elements. - -fieldset { - padding: 0; - margin: 0; - border: 0; - // Chrome and Firefox set a `min-width: min-content;` on fieldsets, - // so we reset that to ensure it behaves more like a standard block element. - // See https://github.com/twbs/bootstrap/issues/12359. - min-width: 0; -} - -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: @line-height-computed; - font-size: (@font-size-base * 1.5); - line-height: inherit; - color: @legend-color; - border: 0; - border-bottom: 1px solid @legend-border-color; -} - -label { - display: inline-block; - max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141) - margin-bottom: 5px; - font-weight: bold; -} - - -// Normalize form controls -// -// While most of our form styles require extra classes, some basic normalization -// is required to ensure optimum display with or without those classes to better -// address browser inconsistencies. - -// Override content-box in Normalize (* isn't specific enough) -input[type="search"] { - .box-sizing(border-box); -} - -// Position radios and checkboxes better -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - margin-top: 1px \9; // IE8-9 - line-height: normal; -} - -input[type="file"] { - display: block; -} - -// Make range inputs behave like textual form controls -input[type="range"] { - display: block; - width: 100%; -} - -// Make multiple select elements height not fixed -select[multiple], -select[size] { - height: auto; -} - -// Focus for file, radio, and checkbox -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - .tab-focus(); -} - -// Adjust output element -output { - display: block; - padding-top: (@padding-base-vertical + 1); - font-size: @font-size-base; - line-height: @line-height-base; - color: @input-color; -} - - -// Common form controls -// -// Shared size and type resets for form controls. Apply `.form-control` to any -// of the following form controls: -// -// select -// textarea -// input[type="text"] -// input[type="password"] -// input[type="datetime"] -// input[type="datetime-local"] -// input[type="date"] -// input[type="month"] -// input[type="time"] -// input[type="week"] -// input[type="number"] -// input[type="email"] -// input[type="url"] -// input[type="search"] -// input[type="tel"] -// input[type="color"] - -.form-control { - display: block; - width: 100%; - height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border) - padding: @padding-base-vertical @padding-base-horizontal; - font-size: @font-size-base; - line-height: @line-height-base; - color: @input-color; - background-color: @input-bg; - background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 - border: 1px solid @input-border; - border-radius: @input-border-radius; // Note: This has no effect on s in CSS. - .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); - .transition(~"border-color ease-in-out .15s, box-shadow ease-in-out .15s"); - - // Customize the `:focus` state to imitate native WebKit styles. - .form-control-focus(); - - // Placeholder - .placeholder(); - - // Unstyle the caret on `` -// element gets special love because it's special, and that's a fact! -.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) { - height: @input-height; - padding: @padding-vertical @padding-horizontal; - font-size: @font-size; - line-height: @line-height; - border-radius: @border-radius; - - select& { - height: @input-height; - line-height: @input-height; - } - - textarea&, - select[multiple]& { - height: auto; - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/gradients.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/gradients.less deleted file mode 100644 index 0b88a89c..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/gradients.less +++ /dev/null @@ -1,59 +0,0 @@ -// Gradients - -#gradient { - - // Horizontal gradient, from left to right - // - // Creates two color stops, start and end, by specifying a color and position for each color stop. - // Color stops are not available in IE9 and below. - .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) { - background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+ - background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12 - background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+ - background-repeat: repeat-x; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down - } - - // Vertical gradient, from top to bottom - // - // Creates two color stops, start and end, by specifying a color and position for each color stop. - // Color stops are not available in IE9 and below. - .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) { - background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+ - background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12 - background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+ - background-repeat: repeat-x; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start-color),argb(@end-color))); // IE9 and down - } - - .directional(@start-color: #555; @end-color: #333; @deg: 45deg) { - background-repeat: repeat-x; - background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+ - background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12 - background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+ - } - .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) { - background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color); - background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color); - background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color); - background-repeat: no-repeat; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback - } - .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) { - background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color); - background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color); - background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color); - background-repeat: no-repeat; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback - } - .radial(@inner-color: #555; @outer-color: #333) { - background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color); - background-image: radial-gradient(circle, @inner-color, @outer-color); - background-repeat: no-repeat; - } - .striped(@color: rgba(255,255,255,.15); @angle: 45deg) { - background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent); - background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent); - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/grid-framework.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/grid-framework.less deleted file mode 100644 index 8c23eed2..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/grid-framework.less +++ /dev/null @@ -1,91 +0,0 @@ -// Framework grid generation -// -// Used only by Bootstrap to generate the correct number of grid classes given -// any value of `@grid-columns`. - -.make-grid-columns() { - // Common styles for all sizes of grid columns, widths 1-12 - .col(@index) { // initial - @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}"; - .col((@index + 1), @item); - } - .col(@index, @list) when (@index =< @grid-columns) { // general; "=<" isn't a typo - @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}"; - .col((@index + 1), ~"@{list}, @{item}"); - } - .col(@index, @list) when (@index > @grid-columns) { // terminal - @{list} { - position: relative; - // Prevent columns from collapsing when empty - min-height: 1px; - // Inner gutter via padding - padding-left: ceil((@grid-gutter-width / 2)); - padding-right: floor((@grid-gutter-width / 2)); - } - } - .col(1); // kickstart it -} - -.float-grid-columns(@class) { - .col(@index) { // initial - @item: ~".col-@{class}-@{index}"; - .col((@index + 1), @item); - } - .col(@index, @list) when (@index =< @grid-columns) { // general - @item: ~".col-@{class}-@{index}"; - .col((@index + 1), ~"@{list}, @{item}"); - } - .col(@index, @list) when (@index > @grid-columns) { // terminal - @{list} { - float: left; - } - } - .col(1); // kickstart it -} - -.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) { - .col-@{class}-@{index} { - width: percentage((@index / @grid-columns)); - } -} -.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) { - .col-@{class}-push-@{index} { - left: percentage((@index / @grid-columns)); - } -} -.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) { - .col-@{class}-push-0 { - left: auto; - } -} -.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) { - .col-@{class}-pull-@{index} { - right: percentage((@index / @grid-columns)); - } -} -.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) { - .col-@{class}-pull-0 { - right: auto; - } -} -.calc-grid-column(@index, @class, @type) when (@type = offset) { - .col-@{class}-offset-@{index} { - margin-left: percentage((@index / @grid-columns)); - } -} - -// Basic looping in LESS -.loop-grid-columns(@index, @class, @type) when (@index >= 0) { - .calc-grid-column(@index, @class, @type); - // next iteration - .loop-grid-columns((@index - 1), @class, @type); -} - -// Create grid for specific class -.make-grid(@class) { - .float-grid-columns(@class); - .loop-grid-columns(@grid-columns, @class, width); - .loop-grid-columns(@grid-columns, @class, pull); - .loop-grid-columns(@grid-columns, @class, push); - .loop-grid-columns(@grid-columns, @class, offset); -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/grid.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/grid.less deleted file mode 100644 index df496d0b..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/grid.less +++ /dev/null @@ -1,122 +0,0 @@ -// Grid system -// -// Generate semantic grid columns with these mixins. - -// Centered container element -.container-fixed(@gutter: @grid-gutter-width) { - margin-right: auto; - margin-left: auto; - padding-left: floor((@gutter / 2)); - padding-right: ceil((@gutter / 2)); - &:extend(.clearfix all); -} - -// Creates a wrapper for a series of columns -.make-row(@gutter: @grid-gutter-width) { - margin-left: ceil((@gutter / -2)); - margin-right: floor((@gutter / -2)); - &:extend(.clearfix all); -} - -// Generate the extra small columns -.make-xs-column(@columns; @gutter: @grid-gutter-width) { - position: relative; - float: left; - width: percentage((@columns / @grid-columns)); - min-height: 1px; - padding-left: (@gutter / 2); - padding-right: (@gutter / 2); -} -.make-xs-column-offset(@columns) { - margin-left: percentage((@columns / @grid-columns)); -} -.make-xs-column-push(@columns) { - left: percentage((@columns / @grid-columns)); -} -.make-xs-column-pull(@columns) { - right: percentage((@columns / @grid-columns)); -} - -// Generate the small columns -.make-sm-column(@columns; @gutter: @grid-gutter-width) { - position: relative; - min-height: 1px; - padding-left: (@gutter / 2); - padding-right: (@gutter / 2); - - @media (min-width: @screen-sm-min) { - float: left; - width: percentage((@columns / @grid-columns)); - } -} -.make-sm-column-offset(@columns) { - @media (min-width: @screen-sm-min) { - margin-left: percentage((@columns / @grid-columns)); - } -} -.make-sm-column-push(@columns) { - @media (min-width: @screen-sm-min) { - left: percentage((@columns / @grid-columns)); - } -} -.make-sm-column-pull(@columns) { - @media (min-width: @screen-sm-min) { - right: percentage((@columns / @grid-columns)); - } -} - -// Generate the medium columns -.make-md-column(@columns; @gutter: @grid-gutter-width) { - position: relative; - min-height: 1px; - padding-left: (@gutter / 2); - padding-right: (@gutter / 2); - - @media (min-width: @screen-md-min) { - float: left; - width: percentage((@columns / @grid-columns)); - } -} -.make-md-column-offset(@columns) { - @media (min-width: @screen-md-min) { - margin-left: percentage((@columns / @grid-columns)); - } -} -.make-md-column-push(@columns) { - @media (min-width: @screen-md-min) { - left: percentage((@columns / @grid-columns)); - } -} -.make-md-column-pull(@columns) { - @media (min-width: @screen-md-min) { - right: percentage((@columns / @grid-columns)); - } -} - -// Generate the large columns -.make-lg-column(@columns; @gutter: @grid-gutter-width) { - position: relative; - min-height: 1px; - padding-left: (@gutter / 2); - padding-right: (@gutter / 2); - - @media (min-width: @screen-lg-min) { - float: left; - width: percentage((@columns / @grid-columns)); - } -} -.make-lg-column-offset(@columns) { - @media (min-width: @screen-lg-min) { - margin-left: percentage((@columns / @grid-columns)); - } -} -.make-lg-column-push(@columns) { - @media (min-width: @screen-lg-min) { - left: percentage((@columns / @grid-columns)); - } -} -.make-lg-column-pull(@columns) { - @media (min-width: @screen-lg-min) { - right: percentage((@columns / @grid-columns)); - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/hide-text.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/hide-text.less deleted file mode 100644 index 2bb84a3b..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/hide-text.less +++ /dev/null @@ -1,21 +0,0 @@ -// CSS image replacement -// -// Heads up! v3 launched with only `.hide-text()`, but per our pattern for -// mixins being reused as classes with the same name, this doesn't hold up. As -// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`. -// -// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757 - -// Deprecated as of v3.0.1 (has been removed in v4) -.hide-text() { - font: ~"0/0" a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} - -// New mixin to use as of v3.0.1 -.text-hide() { - .hide-text(); -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/image.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/image.less deleted file mode 100644 index f233cb3e..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/image.less +++ /dev/null @@ -1,33 +0,0 @@ -// Image Mixins -// - Responsive image -// - Retina image - - -// Responsive image -// -// Keep images from scaling beyond the width of their parents. -.img-responsive(@display: block) { - display: @display; - max-width: 100%; // Part 1: Set a maximum relative to the parent - height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching -} - - -// Retina image -// -// Short retina mixin for setting background-image and -size. Note that the -// spelling of `min--moz-device-pixel-ratio` is intentional. -.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) { - background-image: url("@{file-1x}"); - - @media - only screen and (-webkit-min-device-pixel-ratio: 2), - only screen and ( min--moz-device-pixel-ratio: 2), - only screen and ( -o-min-device-pixel-ratio: 2/1), - only screen and ( min-device-pixel-ratio: 2), - only screen and ( min-resolution: 192dpi), - only screen and ( min-resolution: 2dppx) { - background-image: url("@{file-2x}"); - background-size: @width-1x @height-1x; - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/labels.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/labels.less deleted file mode 100644 index 9f7a67ee..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/labels.less +++ /dev/null @@ -1,12 +0,0 @@ -// Labels - -.label-variant(@color) { - background-color: @color; - - &[href] { - &:hover, - &:focus { - background-color: darken(@color, 10%); - } - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/list-group.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/list-group.less deleted file mode 100644 index 03aa1906..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/list-group.less +++ /dev/null @@ -1,30 +0,0 @@ -// List Groups - -.list-group-item-variant(@state; @background; @color) { - .list-group-item-@{state} { - color: @color; - background-color: @background; - - a&, - button& { - color: @color; - - .list-group-item-heading { - color: inherit; - } - - &:hover, - &:focus { - color: @color; - background-color: darken(@background, 5%); - } - &.active, - &.active:hover, - &.active:focus { - color: #fff; - background-color: @color; - border-color: @color; - } - } - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/nav-divider.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/nav-divider.less deleted file mode 100644 index feb1e9ed..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/nav-divider.less +++ /dev/null @@ -1,10 +0,0 @@ -// Horizontal dividers -// -// Dividers (basically an hr) within dropdowns and nav lists - -.nav-divider(@color: #e5e5e5) { - height: 1px; - margin: ((@line-height-computed / 2) - 1) 0; - overflow: hidden; - background-color: @color; -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/nav-vertical-align.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/nav-vertical-align.less deleted file mode 100644 index d458c786..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/nav-vertical-align.less +++ /dev/null @@ -1,9 +0,0 @@ -// Navbar vertical align -// -// Vertically center elements in the navbar. -// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin. - -.navbar-vertical-align(@element-height) { - margin-top: ((@navbar-height - @element-height) / 2); - margin-bottom: ((@navbar-height - @element-height) / 2); -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/opacity.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/opacity.less deleted file mode 100644 index 33ed25ce..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/opacity.less +++ /dev/null @@ -1,8 +0,0 @@ -// Opacity - -.opacity(@opacity) { - opacity: @opacity; - // IE8 filter - @opacity-ie: (@opacity * 100); - filter: ~"alpha(opacity=@{opacity-ie})"; -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/pagination.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/pagination.less deleted file mode 100644 index 618804f2..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/pagination.less +++ /dev/null @@ -1,24 +0,0 @@ -// Pagination - -.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) { - > li { - > a, - > span { - padding: @padding-vertical @padding-horizontal; - font-size: @font-size; - line-height: @line-height; - } - &:first-child { - > a, - > span { - .border-left-radius(@border-radius); - } - } - &:last-child { - > a, - > span { - .border-right-radius(@border-radius); - } - } - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/panels.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/panels.less deleted file mode 100644 index 49ee10d4..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/panels.less +++ /dev/null @@ -1,24 +0,0 @@ -// Panels - -.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) { - border-color: @border; - - & > .panel-heading { - color: @heading-text-color; - background-color: @heading-bg-color; - border-color: @heading-border; - - + .panel-collapse > .panel-body { - border-top-color: @border; - } - .badge { - color: @heading-bg-color; - background-color: @heading-text-color; - } - } - & > .panel-footer { - + .panel-collapse > .panel-body { - border-bottom-color: @border; - } - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/progress-bar.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/progress-bar.less deleted file mode 100644 index f07996a3..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/progress-bar.less +++ /dev/null @@ -1,10 +0,0 @@ -// Progress bars - -.progress-bar-variant(@color) { - background-color: @color; - - // Deprecated parent class requirement as of v3.2.0 - .progress-striped & { - #gradient > .striped(); - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/reset-filter.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/reset-filter.less deleted file mode 100644 index 68cdb5e1..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/reset-filter.less +++ /dev/null @@ -1,8 +0,0 @@ -// Reset filters for IE -// -// When you need to remove a gradient background, do not forget to use this to reset -// the IE filter for IE9 and below. - -.reset-filter() { - filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)")); -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/reset-text.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/reset-text.less deleted file mode 100644 index 58dd4d19..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/reset-text.less +++ /dev/null @@ -1,18 +0,0 @@ -.reset-text() { - font-family: @font-family-base; - // We deliberately do NOT reset font-size. - font-style: normal; - font-weight: normal; - letter-spacing: normal; - line-break: auto; - line-height: @line-height-base; - text-align: left; // Fallback for where `start` is not supported - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - white-space: normal; - word-break: normal; - word-spacing: normal; - word-wrap: normal; -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/resize.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/resize.less deleted file mode 100644 index 3acd3afd..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/resize.less +++ /dev/null @@ -1,6 +0,0 @@ -// Resize anything - -.resizable(@direction) { - resize: @direction; // Options: horizontal, vertical, both - overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible` -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/responsive-visibility.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/responsive-visibility.less deleted file mode 100644 index ecf1e979..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/responsive-visibility.less +++ /dev/null @@ -1,15 +0,0 @@ -// Responsive utilities - -// -// More easily include all the states for responsive-utilities.less. -.responsive-visibility() { - display: block !important; - table& { display: table !important; } - tr& { display: table-row !important; } - th&, - td& { display: table-cell !important; } -} - -.responsive-invisibility() { - display: none !important; -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/size.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/size.less deleted file mode 100644 index a8be6508..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/size.less +++ /dev/null @@ -1,10 +0,0 @@ -// Sizing shortcuts - -.size(@width; @height) { - width: @width; - height: @height; -} - -.square(@size) { - .size(@size; @size); -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/tab-focus.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/tab-focus.less deleted file mode 100644 index 1f1f05ab..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/tab-focus.less +++ /dev/null @@ -1,9 +0,0 @@ -// WebKit-style focus - -.tab-focus() { - // Default - outline: thin dotted; - // WebKit - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/table-row.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/table-row.less deleted file mode 100644 index 0f287f1a..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/table-row.less +++ /dev/null @@ -1,28 +0,0 @@ -// Tables - -.table-row-variant(@state; @background) { - // Exact selectors below required to override `.table-striped` and prevent - // inheritance to nested tables. - .table > thead > tr, - .table > tbody > tr, - .table > tfoot > tr { - > td.@{state}, - > th.@{state}, - &.@{state} > td, - &.@{state} > th { - background-color: @background; - } - } - - // Hover states for `.table-hover` - // Note: this is not available for cells or rows within `thead` or `tfoot`. - .table-hover > tbody > tr { - > td.@{state}:hover, - > th.@{state}:hover, - &.@{state}:hover > td, - &:hover > .@{state}, - &.@{state}:hover > th { - background-color: darken(@background, 5%); - } - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/text-emphasis.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/text-emphasis.less deleted file mode 100644 index 9e8a77a6..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/text-emphasis.less +++ /dev/null @@ -1,9 +0,0 @@ -// Typography - -.text-emphasis-variant(@color) { - color: @color; - a&:hover, - a&:focus { - color: darken(@color, 10%); - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/text-overflow.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/text-overflow.less deleted file mode 100644 index c11ad2fb..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/text-overflow.less +++ /dev/null @@ -1,8 +0,0 @@ -// Text overflow -// Requires inline-block or block for proper styling - -.text-overflow() { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/vendor-prefixes.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/vendor-prefixes.less deleted file mode 100644 index 2b5e74b9..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/mixins/vendor-prefixes.less +++ /dev/null @@ -1,227 +0,0 @@ -// Vendor Prefixes -// -// All vendor mixins are deprecated as of v3.2.0 due to the introduction of -// Autoprefixer in our Gruntfile. They have been removed in v4. - -// - Animations -// - Backface visibility -// - Box shadow -// - Box sizing -// - Content columns -// - Hyphens -// - Placeholder text -// - Transformations -// - Transitions -// - User Select - - -// Animations -.animation(@animation) { - -webkit-animation: @animation; - -o-animation: @animation; - animation: @animation; -} -.animation-name(@name) { - -webkit-animation-name: @name; - animation-name: @name; -} -.animation-duration(@duration) { - -webkit-animation-duration: @duration; - animation-duration: @duration; -} -.animation-timing-function(@timing-function) { - -webkit-animation-timing-function: @timing-function; - animation-timing-function: @timing-function; -} -.animation-delay(@delay) { - -webkit-animation-delay: @delay; - animation-delay: @delay; -} -.animation-iteration-count(@iteration-count) { - -webkit-animation-iteration-count: @iteration-count; - animation-iteration-count: @iteration-count; -} -.animation-direction(@direction) { - -webkit-animation-direction: @direction; - animation-direction: @direction; -} -.animation-fill-mode(@fill-mode) { - -webkit-animation-fill-mode: @fill-mode; - animation-fill-mode: @fill-mode; -} - -// Backface visibility -// Prevent browsers from flickering when using CSS 3D transforms. -// Default value is `visible`, but can be changed to `hidden` - -.backface-visibility(@visibility) { - -webkit-backface-visibility: @visibility; - -moz-backface-visibility: @visibility; - backface-visibility: @visibility; -} - -// Drop shadows -// -// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's -// supported browsers that have box shadow capabilities now support it. - -.box-shadow(@shadow) { - -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1 - box-shadow: @shadow; -} - -// Box sizing -.box-sizing(@boxmodel) { - -webkit-box-sizing: @boxmodel; - -moz-box-sizing: @boxmodel; - box-sizing: @boxmodel; -} - -// CSS3 Content Columns -.content-columns(@column-count; @column-gap: @grid-gutter-width) { - -webkit-column-count: @column-count; - -moz-column-count: @column-count; - column-count: @column-count; - -webkit-column-gap: @column-gap; - -moz-column-gap: @column-gap; - column-gap: @column-gap; -} - -// Optional hyphenation -.hyphens(@mode: auto) { - word-wrap: break-word; - -webkit-hyphens: @mode; - -moz-hyphens: @mode; - -ms-hyphens: @mode; // IE10+ - -o-hyphens: @mode; - hyphens: @mode; -} - -// Placeholder text -.placeholder(@color: @input-color-placeholder) { - // Firefox - &::-moz-placeholder { - color: @color; - opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526 - } - &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+ - &::-webkit-input-placeholder { color: @color; } // Safari and Chrome -} - -// Transformations -.scale(@ratio) { - -webkit-transform: scale(@ratio); - -ms-transform: scale(@ratio); // IE9 only - -o-transform: scale(@ratio); - transform: scale(@ratio); -} -.scale(@ratioX; @ratioY) { - -webkit-transform: scale(@ratioX, @ratioY); - -ms-transform: scale(@ratioX, @ratioY); // IE9 only - -o-transform: scale(@ratioX, @ratioY); - transform: scale(@ratioX, @ratioY); -} -.scaleX(@ratio) { - -webkit-transform: scaleX(@ratio); - -ms-transform: scaleX(@ratio); // IE9 only - -o-transform: scaleX(@ratio); - transform: scaleX(@ratio); -} -.scaleY(@ratio) { - -webkit-transform: scaleY(@ratio); - -ms-transform: scaleY(@ratio); // IE9 only - -o-transform: scaleY(@ratio); - transform: scaleY(@ratio); -} -.skew(@x; @y) { - -webkit-transform: skewX(@x) skewY(@y); - -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+ - -o-transform: skewX(@x) skewY(@y); - transform: skewX(@x) skewY(@y); -} -.translate(@x; @y) { - -webkit-transform: translate(@x, @y); - -ms-transform: translate(@x, @y); // IE9 only - -o-transform: translate(@x, @y); - transform: translate(@x, @y); -} -.translate3d(@x; @y; @z) { - -webkit-transform: translate3d(@x, @y, @z); - transform: translate3d(@x, @y, @z); -} -.rotate(@degrees) { - -webkit-transform: rotate(@degrees); - -ms-transform: rotate(@degrees); // IE9 only - -o-transform: rotate(@degrees); - transform: rotate(@degrees); -} -.rotateX(@degrees) { - -webkit-transform: rotateX(@degrees); - -ms-transform: rotateX(@degrees); // IE9 only - -o-transform: rotateX(@degrees); - transform: rotateX(@degrees); -} -.rotateY(@degrees) { - -webkit-transform: rotateY(@degrees); - -ms-transform: rotateY(@degrees); // IE9 only - -o-transform: rotateY(@degrees); - transform: rotateY(@degrees); -} -.perspective(@perspective) { - -webkit-perspective: @perspective; - -moz-perspective: @perspective; - perspective: @perspective; -} -.perspective-origin(@perspective) { - -webkit-perspective-origin: @perspective; - -moz-perspective-origin: @perspective; - perspective-origin: @perspective; -} -.transform-origin(@origin) { - -webkit-transform-origin: @origin; - -moz-transform-origin: @origin; - -ms-transform-origin: @origin; // IE9 only - transform-origin: @origin; -} - - -// Transitions - -.transition(@transition) { - -webkit-transition: @transition; - -o-transition: @transition; - transition: @transition; -} -.transition-property(@transition-property) { - -webkit-transition-property: @transition-property; - transition-property: @transition-property; -} -.transition-delay(@transition-delay) { - -webkit-transition-delay: @transition-delay; - transition-delay: @transition-delay; -} -.transition-duration(@transition-duration) { - -webkit-transition-duration: @transition-duration; - transition-duration: @transition-duration; -} -.transition-timing-function(@timing-function) { - -webkit-transition-timing-function: @timing-function; - transition-timing-function: @timing-function; -} -.transition-transform(@transition) { - -webkit-transition: -webkit-transform @transition; - -moz-transition: -moz-transform @transition; - -o-transition: -o-transform @transition; - transition: transform @transition; -} - - -// User select -// For selecting text on the page - -.user-select(@select) { - -webkit-user-select: @select; - -moz-user-select: @select; - -ms-user-select: @select; // IE10+ - user-select: @select; -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/modals.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/modals.less deleted file mode 100644 index 767ce36b..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/modals.less +++ /dev/null @@ -1,150 +0,0 @@ -// -// Modals -// -------------------------------------------------- - -// .modal-open - body class for killing the scroll -// .modal - container to scroll within -// .modal-dialog - positioning shell for the actual modal -// .modal-content - actual modal w/ bg and corners and shit - -// Kill the scroll on the body -.modal-open { - overflow: hidden; -} - -// Container that the modal scrolls within -.modal { - display: none; - overflow: hidden; - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: @zindex-modal; - -webkit-overflow-scrolling: touch; - - // Prevent Chrome on Windows from adding a focus outline. For details, see - // https://github.com/twbs/bootstrap/pull/10951. - outline: 0; - - // When fading in the modal, animate it to slide down - &.fade .modal-dialog { - .translate(0, -25%); - .transition-transform(~"0.3s ease-out"); - } - &.in .modal-dialog { .translate(0, 0) } -} -.modal-open .modal { - overflow-x: hidden; - overflow-y: auto; -} - -// Shell div to position the modal with bottom padding -.modal-dialog { - position: relative; - width: auto; - margin: 10px; -} - -// Actual modal -.modal-content { - position: relative; - background-color: @modal-content-bg; - border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc) - border: 1px solid @modal-content-border-color; - border-radius: @border-radius-large; - .box-shadow(0 3px 9px rgba(0,0,0,.5)); - background-clip: padding-box; - // Remove focus outline from opened modal - outline: 0; -} - -// Modal background -.modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: @zindex-modal-background; - background-color: @modal-backdrop-bg; - // Fade for backdrop - &.fade { .opacity(0); } - &.in { .opacity(@modal-backdrop-opacity); } -} - -// Modal header -// Top section of the modal w/ title and dismiss -.modal-header { - padding: @modal-title-padding; - border-bottom: 1px solid @modal-header-border-color; - &:extend(.clearfix all); -} -// Close icon -.modal-header .close { - margin-top: -2px; -} - -// Title text within header -.modal-title { - margin: 0; - line-height: @modal-title-line-height; -} - -// Modal body -// Where all modal content resides (sibling of .modal-header and .modal-footer) -.modal-body { - position: relative; - padding: @modal-inner-padding; -} - -// Footer (for actions) -.modal-footer { - padding: @modal-inner-padding; - text-align: right; // right align buttons - border-top: 1px solid @modal-footer-border-color; - &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons - - // Properly space out buttons - .btn + .btn { - margin-left: 5px; - margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs - } - // but override that for button groups - .btn-group .btn + .btn { - margin-left: -1px; - } - // and override it for block buttons as well - .btn-block + .btn-block { - margin-left: 0; - } -} - -// Measure scrollbar width for padding body during modal show/hide -.modal-scrollbar-measure { - position: absolute; - top: -9999px; - width: 50px; - height: 50px; - overflow: scroll; -} - -// Scale up the modal -@media (min-width: @screen-sm-min) { - // Automatically set modal's width for larger viewports - .modal-dialog { - width: @modal-md; - margin: 30px auto; - } - .modal-content { - .box-shadow(0 5px 15px rgba(0,0,0,.5)); - } - - // Modal sizes - .modal-sm { width: @modal-sm; } -} - -@media (min-width: @screen-md-min) { - .modal-lg { width: @modal-lg; } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/navbar.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/navbar.less deleted file mode 100644 index 6d751bb9..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/navbar.less +++ /dev/null @@ -1,660 +0,0 @@ -// -// Navbars -// -------------------------------------------------- - - -// Wrapper and base class -// -// Provide a static navbar from which we expand to create full-width, fixed, and -// other navbar variations. - -.navbar { - position: relative; - min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode) - margin-bottom: @navbar-margin-bottom; - border: 1px solid transparent; - - // Prevent floats from breaking the navbar - &:extend(.clearfix all); - - @media (min-width: @grid-float-breakpoint) { - border-radius: @navbar-border-radius; - } -} - - -// Navbar heading -// -// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy -// styling of responsive aspects. - -.navbar-header { - &:extend(.clearfix all); - - @media (min-width: @grid-float-breakpoint) { - float: left; - } -} - - -// Navbar collapse (body) -// -// Group your navbar content into this for easy collapsing and expanding across -// various device sizes. By default, this content is collapsed when <768px, but -// will expand past that for a horizontal display. -// -// To start (on mobile devices) the navbar links, forms, and buttons are stacked -// vertically and include a `max-height` to overflow in case you have too much -// content for the user's viewport. - -.navbar-collapse { - overflow-x: visible; - padding-right: @navbar-padding-horizontal; - padding-left: @navbar-padding-horizontal; - border-top: 1px solid transparent; - box-shadow: inset 0 1px 0 rgba(255,255,255,.1); - &:extend(.clearfix all); - -webkit-overflow-scrolling: touch; - - &.in { - overflow-y: auto; - } - - @media (min-width: @grid-float-breakpoint) { - width: auto; - border-top: 0; - box-shadow: none; - - &.collapse { - display: block !important; - height: auto !important; - padding-bottom: 0; // Override default setting - overflow: visible !important; - } - - &.in { - overflow-y: visible; - } - - // Undo the collapse side padding for navbars with containers to ensure - // alignment of right-aligned contents. - .navbar-fixed-top &, - .navbar-static-top &, - .navbar-fixed-bottom & { - padding-left: 0; - padding-right: 0; - } - } -} - -.navbar-fixed-top, -.navbar-fixed-bottom { - .navbar-collapse { - max-height: @navbar-collapse-max-height; - - @media (max-device-width: @screen-xs-min) and (orientation: landscape) { - max-height: 200px; - } - } -} - - -// Both navbar header and collapse -// -// When a container is present, change the behavior of the header and collapse. - -.container, -.container-fluid { - > .navbar-header, - > .navbar-collapse { - margin-right: -@navbar-padding-horizontal; - margin-left: -@navbar-padding-horizontal; - - @media (min-width: @grid-float-breakpoint) { - margin-right: 0; - margin-left: 0; - } - } -} - - -// -// Navbar alignment options -// -// Display the navbar across the entirety of the page or fixed it to the top or -// bottom of the page. - -// Static top (unfixed, but 100% wide) navbar -.navbar-static-top { - z-index: @zindex-navbar; - border-width: 0 0 1px; - - @media (min-width: @grid-float-breakpoint) { - border-radius: 0; - } -} - -// Fix the top/bottom navbars when screen real estate supports it -.navbar-fixed-top, -.navbar-fixed-bottom { - position: fixed; - right: 0; - left: 0; - z-index: @zindex-navbar-fixed; - - // Undo the rounded corners - @media (min-width: @grid-float-breakpoint) { - border-radius: 0; - } -} -.navbar-fixed-top { - top: 0; - border-width: 0 0 1px; -} -.navbar-fixed-bottom { - bottom: 0; - margin-bottom: 0; // override .navbar defaults - border-width: 1px 0 0; -} - - -// Brand/project name - -.navbar-brand { - float: left; - padding: @navbar-padding-vertical @navbar-padding-horizontal; - font-size: @font-size-large; - line-height: @line-height-computed; - height: @navbar-height; - - &:hover, - &:focus { - text-decoration: none; - } - - > img { - display: block; - } - - @media (min-width: @grid-float-breakpoint) { - .navbar > .container &, - .navbar > .container-fluid & { - margin-left: -@navbar-padding-horizontal; - } - } -} - - -// Navbar toggle -// -// Custom button for toggling the `.navbar-collapse`, powered by the collapse -// JavaScript plugin. - -.navbar-toggle { - position: relative; - float: right; - margin-right: @navbar-padding-horizontal; - padding: 9px 10px; - .navbar-vertical-align(34px); - background-color: transparent; - background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 - border: 1px solid transparent; - border-radius: @border-radius-base; - - // We remove the `outline` here, but later compensate by attaching `:hover` - // styles to `:focus`. - &:focus { - outline: 0; - } - - // Bars - .icon-bar { - display: block; - width: 22px; - height: 2px; - border-radius: 1px; - } - .icon-bar + .icon-bar { - margin-top: 4px; - } - - @media (min-width: @grid-float-breakpoint) { - display: none; - } -} - - -// Navbar nav links -// -// Builds on top of the `.nav` components with its own modifier class to make -// the nav the full height of the horizontal nav (above 768px). - -.navbar-nav { - margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal; - - > li > a { - padding-top: 10px; - padding-bottom: 10px; - line-height: @line-height-computed; - } - - @media (max-width: @grid-float-breakpoint-max) { - // Dropdowns get custom display when collapsed - .open .dropdown-menu { - position: static; - float: none; - width: auto; - margin-top: 0; - background-color: transparent; - border: 0; - box-shadow: none; - > li > a, - .dropdown-header { - padding: 5px 15px 5px 25px; - } - > li > a { - line-height: @line-height-computed; - &:hover, - &:focus { - background-image: none; - } - } - } - } - - // Uncollapse the nav - @media (min-width: @grid-float-breakpoint) { - float: left; - margin: 0; - - > li { - float: left; - > a { - padding-top: @navbar-padding-vertical; - padding-bottom: @navbar-padding-vertical; - } - } - } -} - - -// Navbar form -// -// Extension of the `.form-inline` with some extra flavor for optimum display in -// our navbars. - -.navbar-form { - margin-left: -@navbar-padding-horizontal; - margin-right: -@navbar-padding-horizontal; - padding: 10px @navbar-padding-horizontal; - border-top: 1px solid transparent; - border-bottom: 1px solid transparent; - @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); - .box-shadow(@shadow); - - // Mixin behavior for optimum display - .form-inline(); - - .form-group { - @media (max-width: @grid-float-breakpoint-max) { - margin-bottom: 5px; - - &:last-child { - margin-bottom: 0; - } - } - } - - // Vertically center in expanded, horizontal navbar - .navbar-vertical-align(@input-height-base); - - // Undo 100% width for pull classes - @media (min-width: @grid-float-breakpoint) { - width: auto; - border: 0; - margin-left: 0; - margin-right: 0; - padding-top: 0; - padding-bottom: 0; - .box-shadow(none); - } -} - - -// Dropdown menus - -// Menu position and menu carets -.navbar-nav > li > .dropdown-menu { - margin-top: 0; - .border-top-radius(0); -} -// Menu position and menu caret support for dropups via extra dropup class -.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { - margin-bottom: 0; - .border-top-radius(@navbar-border-radius); - .border-bottom-radius(0); -} - - -// Buttons in navbars -// -// Vertically center a button within a navbar (when *not* in a form). - -.navbar-btn { - .navbar-vertical-align(@input-height-base); - - &.btn-sm { - .navbar-vertical-align(@input-height-small); - } - &.btn-xs { - .navbar-vertical-align(22); - } -} - - -// Text in navbars -// -// Add a class to make any element properly align itself vertically within the navbars. - -.navbar-text { - .navbar-vertical-align(@line-height-computed); - - @media (min-width: @grid-float-breakpoint) { - float: left; - margin-left: @navbar-padding-horizontal; - margin-right: @navbar-padding-horizontal; - } -} - - -// Component alignment -// -// Repurpose the pull utilities as their own navbar utilities to avoid specificity -// issues with parents and chaining. Only do this when the navbar is uncollapsed -// though so that navbar contents properly stack and align in mobile. -// -// Declared after the navbar components to ensure more specificity on the margins. - -@media (min-width: @grid-float-breakpoint) { - .navbar-left { .pull-left(); } - .navbar-right { - .pull-right(); - margin-right: -@navbar-padding-horizontal; - - ~ .navbar-right { - margin-right: 0; - } - } -} - - -// Alternate navbars -// -------------------------------------------------- - -// Default navbar -.navbar-default { - background-color: @navbar-default-bg; - border-color: @navbar-default-border; - - .navbar-brand { - color: @navbar-default-brand-color; - &:hover, - &:focus { - color: @navbar-default-brand-hover-color; - background-color: @navbar-default-brand-hover-bg; - } - } - - .navbar-text { - color: @navbar-default-color; - } - - .navbar-nav { - > li > a { - color: @navbar-default-link-color; - - &:hover, - &:focus { - color: @navbar-default-link-hover-color; - background-color: @navbar-default-link-hover-bg; - } - } - > .active > a { - &, - &:hover, - &:focus { - color: @navbar-default-link-active-color; - background-color: @navbar-default-link-active-bg; - } - } - > .disabled > a { - &, - &:hover, - &:focus { - color: @navbar-default-link-disabled-color; - background-color: @navbar-default-link-disabled-bg; - } - } - } - - .navbar-toggle { - border-color: @navbar-default-toggle-border-color; - &:hover, - &:focus { - background-color: @navbar-default-toggle-hover-bg; - } - .icon-bar { - background-color: @navbar-default-toggle-icon-bar-bg; - } - } - - .navbar-collapse, - .navbar-form { - border-color: @navbar-default-border; - } - - // Dropdown menu items - .navbar-nav { - // Remove background color from open dropdown - > .open > a { - &, - &:hover, - &:focus { - background-color: @navbar-default-link-active-bg; - color: @navbar-default-link-active-color; - } - } - - @media (max-width: @grid-float-breakpoint-max) { - // Dropdowns get custom display when collapsed - .open .dropdown-menu { - > li > a { - color: @navbar-default-link-color; - &:hover, - &:focus { - color: @navbar-default-link-hover-color; - background-color: @navbar-default-link-hover-bg; - } - } - > .active > a { - &, - &:hover, - &:focus { - color: @navbar-default-link-active-color; - background-color: @navbar-default-link-active-bg; - } - } - > .disabled > a { - &, - &:hover, - &:focus { - color: @navbar-default-link-disabled-color; - background-color: @navbar-default-link-disabled-bg; - } - } - } - } - } - - - // Links in navbars - // - // Add a class to ensure links outside the navbar nav are colored correctly. - - .navbar-link { - color: @navbar-default-link-color; - &:hover { - color: @navbar-default-link-hover-color; - } - } - - .btn-link { - color: @navbar-default-link-color; - &:hover, - &:focus { - color: @navbar-default-link-hover-color; - } - &[disabled], - fieldset[disabled] & { - &:hover, - &:focus { - color: @navbar-default-link-disabled-color; - } - } - } -} - -// Inverse navbar - -.navbar-inverse { - background-color: @navbar-inverse-bg; - border-color: @navbar-inverse-border; - - .navbar-brand { - color: @navbar-inverse-brand-color; - &:hover, - &:focus { - color: @navbar-inverse-brand-hover-color; - background-color: @navbar-inverse-brand-hover-bg; - } - } - - .navbar-text { - color: @navbar-inverse-color; - } - - .navbar-nav { - > li > a { - color: @navbar-inverse-link-color; - - &:hover, - &:focus { - color: @navbar-inverse-link-hover-color; - background-color: @navbar-inverse-link-hover-bg; - } - } - > .active > a { - &, - &:hover, - &:focus { - color: @navbar-inverse-link-active-color; - background-color: @navbar-inverse-link-active-bg; - } - } - > .disabled > a { - &, - &:hover, - &:focus { - color: @navbar-inverse-link-disabled-color; - background-color: @navbar-inverse-link-disabled-bg; - } - } - } - - // Darken the responsive nav toggle - .navbar-toggle { - border-color: @navbar-inverse-toggle-border-color; - &:hover, - &:focus { - background-color: @navbar-inverse-toggle-hover-bg; - } - .icon-bar { - background-color: @navbar-inverse-toggle-icon-bar-bg; - } - } - - .navbar-collapse, - .navbar-form { - border-color: darken(@navbar-inverse-bg, 7%); - } - - // Dropdowns - .navbar-nav { - > .open > a { - &, - &:hover, - &:focus { - background-color: @navbar-inverse-link-active-bg; - color: @navbar-inverse-link-active-color; - } - } - - @media (max-width: @grid-float-breakpoint-max) { - // Dropdowns get custom display - .open .dropdown-menu { - > .dropdown-header { - border-color: @navbar-inverse-border; - } - .divider { - background-color: @navbar-inverse-border; - } - > li > a { - color: @navbar-inverse-link-color; - &:hover, - &:focus { - color: @navbar-inverse-link-hover-color; - background-color: @navbar-inverse-link-hover-bg; - } - } - > .active > a { - &, - &:hover, - &:focus { - color: @navbar-inverse-link-active-color; - background-color: @navbar-inverse-link-active-bg; - } - } - > .disabled > a { - &, - &:hover, - &:focus { - color: @navbar-inverse-link-disabled-color; - background-color: @navbar-inverse-link-disabled-bg; - } - } - } - } - } - - .navbar-link { - color: @navbar-inverse-link-color; - &:hover { - color: @navbar-inverse-link-hover-color; - } - } - - .btn-link { - color: @navbar-inverse-link-color; - &:hover, - &:focus { - color: @navbar-inverse-link-hover-color; - } - &[disabled], - fieldset[disabled] & { - &:hover, - &:focus { - color: @navbar-inverse-link-disabled-color; - } - } - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/navs.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/navs.less deleted file mode 100644 index a3d11b13..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/navs.less +++ /dev/null @@ -1,242 +0,0 @@ -// -// Navs -// -------------------------------------------------- - - -// Base class -// -------------------------------------------------- - -.nav { - margin-bottom: 0; - padding-left: 0; // Override default ul/ol - list-style: none; - &:extend(.clearfix all); - - > li { - position: relative; - display: block; - - > a { - position: relative; - display: block; - padding: @nav-link-padding; - &:hover, - &:focus { - text-decoration: none; - background-color: @nav-link-hover-bg; - } - } - - // Disabled state sets text to gray and nukes hover/tab effects - &.disabled > a { - color: @nav-disabled-link-color; - - &:hover, - &:focus { - color: @nav-disabled-link-hover-color; - text-decoration: none; - background-color: transparent; - cursor: @cursor-disabled; - } - } - } - - // Open dropdowns - .open > a { - &, - &:hover, - &:focus { - background-color: @nav-link-hover-bg; - border-color: @link-color; - } - } - - // Nav dividers (deprecated with v3.0.1) - // - // This should have been removed in v3 with the dropping of `.nav-list`, but - // we missed it. We don't currently support this anywhere, but in the interest - // of maintaining backward compatibility in case you use it, it's deprecated. - .nav-divider { - .nav-divider(); - } - - // Prevent IE8 from misplacing imgs - // - // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989 - > li > a > img { - max-width: none; - } -} - - -// Tabs -// ------------------------- - -// Give the tabs something to sit on -.nav-tabs { - border-bottom: 1px solid @nav-tabs-border-color; - > li { - float: left; - // Make the list-items overlay the bottom border - margin-bottom: -1px; - - // Actual tabs (as links) - > a { - margin-right: 2px; - line-height: @line-height-base; - border: 1px solid transparent; - border-radius: @border-radius-base @border-radius-base 0 0; - &:hover { - border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color; - } - } - - // Active state, and its :hover to override normal :hover - &.active > a { - &, - &:hover, - &:focus { - color: @nav-tabs-active-link-hover-color; - background-color: @nav-tabs-active-link-hover-bg; - border: 1px solid @nav-tabs-active-link-hover-border-color; - border-bottom-color: transparent; - cursor: default; - } - } - } - // pulling this in mainly for less shorthand - &.nav-justified { - .nav-justified(); - .nav-tabs-justified(); - } -} - - -// Pills -// ------------------------- -.nav-pills { - > li { - float: left; - - // Links rendered as pills - > a { - border-radius: @nav-pills-border-radius; - } - + li { - margin-left: 2px; - } - - // Active state - &.active > a { - &, - &:hover, - &:focus { - color: @nav-pills-active-link-hover-color; - background-color: @nav-pills-active-link-hover-bg; - } - } - } -} - - -// Stacked pills -.nav-stacked { - > li { - float: none; - + li { - margin-top: 2px; - margin-left: 0; // no need for this gap between nav items - } - } -} - - -// Nav variations -// -------------------------------------------------- - -// Justified nav links -// ------------------------- - -.nav-justified { - width: 100%; - - > li { - float: none; - > a { - text-align: center; - margin-bottom: 5px; - } - } - - > .dropdown .dropdown-menu { - top: auto; - left: auto; - } - - @media (min-width: @screen-sm-min) { - > li { - display: table-cell; - width: 1%; - > a { - margin-bottom: 0; - } - } - } -} - -// Move borders to anchors instead of bottom of list -// -// Mixin for adding on top the shared `.nav-justified` styles for our tabs -.nav-tabs-justified { - border-bottom: 0; - - > li > a { - // Override margin from .nav-tabs - margin-right: 0; - border-radius: @border-radius-base; - } - - > .active > a, - > .active > a:hover, - > .active > a:focus { - border: 1px solid @nav-tabs-justified-link-border-color; - } - - @media (min-width: @screen-sm-min) { - > li > a { - border-bottom: 1px solid @nav-tabs-justified-link-border-color; - border-radius: @border-radius-base @border-radius-base 0 0; - } - > .active > a, - > .active > a:hover, - > .active > a:focus { - border-bottom-color: @nav-tabs-justified-active-link-border-color; - } - } -} - - -// Tabbable tabs -// ------------------------- - -// Hide tabbable panes to start, show them when `.active` -.tab-content { - > .tab-pane { - display: none; - } - > .active { - display: block; - } -} - - -// Dropdowns -// ------------------------- - -// Specific dropdowns -.nav-tabs .dropdown-menu { - // make dropdown border overlap tab border - margin-top: -1px; - // Remove the top rounded corners here since there is a hard edge above the menu - .border-top-radius(0); -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/normalize.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/normalize.less deleted file mode 100644 index 9dddf73a..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/normalize.less +++ /dev/null @@ -1,424 +0,0 @@ -/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ - -// -// 1. Set default font family to sans-serif. -// 2. Prevent iOS and IE text size adjust after device orientation change, -// without disabling user zoom. -// - -html { - font-family: sans-serif; // 1 - -ms-text-size-adjust: 100%; // 2 - -webkit-text-size-adjust: 100%; // 2 -} - -// -// Remove default margin. -// - -body { - margin: 0; -} - -// HTML5 display definitions -// ========================================================================== - -// -// Correct `block` display not defined for any HTML5 element in IE 8/9. -// Correct `block` display not defined for `details` or `summary` in IE 10/11 -// and Firefox. -// Correct `block` display not defined for `main` in IE 11. -// - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -menu, -nav, -section, -summary { - display: block; -} - -// -// 1. Correct `inline-block` display not defined in IE 8/9. -// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. -// - -audio, -canvas, -progress, -video { - display: inline-block; // 1 - vertical-align: baseline; // 2 -} - -// -// Prevent modern browsers from displaying `audio` without controls. -// Remove excess height in iOS 5 devices. -// - -audio:not([controls]) { - display: none; - height: 0; -} - -// -// Address `[hidden]` styling not present in IE 8/9/10. -// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22. -// - -[hidden], -template { - display: none; -} - -// Links -// ========================================================================== - -// -// Remove the gray background color from active links in IE 10. -// - -a { - background-color: transparent; -} - -// -// Improve readability of focused elements when they are also in an -// active/hover state. -// - -a:active, -a:hover { - outline: 0; -} - -// Text-level semantics -// ========================================================================== - -// -// Address styling not present in IE 8/9/10/11, Safari, and Chrome. -// - -abbr[title] { - border-bottom: 1px dotted; -} - -// -// Address style set to `bolder` in Firefox 4+, Safari, and Chrome. -// - -b, -strong { - font-weight: bold; -} - -// -// Address styling not present in Safari and Chrome. -// - -dfn { - font-style: italic; -} - -// -// Address variable `h1` font-size and margin within `section` and `article` -// contexts in Firefox 4+, Safari, and Chrome. -// - -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -// -// Address styling not present in IE 8/9. -// - -mark { - background: #ff0; - color: #000; -} - -// -// Address inconsistent and variable font size in all browsers. -// - -small { - font-size: 80%; -} - -// -// Prevent `sub` and `sup` affecting `line-height` in all browsers. -// - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -// Embedded content -// ========================================================================== - -// -// Remove border when inside `a` element in IE 8/9/10. -// - -img { - border: 0; -} - -// -// Correct overflow not hidden in IE 9/10/11. -// - -svg:not(:root) { - overflow: hidden; -} - -// Grouping content -// ========================================================================== - -// -// Address margin not present in IE 8/9 and Safari. -// - -figure { - margin: 1em 40px; -} - -// -// Address differences between Firefox and other browsers. -// - -hr { - box-sizing: content-box; - height: 0; -} - -// -// Contain overflow in all browsers. -// - -pre { - overflow: auto; -} - -// -// Address odd `em`-unit font size rendering in all browsers. -// - -code, -kbd, -pre, -samp { - font-family: monospace, monospace; - font-size: 1em; -} - -// Forms -// ========================================================================== - -// -// Known limitation: by default, Chrome and Safari on OS X allow very limited -// styling of `select`, unless a `border` property is set. -// - -// -// 1. Correct color not being inherited. -// Known issue: affects color of disabled elements. -// 2. Correct font properties not being inherited. -// 3. Address margins set differently in Firefox 4+, Safari, and Chrome. -// - -button, -input, -optgroup, -select, -textarea { - color: inherit; // 1 - font: inherit; // 2 - margin: 0; // 3 -} - -// -// Address `overflow` set to `hidden` in IE 8/9/10/11. -// - -button { - overflow: visible; -} - -// -// Address inconsistent `text-transform` inheritance for `button` and `select`. -// All other form control elements do not inherit `text-transform` values. -// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. -// Correct `select` style inheritance in Firefox. -// - -button, -select { - text-transform: none; -} - -// -// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` -// and `video` controls. -// 2. Correct inability to style clickable `input` types in iOS. -// 3. Improve usability and consistency of cursor style between image-type -// `input` and others. -// - -button, -html input[type="button"], // 1 -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; // 2 - cursor: pointer; // 3 -} - -// -// Re-set default cursor for disabled elements. -// - -button[disabled], -html input[disabled] { - cursor: default; -} - -// -// Remove inner padding and border in Firefox 4+. -// - -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} - -// -// Address Firefox 4+ setting `line-height` on `input` using `!important` in -// the UA stylesheet. -// - -input { - line-height: normal; -} - -// -// It's recommended that you don't attempt to style these elements. -// Firefox's implementation doesn't respect box-sizing, padding, or width. -// -// 1. Address box sizing set to `content-box` in IE 8/9/10. -// 2. Remove excess padding in IE 8/9/10. -// - -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; // 1 - padding: 0; // 2 -} - -// -// Fix the cursor style for Chrome's increment/decrement buttons. For certain -// `font-size` values of the `input`, it causes the cursor style of the -// decrement button to change from `default` to `text`. -// - -input[type="number"]::-webkit-inner-spin-button, -input[type="number"]::-webkit-outer-spin-button { - height: auto; -} - -// -// 1. Address `appearance` set to `searchfield` in Safari and Chrome. -// 2. Address `box-sizing` set to `border-box` in Safari and Chrome. -// - -input[type="search"] { - -webkit-appearance: textfield; // 1 - box-sizing: content-box; //2 -} - -// -// Remove inner padding and search cancel button in Safari and Chrome on OS X. -// Safari (but not Chrome) clips the cancel button when the search input has -// padding (and `textfield` appearance). -// - -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -// -// Define consistent border, margin, and padding. -// - -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} - -// -// 1. Correct `color` not being inherited in IE 8/9/10/11. -// 2. Remove padding so people aren't caught out if they zero out fieldsets. -// - -legend { - border: 0; // 1 - padding: 0; // 2 -} - -// -// Remove default vertical scrollbar in IE 8/9/10/11. -// - -textarea { - overflow: auto; -} - -// -// Don't inherit the `font-weight` (applied by a rule above). -// NOTE: the default cannot safely be changed in Chrome and Safari on OS X. -// - -optgroup { - font-weight: bold; -} - -// Tables -// ========================================================================== - -// -// Remove most spacing between table cells. -// - -table { - border-collapse: collapse; - border-spacing: 0; -} - -td, -th { - padding: 0; -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/pager.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/pager.less deleted file mode 100644 index 41abaaad..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/pager.less +++ /dev/null @@ -1,54 +0,0 @@ -// -// Pager pagination -// -------------------------------------------------- - - -.pager { - padding-left: 0; - margin: @line-height-computed 0; - list-style: none; - text-align: center; - &:extend(.clearfix all); - li { - display: inline; - > a, - > span { - display: inline-block; - padding: 5px 14px; - background-color: @pager-bg; - border: 1px solid @pager-border; - border-radius: @pager-border-radius; - } - - > a:hover, - > a:focus { - text-decoration: none; - background-color: @pager-hover-bg; - } - } - - .next { - > a, - > span { - float: right; - } - } - - .previous { - > a, - > span { - float: left; - } - } - - .disabled { - > a, - > a:hover, - > a:focus, - > span { - color: @pager-disabled-color; - background-color: @pager-bg; - cursor: @cursor-disabled; - } - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/pagination.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/pagination.less deleted file mode 100644 index 31f77aae..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/pagination.less +++ /dev/null @@ -1,89 +0,0 @@ -// -// Pagination (multiple pages) -// -------------------------------------------------- -.pagination { - display: inline-block; - padding-left: 0; - margin: @line-height-computed 0; - border-radius: @border-radius-base; - - > li { - display: inline; // Remove list-style and block-level defaults - > a, - > span { - position: relative; - float: left; // Collapse white-space - padding: @padding-base-vertical @padding-base-horizontal; - line-height: @line-height-base; - text-decoration: none; - color: @pagination-color; - background-color: @pagination-bg; - border: 1px solid @pagination-border; - margin-left: -1px; - } - &:first-child { - > a, - > span { - margin-left: 0; - .border-left-radius(@border-radius-base); - } - } - &:last-child { - > a, - > span { - .border-right-radius(@border-radius-base); - } - } - } - - > li > a, - > li > span { - &:hover, - &:focus { - z-index: 2; - color: @pagination-hover-color; - background-color: @pagination-hover-bg; - border-color: @pagination-hover-border; - } - } - - > .active > a, - > .active > span { - &, - &:hover, - &:focus { - z-index: 3; - color: @pagination-active-color; - background-color: @pagination-active-bg; - border-color: @pagination-active-border; - cursor: default; - } - } - - > .disabled { - > span, - > span:hover, - > span:focus, - > a, - > a:hover, - > a:focus { - color: @pagination-disabled-color; - background-color: @pagination-disabled-bg; - border-color: @pagination-disabled-border; - cursor: @cursor-disabled; - } - } -} - -// Sizing -// -------------------------------------------------- - -// Large -.pagination-lg { - .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large); -} - -// Small -.pagination-sm { - .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small); -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/panels.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/panels.less deleted file mode 100644 index 425eb5e6..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/panels.less +++ /dev/null @@ -1,271 +0,0 @@ -// -// Panels -// -------------------------------------------------- - - -// Base class -.panel { - margin-bottom: @line-height-computed; - background-color: @panel-bg; - border: 1px solid transparent; - border-radius: @panel-border-radius; - .box-shadow(0 1px 1px rgba(0,0,0,.05)); -} - -// Panel contents -.panel-body { - padding: @panel-body-padding; - &:extend(.clearfix all); -} - -// Optional heading -.panel-heading { - padding: @panel-heading-padding; - border-bottom: 1px solid transparent; - .border-top-radius((@panel-border-radius - 1)); - - > .dropdown .dropdown-toggle { - color: inherit; - } -} - -// Within heading, strip any `h*` tag of its default margins for spacing. -.panel-title { - margin-top: 0; - margin-bottom: 0; - font-size: ceil((@font-size-base * 1.125)); - color: inherit; - - > a, - > small, - > .small, - > small > a, - > .small > a { - color: inherit; - } -} - -// Optional footer (stays gray in every modifier class) -.panel-footer { - padding: @panel-footer-padding; - background-color: @panel-footer-bg; - border-top: 1px solid @panel-inner-border; - .border-bottom-radius((@panel-border-radius - 1)); -} - - -// List groups in panels -// -// By default, space out list group content from panel headings to account for -// any kind of custom content between the two. - -.panel { - > .list-group, - > .panel-collapse > .list-group { - margin-bottom: 0; - - .list-group-item { - border-width: 1px 0; - border-radius: 0; - } - - // Add border top radius for first one - &:first-child { - .list-group-item:first-child { - border-top: 0; - .border-top-radius((@panel-border-radius - 1)); - } - } - - // Add border bottom radius for last one - &:last-child { - .list-group-item:last-child { - border-bottom: 0; - .border-bottom-radius((@panel-border-radius - 1)); - } - } - } - > .panel-heading + .panel-collapse > .list-group { - .list-group-item:first-child { - .border-top-radius(0); - } - } -} -// Collapse space between when there's no additional content. -.panel-heading + .list-group { - .list-group-item:first-child { - border-top-width: 0; - } -} -.list-group + .panel-footer { - border-top-width: 0; -} - -// Tables in panels -// -// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and -// watch it go full width. - -.panel { - > .table, - > .table-responsive > .table, - > .panel-collapse > .table { - margin-bottom: 0; - - caption { - padding-left: @panel-body-padding; - padding-right: @panel-body-padding; - } - } - // Add border top radius for first one - > .table:first-child, - > .table-responsive:first-child > .table:first-child { - .border-top-radius((@panel-border-radius - 1)); - - > thead:first-child, - > tbody:first-child { - > tr:first-child { - border-top-left-radius: (@panel-border-radius - 1); - border-top-right-radius: (@panel-border-radius - 1); - - td:first-child, - th:first-child { - border-top-left-radius: (@panel-border-radius - 1); - } - td:last-child, - th:last-child { - border-top-right-radius: (@panel-border-radius - 1); - } - } - } - } - // Add border bottom radius for last one - > .table:last-child, - > .table-responsive:last-child > .table:last-child { - .border-bottom-radius((@panel-border-radius - 1)); - - > tbody:last-child, - > tfoot:last-child { - > tr:last-child { - border-bottom-left-radius: (@panel-border-radius - 1); - border-bottom-right-radius: (@panel-border-radius - 1); - - td:first-child, - th:first-child { - border-bottom-left-radius: (@panel-border-radius - 1); - } - td:last-child, - th:last-child { - border-bottom-right-radius: (@panel-border-radius - 1); - } - } - } - } - > .panel-body + .table, - > .panel-body + .table-responsive, - > .table + .panel-body, - > .table-responsive + .panel-body { - border-top: 1px solid @table-border-color; - } - > .table > tbody:first-child > tr:first-child th, - > .table > tbody:first-child > tr:first-child td { - border-top: 0; - } - > .table-bordered, - > .table-responsive > .table-bordered { - border: 0; - > thead, - > tbody, - > tfoot { - > tr { - > th:first-child, - > td:first-child { - border-left: 0; - } - > th:last-child, - > td:last-child { - border-right: 0; - } - } - } - > thead, - > tbody { - > tr:first-child { - > td, - > th { - border-bottom: 0; - } - } - } - > tbody, - > tfoot { - > tr:last-child { - > td, - > th { - border-bottom: 0; - } - } - } - } - > .table-responsive { - border: 0; - margin-bottom: 0; - } -} - - -// Collapsable panels (aka, accordion) -// -// Wrap a series of panels in `.panel-group` to turn them into an accordion with -// the help of our collapse JavaScript plugin. - -.panel-group { - margin-bottom: @line-height-computed; - - // Tighten up margin so it's only between panels - .panel { - margin-bottom: 0; - border-radius: @panel-border-radius; - - + .panel { - margin-top: 5px; - } - } - - .panel-heading { - border-bottom: 0; - - + .panel-collapse > .panel-body, - + .panel-collapse > .list-group { - border-top: 1px solid @panel-inner-border; - } - } - - .panel-footer { - border-top: 0; - + .panel-collapse .panel-body { - border-bottom: 1px solid @panel-inner-border; - } - } -} - - -// Contextual variations -.panel-default { - .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border); -} -.panel-primary { - .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border); -} -.panel-success { - .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border); -} -.panel-info { - .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border); -} -.panel-warning { - .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border); -} -.panel-danger { - .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border); -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/popovers.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/popovers.less deleted file mode 100644 index 3a62a645..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/popovers.less +++ /dev/null @@ -1,131 +0,0 @@ -// -// Popovers -// -------------------------------------------------- - - -.popover { - position: absolute; - top: 0; - left: 0; - z-index: @zindex-popover; - display: none; - max-width: @popover-max-width; - padding: 1px; - // Our parent element can be arbitrary since popovers are by default inserted as a sibling of their target element. - // So reset our font and text properties to avoid inheriting weird values. - .reset-text(); - font-size: @font-size-base; - - background-color: @popover-bg; - background-clip: padding-box; - border: 1px solid @popover-fallback-border-color; - border: 1px solid @popover-border-color; - border-radius: @border-radius-large; - .box-shadow(0 5px 10px rgba(0,0,0,.2)); - - // Offset the popover to account for the popover arrow - &.top { margin-top: -@popover-arrow-width; } - &.right { margin-left: @popover-arrow-width; } - &.bottom { margin-top: @popover-arrow-width; } - &.left { margin-left: -@popover-arrow-width; } -} - -.popover-title { - margin: 0; // reset heading margin - padding: 8px 14px; - font-size: @font-size-base; - background-color: @popover-title-bg; - border-bottom: 1px solid darken(@popover-title-bg, 5%); - border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0; -} - -.popover-content { - padding: 9px 14px; -} - -// Arrows -// -// .arrow is outer, .arrow:after is inner - -.popover > .arrow { - &, - &:after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; - } -} -.popover > .arrow { - border-width: @popover-arrow-outer-width; -} -.popover > .arrow:after { - border-width: @popover-arrow-width; - content: ""; -} - -.popover { - &.top > .arrow { - left: 50%; - margin-left: -@popover-arrow-outer-width; - border-bottom-width: 0; - border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback - border-top-color: @popover-arrow-outer-color; - bottom: -@popover-arrow-outer-width; - &:after { - content: " "; - bottom: 1px; - margin-left: -@popover-arrow-width; - border-bottom-width: 0; - border-top-color: @popover-arrow-color; - } - } - &.right > .arrow { - top: 50%; - left: -@popover-arrow-outer-width; - margin-top: -@popover-arrow-outer-width; - border-left-width: 0; - border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback - border-right-color: @popover-arrow-outer-color; - &:after { - content: " "; - left: 1px; - bottom: -@popover-arrow-width; - border-left-width: 0; - border-right-color: @popover-arrow-color; - } - } - &.bottom > .arrow { - left: 50%; - margin-left: -@popover-arrow-outer-width; - border-top-width: 0; - border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback - border-bottom-color: @popover-arrow-outer-color; - top: -@popover-arrow-outer-width; - &:after { - content: " "; - top: 1px; - margin-left: -@popover-arrow-width; - border-top-width: 0; - border-bottom-color: @popover-arrow-color; - } - } - - &.left > .arrow { - top: 50%; - right: -@popover-arrow-outer-width; - margin-top: -@popover-arrow-outer-width; - border-right-width: 0; - border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback - border-left-color: @popover-arrow-outer-color; - &:after { - content: " "; - right: 1px; - border-right-width: 0; - border-left-color: @popover-arrow-color; - bottom: -@popover-arrow-width; - } - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/print.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/print.less deleted file mode 100644 index 66e54ab4..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/print.less +++ /dev/null @@ -1,101 +0,0 @@ -/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ - -// ========================================================================== -// Print styles. -// Inlined to avoid the additional HTTP request: h5bp.com/r -// ========================================================================== - -@media print { - *, - *:before, - *:after { - background: transparent !important; - color: #000 !important; // Black prints faster: h5bp.com/s - box-shadow: none !important; - text-shadow: none !important; - } - - a, - a:visited { - text-decoration: underline; - } - - a[href]:after { - content: " (" attr(href) ")"; - } - - abbr[title]:after { - content: " (" attr(title) ")"; - } - - // Don't show links that are fragment identifiers, - // or use the `javascript:` pseudo protocol - a[href^="#"]:after, - a[href^="javascript:"]:after { - content: ""; - } - - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - - thead { - display: table-header-group; // h5bp.com/t - } - - tr, - img { - page-break-inside: avoid; - } - - img { - max-width: 100% !important; - } - - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - - h2, - h3 { - page-break-after: avoid; - } - - // Bootstrap specific changes start - - // Bootstrap components - .navbar { - display: none; - } - .btn, - .dropup > .btn { - > .caret { - border-top-color: #000 !important; - } - } - .label { - border: 1px solid #000; - } - - .table { - border-collapse: collapse !important; - - td, - th { - background-color: #fff !important; - } - } - .table-bordered { - th, - td { - border: 1px solid #ddd !important; - } - } - - // Bootstrap specific changes end -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/progress-bars.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/progress-bars.less deleted file mode 100644 index 8868a1fe..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/progress-bars.less +++ /dev/null @@ -1,87 +0,0 @@ -// -// Progress bars -// -------------------------------------------------- - - -// Bar animations -// ------------------------- - -// WebKit -@-webkit-keyframes progress-bar-stripes { - from { background-position: 40px 0; } - to { background-position: 0 0; } -} - -// Spec and IE10+ -@keyframes progress-bar-stripes { - from { background-position: 40px 0; } - to { background-position: 0 0; } -} - - -// Bar itself -// ------------------------- - -// Outer container -.progress { - overflow: hidden; - height: @line-height-computed; - margin-bottom: @line-height-computed; - background-color: @progress-bg; - border-radius: @progress-border-radius; - .box-shadow(inset 0 1px 2px rgba(0,0,0,.1)); -} - -// Bar of progress -.progress-bar { - float: left; - width: 0%; - height: 100%; - font-size: @font-size-small; - line-height: @line-height-computed; - color: @progress-bar-color; - text-align: center; - background-color: @progress-bar-bg; - .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15)); - .transition(width .6s ease); -} - -// Striped bars -// -// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the -// `.progress-bar-striped` class, which you just add to an existing -// `.progress-bar`. -.progress-striped .progress-bar, -.progress-bar-striped { - #gradient > .striped(); - background-size: 40px 40px; -} - -// Call animation for the active one -// -// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the -// `.progress-bar.active` approach. -.progress.active .progress-bar, -.progress-bar.active { - .animation(progress-bar-stripes 2s linear infinite); -} - - -// Variations -// ------------------------- - -.progress-bar-success { - .progress-bar-variant(@progress-bar-success-bg); -} - -.progress-bar-info { - .progress-bar-variant(@progress-bar-info-bg); -} - -.progress-bar-warning { - .progress-bar-variant(@progress-bar-warning-bg); -} - -.progress-bar-danger { - .progress-bar-variant(@progress-bar-danger-bg); -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/responsive-embed.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/responsive-embed.less deleted file mode 100644 index 080a5118..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/responsive-embed.less +++ /dev/null @@ -1,35 +0,0 @@ -// Embeds responsive -// -// Credit: Nicolas Gallagher and SUIT CSS. - -.embed-responsive { - position: relative; - display: block; - height: 0; - padding: 0; - overflow: hidden; - - .embed-responsive-item, - iframe, - embed, - object, - video { - position: absolute; - top: 0; - left: 0; - bottom: 0; - height: 100%; - width: 100%; - border: 0; - } -} - -// Modifier class for 16:9 aspect ratio -.embed-responsive-16by9 { - padding-bottom: 56.25%; -} - -// Modifier class for 4:3 aspect ratio -.embed-responsive-4by3 { - padding-bottom: 75%; -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/responsive-utilities.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/responsive-utilities.less deleted file mode 100644 index b1db31d7..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/responsive-utilities.less +++ /dev/null @@ -1,194 +0,0 @@ -// -// Responsive: Utility classes -// -------------------------------------------------- - - -// IE10 in Windows (Phone) 8 -// -// Support for responsive views via media queries is kind of borked in IE10, for -// Surface/desktop in split view and for Windows Phone 8. This particular fix -// must be accompanied by a snippet of JavaScript to sniff the user agent and -// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at -// our Getting Started page for more information on this bug. -// -// For more information, see the following: -// -// Issue: https://github.com/twbs/bootstrap/issues/10497 -// Docs: http://getbootstrap.com/getting-started/#support-ie10-width -// Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/ -// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/ - -@-ms-viewport { - width: device-width; -} - - -// Visibility utilities -// Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0 -.visible-xs, -.visible-sm, -.visible-md, -.visible-lg { - .responsive-invisibility(); -} - -.visible-xs-block, -.visible-xs-inline, -.visible-xs-inline-block, -.visible-sm-block, -.visible-sm-inline, -.visible-sm-inline-block, -.visible-md-block, -.visible-md-inline, -.visible-md-inline-block, -.visible-lg-block, -.visible-lg-inline, -.visible-lg-inline-block { - display: none !important; -} - -.visible-xs { - @media (max-width: @screen-xs-max) { - .responsive-visibility(); - } -} -.visible-xs-block { - @media (max-width: @screen-xs-max) { - display: block !important; - } -} -.visible-xs-inline { - @media (max-width: @screen-xs-max) { - display: inline !important; - } -} -.visible-xs-inline-block { - @media (max-width: @screen-xs-max) { - display: inline-block !important; - } -} - -.visible-sm { - @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) { - .responsive-visibility(); - } -} -.visible-sm-block { - @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) { - display: block !important; - } -} -.visible-sm-inline { - @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) { - display: inline !important; - } -} -.visible-sm-inline-block { - @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) { - display: inline-block !important; - } -} - -.visible-md { - @media (min-width: @screen-md-min) and (max-width: @screen-md-max) { - .responsive-visibility(); - } -} -.visible-md-block { - @media (min-width: @screen-md-min) and (max-width: @screen-md-max) { - display: block !important; - } -} -.visible-md-inline { - @media (min-width: @screen-md-min) and (max-width: @screen-md-max) { - display: inline !important; - } -} -.visible-md-inline-block { - @media (min-width: @screen-md-min) and (max-width: @screen-md-max) { - display: inline-block !important; - } -} - -.visible-lg { - @media (min-width: @screen-lg-min) { - .responsive-visibility(); - } -} -.visible-lg-block { - @media (min-width: @screen-lg-min) { - display: block !important; - } -} -.visible-lg-inline { - @media (min-width: @screen-lg-min) { - display: inline !important; - } -} -.visible-lg-inline-block { - @media (min-width: @screen-lg-min) { - display: inline-block !important; - } -} - -.hidden-xs { - @media (max-width: @screen-xs-max) { - .responsive-invisibility(); - } -} -.hidden-sm { - @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) { - .responsive-invisibility(); - } -} -.hidden-md { - @media (min-width: @screen-md-min) and (max-width: @screen-md-max) { - .responsive-invisibility(); - } -} -.hidden-lg { - @media (min-width: @screen-lg-min) { - .responsive-invisibility(); - } -} - - -// Print utilities -// -// Media queries are placed on the inside to be mixin-friendly. - -// Note: Deprecated .visible-print as of v3.2.0 -.visible-print { - .responsive-invisibility(); - - @media print { - .responsive-visibility(); - } -} -.visible-print-block { - display: none !important; - - @media print { - display: block !important; - } -} -.visible-print-inline { - display: none !important; - - @media print { - display: inline !important; - } -} -.visible-print-inline-block { - display: none !important; - - @media print { - display: inline-block !important; - } -} - -.hidden-print { - @media print { - .responsive-invisibility(); - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/scaffolding.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/scaffolding.less deleted file mode 100644 index 1929bfc5..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/scaffolding.less +++ /dev/null @@ -1,161 +0,0 @@ -// -// Scaffolding -// -------------------------------------------------- - - -// Reset the box-sizing -// -// Heads up! This reset may cause conflicts with some third-party widgets. -// For recommendations on resolving such conflicts, see -// http://getbootstrap.com/getting-started/#third-box-sizing -* { - .box-sizing(border-box); -} -*:before, -*:after { - .box-sizing(border-box); -} - - -// Body reset - -html { - font-size: 10px; - -webkit-tap-highlight-color: rgba(0,0,0,0); -} - -body { - font-family: @font-family-base; - font-size: @font-size-base; - line-height: @line-height-base; - color: @text-color; - background-color: @body-bg; -} - -// Reset fonts for relevant elements -input, -button, -select, -textarea { - font-family: inherit; - font-size: inherit; - line-height: inherit; -} - - -// Links - -a { - color: @link-color; - text-decoration: none; - - &:hover, - &:focus { - color: @link-hover-color; - text-decoration: @link-hover-decoration; - } - - &:focus { - .tab-focus(); - } -} - - -// Figures -// -// We reset this here because previously Normalize had no `figure` margins. This -// ensures we don't break anyone's use of the element. - -figure { - margin: 0; -} - - -// Images - -img { - vertical-align: middle; -} - -// Responsive images (ensure images don't scale beyond their parents) -.img-responsive { - .img-responsive(); -} - -// Rounded corners -.img-rounded { - border-radius: @border-radius-large; -} - -// Image thumbnails -// -// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`. -.img-thumbnail { - padding: @thumbnail-padding; - line-height: @line-height-base; - background-color: @thumbnail-bg; - border: 1px solid @thumbnail-border; - border-radius: @thumbnail-border-radius; - .transition(all .2s ease-in-out); - - // Keep them at most 100% wide - .img-responsive(inline-block); -} - -// Perfect circle -.img-circle { - border-radius: 50%; // set radius in percents -} - - -// Horizontal rules - -hr { - margin-top: @line-height-computed; - margin-bottom: @line-height-computed; - border: 0; - border-top: 1px solid @hr-border; -} - - -// Only display content to screen readers -// -// See: http://a11yproject.com/posts/how-to-hide-content/ - -.sr-only { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0,0,0,0); - border: 0; -} - -// Use in conjunction with .sr-only to only display content when it's focused. -// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 -// Credit: HTML5 Boilerplate - -.sr-only-focusable { - &:active, - &:focus { - position: static; - width: auto; - height: auto; - margin: 0; - overflow: visible; - clip: auto; - } -} - - -// iOS "clickable elements" fix for role="button" -// -// Fixes "clickability" issue (and more generally, the firing of events such as focus as well) -// for traditionally non-focusable elements with role="button" -// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile - -[role="button"] { - cursor: pointer; -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/tables.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/tables.less deleted file mode 100644 index 2242c036..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/tables.less +++ /dev/null @@ -1,234 +0,0 @@ -// -// Tables -// -------------------------------------------------- - - -table { - background-color: @table-bg; -} -caption { - padding-top: @table-cell-padding; - padding-bottom: @table-cell-padding; - color: @text-muted; - text-align: left; -} -th { - text-align: left; -} - - -// Baseline styles - -.table { - width: 100%; - max-width: 100%; - margin-bottom: @line-height-computed; - // Cells - > thead, - > tbody, - > tfoot { - > tr { - > th, - > td { - padding: @table-cell-padding; - line-height: @line-height-base; - vertical-align: top; - border-top: 1px solid @table-border-color; - } - } - } - // Bottom align for column headings - > thead > tr > th { - vertical-align: bottom; - border-bottom: 2px solid @table-border-color; - } - // Remove top border from thead by default - > caption + thead, - > colgroup + thead, - > thead:first-child { - > tr:first-child { - > th, - > td { - border-top: 0; - } - } - } - // Account for multiple tbody instances - > tbody + tbody { - border-top: 2px solid @table-border-color; - } - - // Nesting - .table { - background-color: @body-bg; - } -} - - -// Condensed table w/ half padding - -.table-condensed { - > thead, - > tbody, - > tfoot { - > tr { - > th, - > td { - padding: @table-condensed-cell-padding; - } - } - } -} - - -// Bordered version -// -// Add borders all around the table and between all the columns. - -.table-bordered { - border: 1px solid @table-border-color; - > thead, - > tbody, - > tfoot { - > tr { - > th, - > td { - border: 1px solid @table-border-color; - } - } - } - > thead > tr { - > th, - > td { - border-bottom-width: 2px; - } - } -} - - -// Zebra-striping -// -// Default zebra-stripe styles (alternating gray and transparent backgrounds) - -.table-striped { - > tbody > tr:nth-of-type(odd) { - background-color: @table-bg-accent; - } -} - - -// Hover effect -// -// Placed here since it has to come after the potential zebra striping - -.table-hover { - > tbody > tr:hover { - background-color: @table-bg-hover; - } -} - - -// Table cell sizing -// -// Reset default table behavior - -table col[class*="col-"] { - position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623) - float: none; - display: table-column; -} -table { - td, - th { - &[class*="col-"] { - position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623) - float: none; - display: table-cell; - } - } -} - - -// Table backgrounds -// -// Exact selectors below required to override `.table-striped` and prevent -// inheritance to nested tables. - -// Generate the contextual variants -.table-row-variant(active; @table-bg-active); -.table-row-variant(success; @state-success-bg); -.table-row-variant(info; @state-info-bg); -.table-row-variant(warning; @state-warning-bg); -.table-row-variant(danger; @state-danger-bg); - - -// Responsive tables -// -// Wrap your tables in `.table-responsive` and we'll make them mobile friendly -// by enabling horizontal scrolling. Only applies <768px. Everything above that -// will display normally. - -.table-responsive { - overflow-x: auto; - min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837) - - @media screen and (max-width: @screen-xs-max) { - width: 100%; - margin-bottom: (@line-height-computed * 0.75); - overflow-y: hidden; - -ms-overflow-style: -ms-autohiding-scrollbar; - border: 1px solid @table-border-color; - - // Tighten up spacing - > .table { - margin-bottom: 0; - - // Ensure the content doesn't wrap - > thead, - > tbody, - > tfoot { - > tr { - > th, - > td { - white-space: nowrap; - } - } - } - } - - // Special overrides for the bordered tables - > .table-bordered { - border: 0; - - // Nuke the appropriate borders so that the parent can handle them - > thead, - > tbody, - > tfoot { - > tr { - > th:first-child, - > td:first-child { - border-left: 0; - } - > th:last-child, - > td:last-child { - border-right: 0; - } - } - } - - // Only nuke the last row's bottom-border in `tbody` and `tfoot` since - // chances are there will be only one `tr` in a `thead` and that would - // remove the border altogether. - > tbody, - > tfoot { - > tr:last-child { - > th, - > td { - border-bottom: 0; - } - } - } - - } - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/theme.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/theme.less deleted file mode 100644 index 8f51d913..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/theme.less +++ /dev/null @@ -1,291 +0,0 @@ -/*! - * Bootstrap v3.3.6 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ - -// -// Load core variables and mixins -// -------------------------------------------------- - -@import "variables.less"; -@import "mixins.less"; - - -// -// Buttons -// -------------------------------------------------- - -// Common styles -.btn-default, -.btn-primary, -.btn-success, -.btn-info, -.btn-warning, -.btn-danger { - text-shadow: 0 -1px 0 rgba(0,0,0,.2); - @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075); - .box-shadow(@shadow); - - // Reset the shadow - &:active, - &.active { - .box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); - } - - &.disabled, - &[disabled], - fieldset[disabled] & { - .box-shadow(none); - } - - .badge { - text-shadow: none; - } -} - -// Mixin for generating new styles -.btn-styles(@btn-color: #555) { - #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%)); - .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620 - background-repeat: repeat-x; - border-color: darken(@btn-color, 14%); - - &:hover, - &:focus { - background-color: darken(@btn-color, 12%); - background-position: 0 -15px; - } - - &:active, - &.active { - background-color: darken(@btn-color, 12%); - border-color: darken(@btn-color, 14%); - } - - &.disabled, - &[disabled], - fieldset[disabled] & { - &, - &:hover, - &:focus, - &.focus, - &:active, - &.active { - background-color: darken(@btn-color, 12%); - background-image: none; - } - } -} - -// Common styles -.btn { - // Remove the gradient for the pressed/active state - &:active, - &.active { - background-image: none; - } -} - -// Apply the mixin to the buttons -.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; } -.btn-primary { .btn-styles(@btn-primary-bg); } -.btn-success { .btn-styles(@btn-success-bg); } -.btn-info { .btn-styles(@btn-info-bg); } -.btn-warning { .btn-styles(@btn-warning-bg); } -.btn-danger { .btn-styles(@btn-danger-bg); } - - -// -// Images -// -------------------------------------------------- - -.thumbnail, -.img-thumbnail { - .box-shadow(0 1px 2px rgba(0,0,0,.075)); -} - - -// -// Dropdowns -// -------------------------------------------------- - -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus { - #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%)); - background-color: darken(@dropdown-link-hover-bg, 5%); -} -.dropdown-menu > .active > a, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > a:focus { - #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%)); - background-color: darken(@dropdown-link-active-bg, 5%); -} - - -// -// Navbar -// -------------------------------------------------- - -// Default navbar -.navbar-default { - #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg); - .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered - border-radius: @navbar-border-radius; - @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075); - .box-shadow(@shadow); - - .navbar-nav > .open > a, - .navbar-nav > .active > a { - #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%)); - .box-shadow(inset 0 3px 9px rgba(0,0,0,.075)); - } -} -.navbar-brand, -.navbar-nav > li > a { - text-shadow: 0 1px 0 rgba(255,255,255,.25); -} - -// Inverted navbar -.navbar-inverse { - #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg); - .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257 - border-radius: @navbar-border-radius; - .navbar-nav > .open > a, - .navbar-nav > .active > a { - #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%)); - .box-shadow(inset 0 3px 9px rgba(0,0,0,.25)); - } - - .navbar-brand, - .navbar-nav > li > a { - text-shadow: 0 -1px 0 rgba(0,0,0,.25); - } -} - -// Undo rounded corners in static and fixed navbars -.navbar-static-top, -.navbar-fixed-top, -.navbar-fixed-bottom { - border-radius: 0; -} - -// Fix active state of dropdown items in collapsed mode -@media (max-width: @grid-float-breakpoint-max) { - .navbar .navbar-nav .open .dropdown-menu > .active > a { - &, - &:hover, - &:focus { - color: #fff; - #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%)); - } - } -} - - -// -// Alerts -// -------------------------------------------------- - -// Common styles -.alert { - text-shadow: 0 1px 0 rgba(255,255,255,.2); - @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05); - .box-shadow(@shadow); -} - -// Mixin for generating new styles -.alert-styles(@color) { - #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%)); - border-color: darken(@color, 15%); -} - -// Apply the mixin to the alerts -.alert-success { .alert-styles(@alert-success-bg); } -.alert-info { .alert-styles(@alert-info-bg); } -.alert-warning { .alert-styles(@alert-warning-bg); } -.alert-danger { .alert-styles(@alert-danger-bg); } - - -// -// Progress bars -// -------------------------------------------------- - -// Give the progress background some depth -.progress { - #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg) -} - -// Mixin for generating new styles -.progress-bar-styles(@color) { - #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%)); -} - -// Apply the mixin to the progress bars -.progress-bar { .progress-bar-styles(@progress-bar-bg); } -.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); } -.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); } -.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); } -.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); } - -// Reset the striped class because our mixins don't do multiple gradients and -// the above custom styles override the new `.progress-bar-striped` in v3.2.0. -.progress-bar-striped { - #gradient > .striped(); -} - - -// -// List groups -// -------------------------------------------------- - -.list-group { - border-radius: @border-radius-base; - .box-shadow(0 1px 2px rgba(0,0,0,.075)); -} -.list-group-item.active, -.list-group-item.active:hover, -.list-group-item.active:focus { - text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%); - #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%)); - border-color: darken(@list-group-active-border, 7.5%); - - .badge { - text-shadow: none; - } -} - - -// -// Panels -// -------------------------------------------------- - -// Common styles -.panel { - .box-shadow(0 1px 2px rgba(0,0,0,.05)); -} - -// Mixin for generating new styles -.panel-heading-styles(@color) { - #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%)); -} - -// Apply the mixin to the panel headings only -.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); } -.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); } -.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); } -.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); } -.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); } -.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); } - - -// -// Wells -// -------------------------------------------------- - -.well { - #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg); - border-color: darken(@well-bg, 10%); - @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1); - .box-shadow(@shadow); -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/thumbnails.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/thumbnails.less deleted file mode 100644 index 0713e67d..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/thumbnails.less +++ /dev/null @@ -1,36 +0,0 @@ -// -// Thumbnails -// -------------------------------------------------- - - -// Mixin and adjust the regular image class -.thumbnail { - display: block; - padding: @thumbnail-padding; - margin-bottom: @line-height-computed; - line-height: @line-height-base; - background-color: @thumbnail-bg; - border: 1px solid @thumbnail-border; - border-radius: @thumbnail-border-radius; - .transition(border .2s ease-in-out); - - > img, - a > img { - &:extend(.img-responsive); - margin-left: auto; - margin-right: auto; - } - - // Add a hover state for linked versions only - a&:hover, - a&:focus, - a&.active { - border-color: @link-color; - } - - // Image captions - .caption { - padding: @thumbnail-caption-padding; - color: @thumbnail-caption-color; - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/tooltip.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/tooltip.less deleted file mode 100644 index b48d63e0..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/tooltip.less +++ /dev/null @@ -1,101 +0,0 @@ -// -// Tooltips -// -------------------------------------------------- - - -// Base class -.tooltip { - position: absolute; - z-index: @zindex-tooltip; - display: block; - // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element. - // So reset our font and text properties to avoid inheriting weird values. - .reset-text(); - font-size: @font-size-small; - - .opacity(0); - - &.in { .opacity(@tooltip-opacity); } - &.top { margin-top: -3px; padding: @tooltip-arrow-width 0; } - &.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; } - &.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; } - &.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; } -} - -// Wrapper for the tooltip content -.tooltip-inner { - max-width: @tooltip-max-width; - padding: 3px 8px; - color: @tooltip-color; - text-align: center; - background-color: @tooltip-bg; - border-radius: @border-radius-base; -} - -// Arrows -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -// Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as of v3.3.1 -.tooltip { - &.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -@tooltip-arrow-width; - border-width: @tooltip-arrow-width @tooltip-arrow-width 0; - border-top-color: @tooltip-arrow-color; - } - &.top-left .tooltip-arrow { - bottom: 0; - right: @tooltip-arrow-width; - margin-bottom: -@tooltip-arrow-width; - border-width: @tooltip-arrow-width @tooltip-arrow-width 0; - border-top-color: @tooltip-arrow-color; - } - &.top-right .tooltip-arrow { - bottom: 0; - left: @tooltip-arrow-width; - margin-bottom: -@tooltip-arrow-width; - border-width: @tooltip-arrow-width @tooltip-arrow-width 0; - border-top-color: @tooltip-arrow-color; - } - &.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -@tooltip-arrow-width; - border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0; - border-right-color: @tooltip-arrow-color; - } - &.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -@tooltip-arrow-width; - border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width; - border-left-color: @tooltip-arrow-color; - } - &.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -@tooltip-arrow-width; - border-width: 0 @tooltip-arrow-width @tooltip-arrow-width; - border-bottom-color: @tooltip-arrow-color; - } - &.bottom-left .tooltip-arrow { - top: 0; - right: @tooltip-arrow-width; - margin-top: -@tooltip-arrow-width; - border-width: 0 @tooltip-arrow-width @tooltip-arrow-width; - border-bottom-color: @tooltip-arrow-color; - } - &.bottom-right .tooltip-arrow { - top: 0; - left: @tooltip-arrow-width; - margin-top: -@tooltip-arrow-width; - border-width: 0 @tooltip-arrow-width @tooltip-arrow-width; - border-bottom-color: @tooltip-arrow-color; - } -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/type.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/type.less deleted file mode 100644 index 0d4fee48..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/type.less +++ /dev/null @@ -1,302 +0,0 @@ -// -// Typography -// -------------------------------------------------- - - -// Headings -// ------------------------- - -h1, h2, h3, h4, h5, h6, -.h1, .h2, .h3, .h4, .h5, .h6 { - font-family: @headings-font-family; - font-weight: @headings-font-weight; - line-height: @headings-line-height; - color: @headings-color; - - small, - .small { - font-weight: normal; - line-height: 1; - color: @headings-small-color; - } -} - -h1, .h1, -h2, .h2, -h3, .h3 { - margin-top: @line-height-computed; - margin-bottom: (@line-height-computed / 2); - - small, - .small { - font-size: 65%; - } -} -h4, .h4, -h5, .h5, -h6, .h6 { - margin-top: (@line-height-computed / 2); - margin-bottom: (@line-height-computed / 2); - - small, - .small { - font-size: 75%; - } -} - -h1, .h1 { font-size: @font-size-h1; } -h2, .h2 { font-size: @font-size-h2; } -h3, .h3 { font-size: @font-size-h3; } -h4, .h4 { font-size: @font-size-h4; } -h5, .h5 { font-size: @font-size-h5; } -h6, .h6 { font-size: @font-size-h6; } - - -// Body text -// ------------------------- - -p { - margin: 0 0 (@line-height-computed / 2); -} - -.lead { - margin-bottom: @line-height-computed; - font-size: floor((@font-size-base * 1.15)); - font-weight: 300; - line-height: 1.4; - - @media (min-width: @screen-sm-min) { - font-size: (@font-size-base * 1.5); - } -} - - -// Emphasis & misc -// ------------------------- - -// Ex: (12px small font / 14px base font) * 100% = about 85% -small, -.small { - font-size: floor((100% * @font-size-small / @font-size-base)); -} - -mark, -.mark { - background-color: @state-warning-bg; - padding: .2em; -} - -// Alignment -.text-left { text-align: left; } -.text-right { text-align: right; } -.text-center { text-align: center; } -.text-justify { text-align: justify; } -.text-nowrap { white-space: nowrap; } - -// Transformation -.text-lowercase { text-transform: lowercase; } -.text-uppercase { text-transform: uppercase; } -.text-capitalize { text-transform: capitalize; } - -// Contextual colors -.text-muted { - color: @text-muted; -} -.text-primary { - .text-emphasis-variant(@brand-primary); -} -.text-success { - .text-emphasis-variant(@state-success-text); -} -.text-info { - .text-emphasis-variant(@state-info-text); -} -.text-warning { - .text-emphasis-variant(@state-warning-text); -} -.text-danger { - .text-emphasis-variant(@state-danger-text); -} - -// Contextual backgrounds -// For now we'll leave these alongside the text classes until v4 when we can -// safely shift things around (per SemVer rules). -.bg-primary { - // Given the contrast here, this is the only class to have its color inverted - // automatically. - color: #fff; - .bg-variant(@brand-primary); -} -.bg-success { - .bg-variant(@state-success-bg); -} -.bg-info { - .bg-variant(@state-info-bg); -} -.bg-warning { - .bg-variant(@state-warning-bg); -} -.bg-danger { - .bg-variant(@state-danger-bg); -} - - -// Page header -// ------------------------- - -.page-header { - padding-bottom: ((@line-height-computed / 2) - 1); - margin: (@line-height-computed * 2) 0 @line-height-computed; - border-bottom: 1px solid @page-header-border-color; -} - - -// Lists -// ------------------------- - -// Unordered and Ordered lists -ul, -ol { - margin-top: 0; - margin-bottom: (@line-height-computed / 2); - ul, - ol { - margin-bottom: 0; - } -} - -// List options - -// Unstyled keeps list items block level, just removes default browser padding and list-style -.list-unstyled { - padding-left: 0; - list-style: none; -} - -// Inline turns list items into inline-block -.list-inline { - .list-unstyled(); - margin-left: -5px; - - > li { - display: inline-block; - padding-left: 5px; - padding-right: 5px; - } -} - -// Description Lists -dl { - margin-top: 0; // Remove browser default - margin-bottom: @line-height-computed; -} -dt, -dd { - line-height: @line-height-base; -} -dt { - font-weight: bold; -} -dd { - margin-left: 0; // Undo browser default -} - -// Horizontal description lists -// -// Defaults to being stacked without any of the below styles applied, until the -// grid breakpoint is reached (default of ~768px). - -.dl-horizontal { - dd { - &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present - } - - @media (min-width: @dl-horizontal-breakpoint) { - dt { - float: left; - width: (@dl-horizontal-offset - 20); - clear: left; - text-align: right; - .text-overflow(); - } - dd { - margin-left: @dl-horizontal-offset; - } - } -} - - -// Misc -// ------------------------- - -// Abbreviations and acronyms -abbr[title], -// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257 -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted @abbr-border-color; -} -.initialism { - font-size: 90%; - .text-uppercase(); -} - -// Blockquotes -blockquote { - padding: (@line-height-computed / 2) @line-height-computed; - margin: 0 0 @line-height-computed; - font-size: @blockquote-font-size; - border-left: 5px solid @blockquote-border-color; - - p, - ul, - ol { - &:last-child { - margin-bottom: 0; - } - } - - // Note: Deprecated small and .small as of v3.1.0 - // Context: https://github.com/twbs/bootstrap/issues/11660 - footer, - small, - .small { - display: block; - font-size: 80%; // back to default font-size - line-height: @line-height-base; - color: @blockquote-small-color; - - &:before { - content: '\2014 \00A0'; // em dash, nbsp - } - } -} - -// Opposite alignment of blockquote -// -// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0. -.blockquote-reverse, -blockquote.pull-right { - padding-right: 15px; - padding-left: 0; - border-right: 5px solid @blockquote-border-color; - border-left: 0; - text-align: right; - - // Account for citation - footer, - small, - .small { - &:before { content: ''; } - &:after { - content: '\00A0 \2014'; // nbsp, em dash - } - } -} - -// Addresses -address { - margin-bottom: @line-height-computed; - font-style: normal; - line-height: @line-height-base; -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/utilities.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/utilities.less deleted file mode 100644 index 7a8ca27a..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/utilities.less +++ /dev/null @@ -1,55 +0,0 @@ -// -// Utility classes -// -------------------------------------------------- - - -// Floats -// ------------------------- - -.clearfix { - .clearfix(); -} -.center-block { - .center-block(); -} -.pull-right { - float: right !important; -} -.pull-left { - float: left !important; -} - - -// Toggling content -// ------------------------- - -// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1 -.hide { - display: none !important; -} -.show { - display: block !important; -} -.invisible { - visibility: hidden; -} -.text-hide { - .text-hide(); -} - - -// Hide from screenreaders and browsers -// -// Credit: HTML5 Boilerplate - -.hidden { - display: none !important; -} - - -// For Affix plugin -// ------------------------- - -.affix { - position: fixed; -} diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/variables.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/variables.less deleted file mode 100644 index b057ef5b..00000000 --- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/variables.less +++ /dev/null @@ -1,869 +0,0 @@ -// -// Variables -// -------------------------------------------------- - - -//== Colors -// -//## Gray and brand colors for use across Bootstrap. - -@gray-base: #000; -@gray-darker: lighten(@gray-base, 13.5%); // #222 -@gray-dark: lighten(@gray-base, 20%); // #333 -@gray: lighten(@gray-base, 33.5%); // #555 -@gray-light: lighten(@gray-base, 46.7%); // #777 -@gray-lighter: lighten(@gray-base, 93.5%); // #eee - -@brand-primary: darken(#428bca, 6.5%); // #337ab7 -@brand-success: #5cb85c; -@brand-info: #5bc0de; -@brand-warning: #f0ad4e; -@brand-danger: #d9534f; - - -//== Scaffolding -// -//## Settings for some of the most global styles. - -//** Background color for ``. -@body-bg: #fff; -//** Global text color on ``. -@text-color: @gray-dark; - -//** Global textual link color. -@link-color: @brand-primary; -//** Link hover color set via `darken()` function. -@link-hover-color: darken(@link-color, 15%); -//** Link hover decoration. -@link-hover-decoration: underline; - - -//== Typography -// -//## Font, line-height, and color for body text, headings, and more. - -@font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif; -@font-family-serif: Georgia, "Times New Roman", Times, serif; -//** Default monospace fonts for ``, ``, and `
`.
-@font-family-monospace:   Menlo, Monaco, Consolas, "Courier New", monospace;
-@font-family-base:        @font-family-sans-serif;
-
-@font-size-base:          14px;
-@font-size-large:         ceil((@font-size-base * 1.25)); // ~18px
-@font-size-small:         ceil((@font-size-base * 0.85)); // ~12px
-
-@font-size-h1:            floor((@font-size-base * 2.6)); // ~36px
-@font-size-h2:            floor((@font-size-base * 2.15)); // ~30px
-@font-size-h3:            ceil((@font-size-base * 1.7)); // ~24px
-@font-size-h4:            ceil((@font-size-base * 1.25)); // ~18px
-@font-size-h5:            @font-size-base;
-@font-size-h6:            ceil((@font-size-base * 0.85)); // ~12px
-
-//** Unit-less `line-height` for use in components like buttons.
-@line-height-base:        1.428571429; // 20/14
-//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
-@line-height-computed:    floor((@font-size-base * @line-height-base)); // ~20px
-
-//** By default, this inherits from the ``.
-@headings-font-family:    inherit;
-@headings-font-weight:    500;
-@headings-line-height:    1.1;
-@headings-color:          inherit;
-
-
-//== Iconography
-//
-//## Specify custom location and filename of the included Glyphicons icon font. Useful for those including Bootstrap via Bower.
-
-//** Load fonts from this directory.
-@icon-font-path:          "../fonts/";
-//** File name for all font files.
-@icon-font-name:          "glyphicons-halflings-regular";
-//** Element ID within SVG icon file.
-@icon-font-svg-id:        "glyphicons_halflingsregular";
-
-
-//== Components
-//
-//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
-
-@padding-base-vertical:     6px;
-@padding-base-horizontal:   12px;
-
-@padding-large-vertical:    10px;
-@padding-large-horizontal:  16px;
-
-@padding-small-vertical:    5px;
-@padding-small-horizontal:  10px;
-
-@padding-xs-vertical:       1px;
-@padding-xs-horizontal:     5px;
-
-@line-height-large:         1.3333333; // extra decimals for Win 8.1 Chrome
-@line-height-small:         1.5;
-
-@border-radius-base:        4px;
-@border-radius-large:       6px;
-@border-radius-small:       3px;
-
-//** Global color for active items (e.g., navs or dropdowns).
-@component-active-color:    #fff;
-//** Global background color for active items (e.g., navs or dropdowns).
-@component-active-bg:       @brand-primary;
-
-//** Width of the `border` for generating carets that indicator dropdowns.
-@caret-width-base:          4px;
-//** Carets increase slightly in size for larger components.
-@caret-width-large:         5px;
-
-
-//== Tables
-//
-//## Customizes the `.table` component with basic values, each used across all table variations.
-
-//** Padding for ``s and ``s.
-@table-cell-padding:            8px;
-//** Padding for cells in `.table-condensed`.
-@table-condensed-cell-padding:  5px;
-
-//** Default background color used for all tables.
-@table-bg:                      transparent;
-//** Background color used for `.table-striped`.
-@table-bg-accent:               #f9f9f9;
-//** Background color used for `.table-hover`.
-@table-bg-hover:                #f5f5f5;
-@table-bg-active:               @table-bg-hover;
-
-//** Border color for table and cell borders.
-@table-border-color:            #ddd;
-
-
-//== Buttons
-//
-//## For each of Bootstrap's buttons, define text, background and border color.
-
-@btn-font-weight:                normal;
-
-@btn-default-color:              #333;
-@btn-default-bg:                 #fff;
-@btn-default-border:             #ccc;
-
-@btn-primary-color:              #fff;
-@btn-primary-bg:                 @brand-primary;
-@btn-primary-border:             darken(@btn-primary-bg, 5%);
-
-@btn-success-color:              #fff;
-@btn-success-bg:                 @brand-success;
-@btn-success-border:             darken(@btn-success-bg, 5%);
-
-@btn-info-color:                 #fff;
-@btn-info-bg:                    @brand-info;
-@btn-info-border:                darken(@btn-info-bg, 5%);
-
-@btn-warning-color:              #fff;
-@btn-warning-bg:                 @brand-warning;
-@btn-warning-border:             darken(@btn-warning-bg, 5%);
-
-@btn-danger-color:               #fff;
-@btn-danger-bg:                  @brand-danger;
-@btn-danger-border:              darken(@btn-danger-bg, 5%);
-
-@btn-link-disabled-color:        @gray-light;
-
-// Allows for customizing button radius independently from global border radius
-@btn-border-radius-base:         @border-radius-base;
-@btn-border-radius-large:        @border-radius-large;
-@btn-border-radius-small:        @border-radius-small;
-
-
-//== Forms
-//
-//##
-
-//** `` background color
-@input-bg:                       #fff;
-//** `` background color
-@input-bg-disabled:              @gray-lighter;
-
-//** Text color for ``s
-@input-color:                    @gray;
-//** `` border color
-@input-border:                   #ccc;
-
-// TODO: Rename `@input-border-radius` to `@input-border-radius-base` in v4
-//** Default `.form-control` border radius
-// This has no effect on ``s in CSS.
-@input-border-radius:            @border-radius-base;
-//** Large `.form-control` border radius
-@input-border-radius-large:      @border-radius-large;
-//** Small `.form-control` border radius
-@input-border-radius-small:      @border-radius-small;
-
-//** Border color for inputs on focus
-@input-border-focus:             #66afe9;
-
-//** Placeholder text color
-@input-color-placeholder:        #999;
-
-//** Default `.form-control` height
-@input-height-base:              (@line-height-computed + (@padding-base-vertical * 2) + 2);
-//** Large `.form-control` height
-@input-height-large:             (ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2);
-//** Small `.form-control` height
-@input-height-small:             (floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2);
-
-//** `.form-group` margin
-@form-group-margin-bottom:       15px;
-
-@legend-color:                   @gray-dark;
-@legend-border-color:            #e5e5e5;
-
-//** Background color for textual input addons
-@input-group-addon-bg:           @gray-lighter;
-//** Border color for textual input addons
-@input-group-addon-border-color: @input-border;
-
-//** Disabled cursor for form controls and buttons.
-@cursor-disabled:                not-allowed;
-
-
-//== Dropdowns
-//
-//## Dropdown menu container and contents.
-
-//** Background for the dropdown menu.
-@dropdown-bg:                    #fff;
-//** Dropdown menu `border-color`.
-@dropdown-border:                rgba(0,0,0,.15);
-//** Dropdown menu `border-color` **for IE8**.
-@dropdown-fallback-border:       #ccc;
-//** Divider color for between dropdown items.
-@dropdown-divider-bg:            #e5e5e5;
-
-//** Dropdown link text color.
-@dropdown-link-color:            @gray-dark;
-//** Hover color for dropdown links.
-@dropdown-link-hover-color:      darken(@gray-dark, 5%);
-//** Hover background for dropdown links.
-@dropdown-link-hover-bg:         #f5f5f5;
-
-//** Active dropdown menu item text color.
-@dropdown-link-active-color:     @component-active-color;
-//** Active dropdown menu item background color.
-@dropdown-link-active-bg:        @component-active-bg;
-
-//** Disabled dropdown menu item background color.
-@dropdown-link-disabled-color:   @gray-light;
-
-//** Text color for headers within dropdown menus.
-@dropdown-header-color:          @gray-light;
-
-//** Deprecated `@dropdown-caret-color` as of v3.1.0
-@dropdown-caret-color:           #000;
-
-
-//-- Z-index master list
-//
-// Warning: Avoid customizing these values. They're used for a bird's eye view
-// of components dependent on the z-axis and are designed to all work together.
-//
-// Note: These variables are not generated into the Customizer.
-
-@zindex-navbar:            1000;
-@zindex-dropdown:          1000;
-@zindex-popover:           1060;
-@zindex-tooltip:           1070;
-@zindex-navbar-fixed:      1030;
-@zindex-modal-background:  1040;
-@zindex-modal:             1050;
-
-
-//== Media queries breakpoints
-//
-//## Define the breakpoints at which your layout will change, adapting to different screen sizes.
-
-// Extra small screen / phone
-//** Deprecated `@screen-xs` as of v3.0.1
-@screen-xs:                  480px;
-//** Deprecated `@screen-xs-min` as of v3.2.0
-@screen-xs-min:              @screen-xs;
-//** Deprecated `@screen-phone` as of v3.0.1
-@screen-phone:               @screen-xs-min;
-
-// Small screen / tablet
-//** Deprecated `@screen-sm` as of v3.0.1
-@screen-sm:                  768px;
-@screen-sm-min:              @screen-sm;
-//** Deprecated `@screen-tablet` as of v3.0.1
-@screen-tablet:              @screen-sm-min;
-
-// Medium screen / desktop
-//** Deprecated `@screen-md` as of v3.0.1
-@screen-md:                  992px;
-@screen-md-min:              @screen-md;
-//** Deprecated `@screen-desktop` as of v3.0.1
-@screen-desktop:             @screen-md-min;
-
-// Large screen / wide desktop
-//** Deprecated `@screen-lg` as of v3.0.1
-@screen-lg:                  1200px;
-@screen-lg-min:              @screen-lg;
-//** Deprecated `@screen-lg-desktop` as of v3.0.1
-@screen-lg-desktop:          @screen-lg-min;
-
-// So media queries don't overlap when required, provide a maximum
-@screen-xs-max:              (@screen-sm-min - 1);
-@screen-sm-max:              (@screen-md-min - 1);
-@screen-md-max:              (@screen-lg-min - 1);
-
-
-//== Grid system
-//
-//## Define your custom responsive grid.
-
-//** Number of columns in the grid.
-@grid-columns:              12;
-//** Padding between columns. Gets divided in half for the left and right.
-@grid-gutter-width:         30px;
-// Navbar collapse
-//** Point at which the navbar becomes uncollapsed.
-@grid-float-breakpoint:     @screen-sm-min;
-//** Point at which the navbar begins collapsing.
-@grid-float-breakpoint-max: (@grid-float-breakpoint - 1);
-
-
-//== Container sizes
-//
-//## Define the maximum width of `.container` for different screen sizes.
-
-// Small screen / tablet
-@container-tablet:             (720px + @grid-gutter-width);
-//** For `@screen-sm-min` and up.
-@container-sm:                 @container-tablet;
-
-// Medium screen / desktop
-@container-desktop:            (940px + @grid-gutter-width);
-//** For `@screen-md-min` and up.
-@container-md:                 @container-desktop;
-
-// Large screen / wide desktop
-@container-large-desktop:      (1140px + @grid-gutter-width);
-//** For `@screen-lg-min` and up.
-@container-lg:                 @container-large-desktop;
-
-
-//== Navbar
-//
-//##
-
-// Basics of a navbar
-@navbar-height:                    50px;
-@navbar-margin-bottom:             @line-height-computed;
-@navbar-border-radius:             @border-radius-base;
-@navbar-padding-horizontal:        floor((@grid-gutter-width / 2));
-@navbar-padding-vertical:          ((@navbar-height - @line-height-computed) / 2);
-@navbar-collapse-max-height:       340px;
-
-@navbar-default-color:             #777;
-@navbar-default-bg:                #f8f8f8;
-@navbar-default-border:            darken(@navbar-default-bg, 6.5%);
-
-// Navbar links
-@navbar-default-link-color:                #777;
-@navbar-default-link-hover-color:          #333;
-@navbar-default-link-hover-bg:             transparent;
-@navbar-default-link-active-color:         #555;
-@navbar-default-link-active-bg:            darken(@navbar-default-bg, 6.5%);
-@navbar-default-link-disabled-color:       #ccc;
-@navbar-default-link-disabled-bg:          transparent;
-
-// Navbar brand label
-@navbar-default-brand-color:               @navbar-default-link-color;
-@navbar-default-brand-hover-color:         darken(@navbar-default-brand-color, 10%);
-@navbar-default-brand-hover-bg:            transparent;
-
-// Navbar toggle
-@navbar-default-toggle-hover-bg:           #ddd;
-@navbar-default-toggle-icon-bar-bg:        #888;
-@navbar-default-toggle-border-color:       #ddd;
-
-
-//=== Inverted navbar
-// Reset inverted navbar basics
-@navbar-inverse-color:                      lighten(@gray-light, 15%);
-@navbar-inverse-bg:                         #222;
-@navbar-inverse-border:                     darken(@navbar-inverse-bg, 10%);
-
-// Inverted navbar links
-@navbar-inverse-link-color:                 lighten(@gray-light, 15%);
-@navbar-inverse-link-hover-color:           #fff;
-@navbar-inverse-link-hover-bg:              transparent;
-@navbar-inverse-link-active-color:          @navbar-inverse-link-hover-color;
-@navbar-inverse-link-active-bg:             darken(@navbar-inverse-bg, 10%);
-@navbar-inverse-link-disabled-color:        #444;
-@navbar-inverse-link-disabled-bg:           transparent;
-
-// Inverted navbar brand label
-@navbar-inverse-brand-color:                @navbar-inverse-link-color;
-@navbar-inverse-brand-hover-color:          #fff;
-@navbar-inverse-brand-hover-bg:             transparent;
-
-// Inverted navbar toggle
-@navbar-inverse-toggle-hover-bg:            #333;
-@navbar-inverse-toggle-icon-bar-bg:         #fff;
-@navbar-inverse-toggle-border-color:        #333;
-
-
-//== Navs
-//
-//##
-
-//=== Shared nav styles
-@nav-link-padding:                          10px 15px;
-@nav-link-hover-bg:                         @gray-lighter;
-
-@nav-disabled-link-color:                   @gray-light;
-@nav-disabled-link-hover-color:             @gray-light;
-
-//== Tabs
-@nav-tabs-border-color:                     #ddd;
-
-@nav-tabs-link-hover-border-color:          @gray-lighter;
-
-@nav-tabs-active-link-hover-bg:             @body-bg;
-@nav-tabs-active-link-hover-color:          @gray;
-@nav-tabs-active-link-hover-border-color:   #ddd;
-
-@nav-tabs-justified-link-border-color:            #ddd;
-@nav-tabs-justified-active-link-border-color:     @body-bg;
-
-//== Pills
-@nav-pills-border-radius:                   @border-radius-base;
-@nav-pills-active-link-hover-bg:            @component-active-bg;
-@nav-pills-active-link-hover-color:         @component-active-color;
-
-
-//== Pagination
-//
-//##
-
-@pagination-color:                     @link-color;
-@pagination-bg:                        #fff;
-@pagination-border:                    #ddd;
-
-@pagination-hover-color:               @link-hover-color;
-@pagination-hover-bg:                  @gray-lighter;
-@pagination-hover-border:              #ddd;
-
-@pagination-active-color:              #fff;
-@pagination-active-bg:                 @brand-primary;
-@pagination-active-border:             @brand-primary;
-
-@pagination-disabled-color:            @gray-light;
-@pagination-disabled-bg:               #fff;
-@pagination-disabled-border:           #ddd;
-
-
-//== Pager
-//
-//##
-
-@pager-bg:                             @pagination-bg;
-@pager-border:                         @pagination-border;
-@pager-border-radius:                  15px;
-
-@pager-hover-bg:                       @pagination-hover-bg;
-
-@pager-active-bg:                      @pagination-active-bg;
-@pager-active-color:                   @pagination-active-color;
-
-@pager-disabled-color:                 @pagination-disabled-color;
-
-
-//== Jumbotron
-//
-//##
-
-@jumbotron-padding:              30px;
-@jumbotron-color:                inherit;
-@jumbotron-bg:                   @gray-lighter;
-@jumbotron-heading-color:        inherit;
-@jumbotron-font-size:            ceil((@font-size-base * 1.5));
-@jumbotron-heading-font-size:    ceil((@font-size-base * 4.5));
-
-
-//== Form states and alerts
-//
-//## Define colors for form feedback states and, by default, alerts.
-
-@state-success-text:             #3c763d;
-@state-success-bg:               #dff0d8;
-@state-success-border:           darken(spin(@state-success-bg, -10), 5%);
-
-@state-info-text:                #31708f;
-@state-info-bg:                  #d9edf7;
-@state-info-border:              darken(spin(@state-info-bg, -10), 7%);
-
-@state-warning-text:             #8a6d3b;
-@state-warning-bg:               #fcf8e3;
-@state-warning-border:           darken(spin(@state-warning-bg, -10), 5%);
-
-@state-danger-text:              #a94442;
-@state-danger-bg:                #f2dede;
-@state-danger-border:            darken(spin(@state-danger-bg, -10), 5%);
-
-
-//== Tooltips
-//
-//##
-
-//** Tooltip max width
-@tooltip-max-width:           200px;
-//** Tooltip text color
-@tooltip-color:               #fff;
-//** Tooltip background color
-@tooltip-bg:                  #000;
-@tooltip-opacity:             .9;
-
-//** Tooltip arrow width
-@tooltip-arrow-width:         5px;
-//** Tooltip arrow color
-@tooltip-arrow-color:         @tooltip-bg;
-
-
-//== Popovers
-//
-//##
-
-//** Popover body background color
-@popover-bg:                          #fff;
-//** Popover maximum width
-@popover-max-width:                   276px;
-//** Popover border color
-@popover-border-color:                rgba(0,0,0,.2);
-//** Popover fallback border color
-@popover-fallback-border-color:       #ccc;
-
-//** Popover title background color
-@popover-title-bg:                    darken(@popover-bg, 3%);
-
-//** Popover arrow width
-@popover-arrow-width:                 10px;
-//** Popover arrow color
-@popover-arrow-color:                 @popover-bg;
-
-//** Popover outer arrow width
-@popover-arrow-outer-width:           (@popover-arrow-width + 1);
-//** Popover outer arrow color
-@popover-arrow-outer-color:           fadein(@popover-border-color, 5%);
-//** Popover outer arrow fallback color
-@popover-arrow-outer-fallback-color:  darken(@popover-fallback-border-color, 20%);
-
-
-//== Labels
-//
-//##
-
-//** Default label background color
-@label-default-bg:            @gray-light;
-//** Primary label background color
-@label-primary-bg:            @brand-primary;
-//** Success label background color
-@label-success-bg:            @brand-success;
-//** Info label background color
-@label-info-bg:               @brand-info;
-//** Warning label background color
-@label-warning-bg:            @brand-warning;
-//** Danger label background color
-@label-danger-bg:             @brand-danger;
-
-//** Default label text color
-@label-color:                 #fff;
-//** Default text color of a linked label
-@label-link-hover-color:      #fff;
-
-
-//== Modals
-//
-//##
-
-//** Padding applied to the modal body
-@modal-inner-padding:         15px;
-
-//** Padding applied to the modal title
-@modal-title-padding:         15px;
-//** Modal title line-height
-@modal-title-line-height:     @line-height-base;
-
-//** Background color of modal content area
-@modal-content-bg:                             #fff;
-//** Modal content border color
-@modal-content-border-color:                   rgba(0,0,0,.2);
-//** Modal content border color **for IE8**
-@modal-content-fallback-border-color:          #999;
-
-//** Modal backdrop background color
-@modal-backdrop-bg:           #000;
-//** Modal backdrop opacity
-@modal-backdrop-opacity:      .5;
-//** Modal header border color
-@modal-header-border-color:   #e5e5e5;
-//** Modal footer border color
-@modal-footer-border-color:   @modal-header-border-color;
-
-@modal-lg:                    900px;
-@modal-md:                    600px;
-@modal-sm:                    300px;
-
-
-//== Alerts
-//
-//## Define alert colors, border radius, and padding.
-
-@alert-padding:               15px;
-@alert-border-radius:         @border-radius-base;
-@alert-link-font-weight:      bold;
-
-@alert-success-bg:            @state-success-bg;
-@alert-success-text:          @state-success-text;
-@alert-success-border:        @state-success-border;
-
-@alert-info-bg:               @state-info-bg;
-@alert-info-text:             @state-info-text;
-@alert-info-border:           @state-info-border;
-
-@alert-warning-bg:            @state-warning-bg;
-@alert-warning-text:          @state-warning-text;
-@alert-warning-border:        @state-warning-border;
-
-@alert-danger-bg:             @state-danger-bg;
-@alert-danger-text:           @state-danger-text;
-@alert-danger-border:         @state-danger-border;
-
-
-//== Progress bars
-//
-//##
-
-//** Background color of the whole progress component
-@progress-bg:                 #f5f5f5;
-//** Progress bar text color
-@progress-bar-color:          #fff;
-//** Variable for setting rounded corners on progress bar.
-@progress-border-radius:      @border-radius-base;
-
-//** Default progress bar color
-@progress-bar-bg:             @brand-primary;
-//** Success progress bar color
-@progress-bar-success-bg:     @brand-success;
-//** Warning progress bar color
-@progress-bar-warning-bg:     @brand-warning;
-//** Danger progress bar color
-@progress-bar-danger-bg:      @brand-danger;
-//** Info progress bar color
-@progress-bar-info-bg:        @brand-info;
-
-
-//== List group
-//
-//##
-
-//** Background color on `.list-group-item`
-@list-group-bg:                 #fff;
-//** `.list-group-item` border color
-@list-group-border:             #ddd;
-//** List group border radius
-@list-group-border-radius:      @border-radius-base;
-
-//** Background color of single list items on hover
-@list-group-hover-bg:           #f5f5f5;
-//** Text color of active list items
-@list-group-active-color:       @component-active-color;
-//** Background color of active list items
-@list-group-active-bg:          @component-active-bg;
-//** Border color of active list elements
-@list-group-active-border:      @list-group-active-bg;
-//** Text color for content within active list items
-@list-group-active-text-color:  lighten(@list-group-active-bg, 40%);
-
-//** Text color of disabled list items
-@list-group-disabled-color:      @gray-light;
-//** Background color of disabled list items
-@list-group-disabled-bg:         @gray-lighter;
-//** Text color for content within disabled list items
-@list-group-disabled-text-color: @list-group-disabled-color;
-
-@list-group-link-color:         #555;
-@list-group-link-hover-color:   @list-group-link-color;
-@list-group-link-heading-color: #333;
-
-
-//== Panels
-//
-//##
-
-@panel-bg:                    #fff;
-@panel-body-padding:          15px;
-@panel-heading-padding:       10px 15px;
-@panel-footer-padding:        @panel-heading-padding;
-@panel-border-radius:         @border-radius-base;
-
-//** Border color for elements within panels
-@panel-inner-border:          #ddd;
-@panel-footer-bg:             #f5f5f5;
-
-@panel-default-text:          @gray-dark;
-@panel-default-border:        #ddd;
-@panel-default-heading-bg:    #f5f5f5;
-
-@panel-primary-text:          #fff;
-@panel-primary-border:        @brand-primary;
-@panel-primary-heading-bg:    @brand-primary;
-
-@panel-success-text:          @state-success-text;
-@panel-success-border:        @state-success-border;
-@panel-success-heading-bg:    @state-success-bg;
-
-@panel-info-text:             @state-info-text;
-@panel-info-border:           @state-info-border;
-@panel-info-heading-bg:       @state-info-bg;
-
-@panel-warning-text:          @state-warning-text;
-@panel-warning-border:        @state-warning-border;
-@panel-warning-heading-bg:    @state-warning-bg;
-
-@panel-danger-text:           @state-danger-text;
-@panel-danger-border:         @state-danger-border;
-@panel-danger-heading-bg:     @state-danger-bg;
-
-
-//== Thumbnails
-//
-//##
-
-//** Padding around the thumbnail image
-@thumbnail-padding:           4px;
-//** Thumbnail background color
-@thumbnail-bg:                @body-bg;
-//** Thumbnail border color
-@thumbnail-border:            #ddd;
-//** Thumbnail border radius
-@thumbnail-border-radius:     @border-radius-base;
-
-//** Custom text color for thumbnail captions
-@thumbnail-caption-color:     @text-color;
-//** Padding around the thumbnail caption
-@thumbnail-caption-padding:   9px;
-
-
-//== Wells
-//
-//##
-
-@well-bg:                     #f5f5f5;
-@well-border:                 darken(@well-bg, 7%);
-
-
-//== Badges
-//
-//##
-
-@badge-color:                 #fff;
-//** Linked badge text color on hover
-@badge-link-hover-color:      #fff;
-@badge-bg:                    @gray-light;
-
-//** Badge text color in active nav link
-@badge-active-color:          @link-color;
-//** Badge background color in active nav link
-@badge-active-bg:             #fff;
-
-@badge-font-weight:           bold;
-@badge-line-height:           1;
-@badge-border-radius:         10px;
-
-
-//== Breadcrumbs
-//
-//##
-
-@breadcrumb-padding-vertical:   8px;
-@breadcrumb-padding-horizontal: 15px;
-//** Breadcrumb background color
-@breadcrumb-bg:                 #f5f5f5;
-//** Breadcrumb text color
-@breadcrumb-color:              #ccc;
-//** Text color of current page in the breadcrumb
-@breadcrumb-active-color:       @gray-light;
-//** Textual separator for between breadcrumb elements
-@breadcrumb-separator:          "/";
-
-
-//== Carousel
-//
-//##
-
-@carousel-text-shadow:                        0 1px 2px rgba(0,0,0,.6);
-
-@carousel-control-color:                      #fff;
-@carousel-control-width:                      15%;
-@carousel-control-opacity:                    .5;
-@carousel-control-font-size:                  20px;
-
-@carousel-indicator-active-bg:                #fff;
-@carousel-indicator-border-color:             #fff;
-
-@carousel-caption-color:                      #fff;
-
-
-//== Close
-//
-//##
-
-@close-font-weight:           bold;
-@close-color:                 #000;
-@close-text-shadow:           0 1px 0 #fff;
-
-
-//== Code
-//
-//##
-
-@code-color:                  #c7254e;
-@code-bg:                     #f9f2f4;
-
-@kbd-color:                   #fff;
-@kbd-bg:                      #333;
-
-@pre-bg:                      #f5f5f5;
-@pre-color:                   @gray-dark;
-@pre-border-color:            #ccc;
-@pre-scrollable-max-height:   340px;
-
-
-//== Type
-//
-//##
-
-//** Horizontal offset for forms and lists.
-@component-offset-horizontal: 180px;
-//** Text muted color
-@text-muted:                  @gray-light;
-//** Abbreviations and acronyms border color
-@abbr-border-color:           @gray-light;
-//** Headings small color
-@headings-small-color:        @gray-light;
-//** Blockquote small color
-@blockquote-small-color:      @gray-light;
-//** Blockquote font size
-@blockquote-font-size:        (@font-size-base * 1.25);
-//** Blockquote border color
-@blockquote-border-color:     @gray-lighter;
-//** Page header border color
-@page-header-border-color:    @gray-lighter;
-//** Width of horizontal description list titles
-@dl-horizontal-offset:        @component-offset-horizontal;
-//** Point at which .dl-horizontal becomes horizontal
-@dl-horizontal-breakpoint:    @grid-float-breakpoint;
-//** Horizontal line color.
-@hr-border:                   @gray-lighter;
diff --git a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/wells.less b/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/wells.less
deleted file mode 100644
index 15d072b0..00000000
--- a/src/main/webapp/resources/generated/META-INF/resources/webjars/bootstrap/3.3.6/less/wells.less
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Wells
-// --------------------------------------------------
-
-
-// Base class
-.well {
-  min-height: 20px;
-  padding: 19px;
-  margin-bottom: 20px;
-  background-color: @well-bg;
-  border: 1px solid @well-border;
-  border-radius: @border-radius-base;
-  .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));
-  blockquote {
-    border-color: #ddd;
-    border-color: rgba(0,0,0,.15);
-  }
-}
-
-// Sizes
-.well-lg {
-  padding: 24px;
-  border-radius: @border-radius-large;
-}
-.well-sm {
-  padding: 9px;
-  border-radius: @border-radius-small;
-}
diff --git a/src/test/java/org/springframework/samples/petclinic/SpringConfigTests.java b/src/test/java/org/springframework/samples/petclinic/SpringConfigTests.java
new file mode 100644
index 00000000..e33631f2
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/SpringConfigTests.java
@@ -0,0 +1,13 @@
+package org.springframework.samples.petclinic;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest(classes = PetClinicApplication.class)
+class SpringConfigTests {
+
+    @Test
+    void contextLoads() {
+        // Test the Spring configuration
+    }
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java
index b836d0cc..a4413037 100644
--- a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java
@@ -5,10 +5,10 @@
 import java.util.Locale;
 import java.util.Set;
 
-import javax.validation.ConstraintViolation;
-import javax.validation.Validator;
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.Validator;
 
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 import org.springframework.context.i18n.LocaleContextHolder;
 import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
 
@@ -17,7 +17,7 @@
  *         Simple test to make sure that Bean Validation is working
  *         (useful when upgrading to a new version of Hibernate Validator/ Bean Validation)
  */
-public class ValidatorTests {
+class ValidatorTests {
 
     private Validator createValidator() {
         LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
@@ -26,7 +26,7 @@ private Validator createValidator() {
     }
 
     @Test
-    public void shouldNotValidateWhenFirstNameEmpty() {
+    void shouldNotValidateWhenFirstNameEmpty() {
 
         LocaleContextHolder.setLocale(Locale.ENGLISH);
         Person person = new Person();
@@ -39,7 +39,7 @@ public void shouldNotValidateWhenFirstNameEmpty() {
         assertThat(constraintViolations.size()).isEqualTo(1);
         ConstraintViolation violation = constraintViolations.iterator().next();
         assertThat(violation.getPropertyPath().toString()).isEqualTo("firstName");
-        assertThat(violation.getMessage()).isEqualTo("may not be empty");
+        assertThat(violation.getMessage()).isEqualTo("must not be empty");
     }
 
 }
diff --git a/src/test/java/org/springframework/samples/petclinic/rest/controller/OwnerRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/controller/OwnerRestControllerTests.java
new file mode 100644
index 00000000..07bb8cb9
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/rest/controller/OwnerRestControllerTests.java
@@ -0,0 +1,427 @@
+/*
+ * Copyright 2016-2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.samples.petclinic.rest.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.samples.petclinic.mapper.OwnerMapper;
+import org.springframework.samples.petclinic.mapper.PetMapper;
+import org.springframework.samples.petclinic.mapper.VisitMapper;
+import org.springframework.samples.petclinic.model.Owner;
+import org.springframework.samples.petclinic.model.Pet;
+import org.springframework.samples.petclinic.rest.advice.ExceptionControllerAdvice;
+import org.springframework.samples.petclinic.rest.dto.OwnerDto;
+import org.springframework.samples.petclinic.rest.dto.PetDto;
+import org.springframework.samples.petclinic.rest.dto.PetTypeDto;
+import org.springframework.samples.petclinic.rest.dto.VisitDto;
+import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.BDDMockito.given;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+
+/**
+ * Test class for {@link OwnerRestController}
+ *
+ * @author Vitaliy Fedoriv
+ */
+@SpringBootTest
+@ContextConfiguration(classes = ApplicationTestConfig.class)
+@WebAppConfiguration
+class OwnerRestControllerTests {
+
+    @Autowired
+    private OwnerRestController ownerRestController;
+
+    @Autowired
+    private OwnerMapper ownerMapper;
+
+    @Autowired
+    private PetMapper petMapper;
+
+    @Autowired
+    private VisitMapper visitMapper;
+
+    @MockBean
+    private ClinicService clinicService;
+
+    private MockMvc mockMvc;
+
+    private List owners;
+
+    private List pets;
+
+    private List visits;
+
+    @BeforeEach
+    void initOwners() {
+        this.mockMvc = MockMvcBuilders.standaloneSetup(ownerRestController)
+            .setControllerAdvice(new ExceptionControllerAdvice())
+            .build();
+        owners = new ArrayList<>();
+
+        OwnerDto ownerWithPet = new OwnerDto();
+        owners.add(ownerWithPet.id(1).firstName("George").lastName("Franklin").address("110 W. Liberty St.").city("Madison").telephone("6085551023").addPetsItem(getTestPetWithIdAndName(ownerWithPet, 1, "Rosy")));
+        OwnerDto owner = new OwnerDto();
+        owners.add(owner.id(2).firstName("Betty").lastName("Davis").address("638 Cardinal Ave.").city("Sun Prairie").telephone("6085551749"));
+        owner = new OwnerDto();
+        owners.add(owner.id(3).firstName("Eduardo").lastName("Rodriquez").address("2693 Commerce St.").city("McFarland").telephone("6085558763"));
+        owner = new OwnerDto();
+        owners.add(owner.id(4).firstName("Harold").lastName("Davis").address("563 Friendly St.").city("Windsor").telephone("6085553198"));
+
+        PetTypeDto petType = new PetTypeDto();
+        petType.id(2)
+            .name("dog");
+
+        pets = new ArrayList<>();
+        PetDto pet = new PetDto();
+        pets.add(pet.id(3)
+            .name("Rosy")
+            .birthDate(LocalDate.now())
+            .type(petType));
+
+        pet = new PetDto();
+        pets.add(pet.id(4)
+            .name("Jewel")
+            .birthDate(LocalDate.now())
+            .type(petType));
+
+        visits = new ArrayList<>();
+        VisitDto visit = new VisitDto();
+        visit.setId(2);
+        visit.setPetId(pet.getId());
+        visit.setDate(LocalDate.now());
+        visit.setDescription("rabies shot");
+        visits.add(visit);
+
+        visit = new VisitDto();
+        visit.setId(3);
+        visit.setPetId(pet.getId());
+        visit.setDate(LocalDate.now());
+        visit.setDescription("neutered");
+        visits.add(visit);
+    }
+
+    private PetDto getTestPetWithIdAndName(final OwnerDto owner, final int id, final String name) {
+        PetTypeDto petType = new PetTypeDto();
+        PetDto pet = new PetDto();
+        pet.id(id).name(name).birthDate(LocalDate.now()).type(petType.id(2).name("dog")).addVisitsItem(getTestVisitForPet(pet, 1));
+        return pet;
+    }
+
+    private VisitDto getTestVisitForPet(final PetDto pet, final int id) {
+        VisitDto visit = new VisitDto();
+        return visit.id(id).date(LocalDate.now()).description("test" + id);
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testGetOwnerSuccess() throws Exception {
+        given(this.clinicService.findOwnerById(1)).willReturn(ownerMapper.toOwner(owners.get(0)));
+        this.mockMvc.perform(get("/api/owners/1")
+                .accept(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.id").value(1))
+            .andExpect(jsonPath("$.firstName").value("George"));
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testGetOwnerNotFound() throws Exception {
+        given(this.clinicService.findOwnerById(2)).willReturn(null);
+        this.mockMvc.perform(get("/api/owners/2")
+                .accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testGetOwnersListSuccess() throws Exception {
+        owners.remove(0);
+        owners.remove(1);
+        given(this.clinicService.findOwnerByLastName("Davis")).willReturn(ownerMapper.toOwners(owners));
+        this.mockMvc.perform(get("/api/owners?lastName=Davis")
+                .accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.[0].id").value(2))
+            .andExpect(jsonPath("$.[0].firstName").value("Betty"))
+            .andExpect(jsonPath("$.[1].id").value(4))
+            .andExpect(jsonPath("$.[1].firstName").value("Harold"));
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testGetOwnersListNotFound() throws Exception {
+        owners.clear();
+        given(this.clinicService.findOwnerByLastName("0")).willReturn(ownerMapper.toOwners(owners));
+        this.mockMvc.perform(get("/api/owners/?lastName=0")
+                .accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testGetAllOwnersSuccess() throws Exception {
+        owners.remove(0);
+        owners.remove(1);
+        given(this.clinicService.findAllOwners()).willReturn(ownerMapper.toOwners(owners));
+        this.mockMvc.perform(get("/api/owners/")
+                .accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.[0].id").value(2))
+            .andExpect(jsonPath("$.[0].firstName").value("Betty"))
+            .andExpect(jsonPath("$.[1].id").value(4))
+            .andExpect(jsonPath("$.[1].firstName").value("Harold"));
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testGetAllOwnersNotFound() throws Exception {
+        owners.clear();
+        given(this.clinicService.findAllOwners()).willReturn(ownerMapper.toOwners(owners));
+        this.mockMvc.perform(get("/api/owners/")
+                .accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testCreateOwnerSuccess() throws Exception {
+        OwnerDto newOwnerDto = owners.get(0);
+        newOwnerDto.setId(null);
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+        String newOwnerAsJSON = mapper.writeValueAsString(newOwnerDto);
+        this.mockMvc.perform(post("/api/owners/")
+                .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isCreated());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testCreateOwnerError() throws Exception {
+        OwnerDto newOwnerDto = owners.get(0);
+        newOwnerDto.setId(null);
+        newOwnerDto.setFirstName(null);
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+        String newOwnerAsJSON = mapper.writeValueAsString(newOwnerDto);
+        this.mockMvc.perform(post("/api/owners/")
+                .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isBadRequest());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testUpdateOwnerSuccess() throws Exception {
+        given(this.clinicService.findOwnerById(1)).willReturn(ownerMapper.toOwner(owners.get(0)));
+        int ownerId = owners.get(0).getId();
+        OwnerDto updatedOwnerDto = new OwnerDto();
+        // body.id = ownerId which is used in url path
+        updatedOwnerDto.setId(ownerId);
+        updatedOwnerDto.setFirstName("GeorgeI");
+        updatedOwnerDto.setLastName("Franklin");
+        updatedOwnerDto.setAddress("110 W. Liberty St.");
+        updatedOwnerDto.setCity("Madison");
+        updatedOwnerDto.setTelephone("6085551023");
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+        String newOwnerAsJSON = mapper.writeValueAsString(updatedOwnerDto);
+        this.mockMvc.perform(put("/api/owners/" + ownerId)
+                .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(content().contentType("application/json"))
+            .andExpect(status().isNoContent());
+
+        this.mockMvc.perform(get("/api/owners/" + ownerId)
+                .accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.id").value(ownerId))
+            .andExpect(jsonPath("$.firstName").value("GeorgeI"));
+
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testUpdateOwnerSuccessNoBodyId() throws Exception {
+        given(this.clinicService.findOwnerById(1)).willReturn(ownerMapper.toOwner(owners.get(0)));
+        int ownerId = owners.get(0).getId();
+        OwnerDto updatedOwnerDto = new OwnerDto();
+        updatedOwnerDto.setFirstName("GeorgeI");
+        updatedOwnerDto.setLastName("Franklin");
+        updatedOwnerDto.setAddress("110 W. Liberty St.");
+        updatedOwnerDto.setCity("Madison");
+
+        updatedOwnerDto.setTelephone("6085551023");
+        ObjectMapper mapper = new ObjectMapper();
+        String newOwnerAsJSON = mapper.writeValueAsString(updatedOwnerDto);
+        this.mockMvc.perform(put("/api/owners/" + ownerId)
+                .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(content().contentType("application/json"))
+            .andExpect(status().isNoContent());
+
+        this.mockMvc.perform(get("/api/owners/" + ownerId)
+                .accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.id").value(ownerId))
+            .andExpect(jsonPath("$.firstName").value("GeorgeI"));
+
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testUpdateOwnerError() throws Exception {
+        OwnerDto newOwnerDto = owners.get(0);
+        newOwnerDto.setFirstName("");
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        String newOwnerAsJSON = mapper.writeValueAsString(newOwnerDto);
+        this.mockMvc.perform(put("/api/owners/1")
+                .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isBadRequest());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testDeleteOwnerSuccess() throws Exception {
+        OwnerDto newOwnerDto = owners.get(0);
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        String newOwnerAsJSON = mapper.writeValueAsString(newOwnerDto);
+        final Owner owner = ownerMapper.toOwner(owners.get(0));
+        given(this.clinicService.findOwnerById(1)).willReturn(owner);
+        this.mockMvc.perform(delete("/api/owners/1")
+                .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isNoContent());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testDeleteOwnerError() throws Exception {
+        OwnerDto newOwnerDto = owners.get(0);
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        String newOwnerAsJSON = mapper.writeValueAsString(newOwnerDto);
+        given(this.clinicService.findOwnerById(999)).willReturn(null);
+        this.mockMvc.perform(delete("/api/owners/999")
+                .content(newOwnerAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testCreatePetSuccess() throws Exception {
+        PetDto newPet = pets.get(0);
+        newPet.setId(999);
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
+        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+        String newPetAsJSON = mapper.writeValueAsString(newPet);
+        System.err.println("--> newPetAsJSON=" + newPetAsJSON);
+        this.mockMvc.perform(post("/api/owners/1/pets/")
+                .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isCreated());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testCreatePetError() throws Exception {
+        PetDto newPet = pets.get(0);
+        newPet.setId(null);
+        newPet.setName(null);
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
+        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+        mapper.registerModule(new JavaTimeModule());
+        String newPetAsJSON = mapper.writeValueAsString(newPet);
+        this.mockMvc.perform(post("/api/owners/1/pets/")
+                .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isBadRequest()).andDo(MockMvcResultHandlers.print());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testCreateVisitSuccess() throws Exception {
+        VisitDto newVisit = visits.get(0);
+        newVisit.setId(999);
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+        String newVisitAsJSON = mapper.writeValueAsString(visitMapper.toVisit(newVisit));
+        System.out.println("newVisitAsJSON " + newVisitAsJSON);
+        this.mockMvc.perform(post("/api/owners/1/pets/1/visits")
+                .content(newVisitAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isCreated());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testGetOwnerPetSuccess() throws Exception {
+        owners.remove(0);
+        owners.remove(1);
+        given(this.clinicService.findAllOwners()).willReturn(ownerMapper.toOwners(owners));
+        var owner = ownerMapper.toOwner(owners.get(0));
+        given(this.clinicService.findOwnerById(2)).willReturn(owner);
+        var pet = petMapper.toPet(pets.get(0));
+        pet.setOwner(owner);
+        given(this.clinicService.findPetById(1)).willReturn(pet);
+        this.mockMvc.perform(get("/api/owners/2/pets/1")
+                .accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"));
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testGetOwnersPetsNotFound() throws Exception {
+        owners.clear();
+        given(this.clinicService.findAllOwners()).willReturn(ownerMapper.toOwners(owners));
+        this.mockMvc.perform(get("/api/owners/1/pets/1")
+                .accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isNotFound());
+    }
+
+
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/rest/controller/PetRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/controller/PetRestControllerTests.java
new file mode 100644
index 00000000..06f1b5a9
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/rest/controller/PetRestControllerTests.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2016-2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.samples.petclinic.rest.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.samples.petclinic.mapper.PetMapper;
+import org.springframework.samples.petclinic.model.Pet;
+import org.springframework.samples.petclinic.rest.advice.ExceptionControllerAdvice;
+import org.springframework.samples.petclinic.rest.dto.OwnerDto;
+import org.springframework.samples.petclinic.rest.dto.PetDto;
+import org.springframework.samples.petclinic.rest.dto.PetTypeDto;
+import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+
+/**
+ * Test class for {@link PetRestController}
+ *
+ * @author Vitaliy Fedoriv
+ */
+
+@SpringBootTest
+@ContextConfiguration(classes = ApplicationTestConfig.class)
+@WebAppConfiguration
+class PetRestControllerTests {
+
+    @MockBean
+    protected ClinicService clinicService;
+    @Autowired
+    private PetRestController petRestController;
+    @Autowired
+    private PetMapper petMapper;
+    private MockMvc mockMvc;
+
+    private List pets;
+
+    @BeforeEach
+    void initPets() {
+        this.mockMvc = MockMvcBuilders.standaloneSetup(petRestController)
+            .setControllerAdvice(new ExceptionControllerAdvice())
+            .build();
+        pets = new ArrayList<>();
+
+        OwnerDto owner = new OwnerDto();
+        owner.id(1).firstName("Eduardo")
+            .lastName("Rodriquez")
+            .address("2693 Commerce St.")
+            .city("McFarland")
+            .telephone("6085558763");
+
+        PetTypeDto petType = new PetTypeDto();
+        petType.id(2)
+            .name("dog");
+
+        PetDto pet = new PetDto();
+        pets.add(pet.id(3)
+            .name("Rosy")
+            .birthDate(LocalDate.now())
+            .type(petType));
+
+        pet = new PetDto();
+        pets.add(pet.id(4)
+            .name("Jewel")
+            .birthDate(LocalDate.now())
+            .type(petType));
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testGetPetSuccess() throws Exception {
+        given(this.clinicService.findPetById(3)).willReturn(petMapper.toPet(pets.get(0)));
+        this.mockMvc.perform(get("/api/pets/3")
+                .accept(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.id").value(3))
+            .andExpect(jsonPath("$.name").value("Rosy"));
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testGetPetNotFound() throws Exception {
+        given(petMapper.toPetDto(this.clinicService.findPetById(-1))).willReturn(null);
+        this.mockMvc.perform(get("/api/pets/999")
+                .accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testGetAllPetsSuccess() throws Exception {
+        final Collection pets = petMapper.toPets(this.pets);
+        System.err.println(pets);
+        when(this.clinicService.findAllPets()).thenReturn(pets);
+        //given(this.clinicService.findAllPets()).willReturn(petMapper.toPets(pets));
+        this.mockMvc.perform(get("/api/pets/")
+                .accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.[0].id").value(3))
+            .andExpect(jsonPath("$.[0].name").value("Rosy"))
+            .andExpect(jsonPath("$.[1].id").value(4))
+            .andExpect(jsonPath("$.[1].name").value("Jewel"));
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testGetAllPetsNotFound() throws Exception {
+        pets.clear();
+        given(this.clinicService.findAllPets()).willReturn(petMapper.toPets(pets));
+        this.mockMvc.perform(get("/api/pets/")
+                .accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testUpdatePetSuccess() throws Exception {
+        given(this.clinicService.findPetById(3)).willReturn(petMapper.toPet(pets.get(0)));
+        PetDto newPet = pets.get(0);
+        newPet.setName("Rosy I");
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
+        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+
+        String newPetAsJSON = mapper.writeValueAsString(newPet);
+        this.mockMvc.perform(put("/api/pets/3")
+                .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(content().contentType("application/json"))
+            .andExpect(status().isNoContent());
+
+        this.mockMvc.perform(get("/api/pets/3")
+                .accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.id").value(3))
+            .andExpect(jsonPath("$.name").value("Rosy I"));
+
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testUpdatePetError() throws Exception {
+        PetDto newPet = pets.get(0);
+        newPet.setName(null);
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
+        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+        String newPetAsJSON = mapper.writeValueAsString(newPet);
+
+        this.mockMvc.perform(put("/api/pets/3")
+                .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isBadRequest());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testDeletePetSuccess() throws Exception {
+        PetDto newPet = pets.get(0);
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        String newPetAsJSON = mapper.writeValueAsString(newPet);
+        given(this.clinicService.findPetById(3)).willReturn(petMapper.toPet(pets.get(0)));
+        this.mockMvc.perform(delete("/api/pets/3")
+                .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isNoContent());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testDeletePetError() throws Exception {
+        PetDto newPet = pets.get(0);
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        String newPetAsJSON = mapper.writeValueAsString(newPet);
+        given(this.clinicService.findPetById(999)).willReturn(null);
+        this.mockMvc.perform(delete("/api/pets/999")
+                .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testAddPetSuccess() throws Exception {
+        PetDto newPet = pets.get(0);
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        String newPetAsJSON = mapper.writeValueAsString(newPet);
+        given(this.clinicService.findPetById(3)).willReturn(petMapper.toPet(pets.get(0)));
+        this.mockMvc.perform(post("/api/pets")
+                .content(newPetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk());
+    }
+
+    @Test
+    @WithMockUser(roles = "OWNER_ADMIN")
+    void testAddPetError() throws Exception {
+        PetDto newPet = pets.get(0);
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        String newPetAsJSON = mapper.writeValueAsString(newPet);
+        given(this.clinicService.findPetById(999)).willReturn(null);
+        this.mockMvc.perform(post("/api/pets")
+                .content(new String()).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isBadRequest());
+    }
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/rest/controller/PetTypeRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/controller/PetTypeRestControllerTests.java
new file mode 100644
index 00000000..72cb078e
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/rest/controller/PetTypeRestControllerTests.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2016-2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.samples.petclinic.rest.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.samples.petclinic.mapper.PetTypeMapper;
+import org.springframework.samples.petclinic.model.PetType;
+import org.springframework.samples.petclinic.rest.advice.ExceptionControllerAdvice;
+import org.springframework.samples.petclinic.rest.controller.PetTypeRestController;
+import org.springframework.samples.petclinic.rest.dto.PetTypeDto;
+import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.BDDMockito.given;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+
+/**
+ * Test class for {@link PetTypeRestController}
+ *
+ * @author Vitaliy Fedoriv
+ */
+@SpringBootTest
+@ContextConfiguration(classes=ApplicationTestConfig.class)
+@WebAppConfiguration
+class PetTypeRestControllerTests {
+
+    @Autowired
+    private PetTypeRestController petTypeRestController;
+
+    @Autowired
+    private PetTypeMapper petTypeMapper;
+
+    @MockBean
+    private ClinicService clinicService;
+
+    private MockMvc mockMvc;
+
+    private List petTypes;
+
+    @BeforeEach
+    void initPetTypes(){
+    	this.mockMvc = MockMvcBuilders.standaloneSetup(petTypeRestController)
+    			.setControllerAdvice(new ExceptionControllerAdvice())
+    			.build();
+    	petTypes = new ArrayList();
+
+    	PetType petType = new PetType();
+    	petType.setId(1);
+    	petType.setName("cat");
+    	petTypes.add(petType);
+
+    	petType = new PetType();
+    	petType.setId(2);
+    	petType.setName("dog");
+    	petTypes.add(petType);
+
+    	petType = new PetType();
+    	petType.setId(3);
+    	petType.setName("lizard");
+    	petTypes.add(petType);
+
+    	petType = new PetType();
+    	petType.setId(4);
+    	petType.setName("snake");
+    	petTypes.add(petType);
+    }
+
+    @Test
+    @WithMockUser(roles="OWNER_ADMIN")
+    void testGetPetTypeSuccessAsOwnerAdmin() throws Exception {
+    	given(this.clinicService.findPetTypeById(1)).willReturn(petTypes.get(0));
+        this.mockMvc.perform(get("/api/pettypes/1")
+        	.accept(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.id").value(1))
+            .andExpect(jsonPath("$.name").value("cat"));
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testGetPetTypeSuccessAsVetAdmin() throws Exception {
+        given(this.clinicService.findPetTypeById(1)).willReturn(petTypes.get(0));
+        this.mockMvc.perform(get("/api/pettypes/1")
+            .accept(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.id").value(1))
+            .andExpect(jsonPath("$.name").value("cat"));
+    }
+
+    @Test
+    @WithMockUser(roles="OWNER_ADMIN")
+    void testGetPetTypeNotFound() throws Exception {
+    	given(this.clinicService.findPetTypeById(999)).willReturn(null);
+        this.mockMvc.perform(get("/api/pettypes/999")
+        	.accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(roles="OWNER_ADMIN")
+    void testGetAllPetTypesSuccessAsOwnerAdmin() throws Exception {
+    	petTypes.remove(0);
+    	petTypes.remove(1);
+    	given(this.clinicService.findAllPetTypes()).willReturn(petTypes);
+        this.mockMvc.perform(get("/api/pettypes/")
+        	.accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+        	.andExpect(jsonPath("$.[0].id").value(2))
+        	.andExpect(jsonPath("$.[0].name").value("dog"))
+        	.andExpect(jsonPath("$.[1].id").value(4))
+        	.andExpect(jsonPath("$.[1].name").value("snake"));
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testGetAllPetTypesSuccessAsVetAdmin() throws Exception {
+        petTypes.remove(0);
+        petTypes.remove(1);
+        given(this.clinicService.findAllPetTypes()).willReturn(petTypes);
+        this.mockMvc.perform(get("/api/pettypes/")
+            .accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.[0].id").value(2))
+            .andExpect(jsonPath("$.[0].name").value("dog"))
+            .andExpect(jsonPath("$.[1].id").value(4))
+            .andExpect(jsonPath("$.[1].name").value("snake"));
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testGetAllPetTypesNotFound() throws Exception {
+    	petTypes.clear();
+    	given(this.clinicService.findAllPetTypes()).willReturn(petTypes);
+        this.mockMvc.perform(get("/api/pettypes/")
+        	.accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testCreatePetTypeSuccess() throws Exception {
+    	PetType newPetType = petTypes.get(0);
+    	newPetType.setId(null);
+    	ObjectMapper mapper = new ObjectMapper();
+        String newPetTypeAsJSON = mapper.writeValueAsString(petTypeMapper.toPetTypeDto(newPetType));
+    	this.mockMvc.perform(post("/api/pettypes/")
+    		.content(newPetTypeAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+    		.andExpect(status().isCreated());
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testCreatePetTypeError() throws Exception {
+    	PetType newPetType = petTypes.get(0);
+    	newPetType.setId(null);
+    	newPetType.setName(null);
+    	ObjectMapper mapper = new ObjectMapper();
+        String newPetTypeAsJSON = mapper.writeValueAsString(petTypeMapper.toPetTypeDto(newPetType));
+    	this.mockMvc.perform(post("/api/pettypes/")
+        		.content(newPetTypeAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        		.andExpect(status().isBadRequest());
+     }
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testCreatePetTypeErrorWithId() throws Exception {
+        PetType newPetType = petTypes.get(0);
+        newPetType.setId(1);
+        ObjectMapper mapper = new ObjectMapper();
+        String newPetTypeAsJSON = mapper.writeValueAsString(petTypeMapper.toPetTypeDto(newPetType));
+        this.mockMvc.perform(post("/api/pettypes/")
+                .content(newPetTypeAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isBadRequest());
+    }
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testUpdatePetTypeSuccess() throws Exception {
+    	given(this.clinicService.findPetTypeById(2)).willReturn(petTypes.get(1));
+    	PetType newPetType = petTypes.get(1);
+    	newPetType.setName("dog I");
+    	ObjectMapper mapper = new ObjectMapper();
+        String newPetTypeAsJSON = mapper.writeValueAsString(petTypeMapper.toPetTypeDto(newPetType));
+    	this.mockMvc.perform(put("/api/pettypes/2")
+    		.content(newPetTypeAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(content().contentType("application/json"))
+        	.andExpect(status().isNoContent());
+
+    	this.mockMvc.perform(get("/api/pettypes/2")
+           	.accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.id").value(2))
+            .andExpect(jsonPath("$.name").value("dog I"));
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testUpdatePetTypeError() throws Exception {
+    	PetType newPetType = petTypes.get(0);
+    	newPetType.setName("");
+    	ObjectMapper mapper = new ObjectMapper();
+        String newPetTypeAsJSON = mapper.writeValueAsString(petTypeMapper.toPetTypeDto(newPetType));
+    	this.mockMvc.perform(put("/api/pettypes/1")
+    		.content(newPetTypeAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(status().isBadRequest());
+     }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testDeletePetTypeSuccess() throws Exception {
+    	PetType newPetType = petTypes.get(0);
+    	ObjectMapper mapper = new ObjectMapper();
+    	String newPetTypeAsJSON = mapper.writeValueAsString(newPetType);
+    	given(this.clinicService.findPetTypeById(1)).willReturn(petTypes.get(0));
+    	this.mockMvc.perform(delete("/api/pettypes/1")
+    		.content(newPetTypeAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(status().isNoContent());
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testDeletePetTypeError() throws Exception {
+    	PetType newPetType = petTypes.get(0);
+    	ObjectMapper mapper = new ObjectMapper();
+        String newPetTypeAsJSON = mapper.writeValueAsString(petTypeMapper.toPetTypeDto(newPetType));
+    	given(this.clinicService.findPetTypeById(999)).willReturn(null);
+    	this.mockMvc.perform(delete("/api/pettypes/999")
+    		.content(newPetTypeAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(status().isNotFound());
+    }
+
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/rest/controller/SpecialtyRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/controller/SpecialtyRestControllerTests.java
new file mode 100644
index 00000000..7f1ea114
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/rest/controller/SpecialtyRestControllerTests.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2016-2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.samples.petclinic.rest.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.samples.petclinic.mapper.SpecialtyMapper;
+import org.springframework.samples.petclinic.model.Specialty;
+import org.springframework.samples.petclinic.rest.advice.ExceptionControllerAdvice;
+import org.springframework.samples.petclinic.rest.controller.SpecialtyRestController;
+import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.BDDMockito.given;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+/**
+ * Test class for {@link SpecialtyRestController}
+ *
+ * @author Vitaliy Fedoriv
+ */
+@SpringBootTest
+@ContextConfiguration(classes=ApplicationTestConfig.class)
+@WebAppConfiguration
+class SpecialtyRestControllerTests {
+
+    @Autowired
+    private SpecialtyRestController specialtyRestController;
+
+    @Autowired
+    private SpecialtyMapper specialtyMapper;
+
+	@MockBean
+    private ClinicService clinicService;
+
+    private MockMvc mockMvc;
+
+    private List specialties;
+
+    @BeforeEach
+    void initSpecialtys(){
+    	this.mockMvc = MockMvcBuilders.standaloneSetup(specialtyRestController)
+    			.setControllerAdvice(new ExceptionControllerAdvice())
+    			.build();
+    	specialties = new ArrayList();
+
+    	Specialty specialty = new Specialty();
+    	specialty.setId(1);
+    	specialty.setName("radiology");
+    	specialties.add(specialty);
+
+    	specialty = new Specialty();
+    	specialty.setId(2);
+    	specialty.setName("surgery");
+    	specialties.add(specialty);
+
+    	specialty = new Specialty();
+    	specialty.setId(3);
+    	specialty.setName("dentistry");
+    	specialties.add(specialty);
+
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testGetSpecialtySuccess() throws Exception {
+    	given(this.clinicService.findSpecialtyById(1)).willReturn(specialties.get(0));
+        this.mockMvc.perform(get("/api/specialties/1")
+        	.accept(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.id").value(1))
+            .andExpect(jsonPath("$.name").value("radiology"));
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testGetSpecialtyNotFound() throws Exception {
+    	given(this.clinicService.findSpecialtyById(999)).willReturn(null);
+        this.mockMvc.perform(get("/api/specialties/999")
+        	.accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testGetAllSpecialtysSuccess() throws Exception {
+    	specialties.remove(0);
+    	given(this.clinicService.findAllSpecialties()).willReturn(specialties);
+        this.mockMvc.perform(get("/api/specialties/")
+        	.accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+        	.andExpect(jsonPath("$.[0].id").value(2))
+        	.andExpect(jsonPath("$.[0].name").value("surgery"))
+        	.andExpect(jsonPath("$.[1].id").value(3))
+        	.andExpect(jsonPath("$.[1].name").value("dentistry"));
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testGetAllSpecialtysNotFound() throws Exception {
+    	specialties.clear();
+    	given(this.clinicService.findAllSpecialties()).willReturn(specialties);
+        this.mockMvc.perform(get("/api/specialties/")
+        	.accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testCreateSpecialtySuccess() throws Exception {
+    	Specialty newSpecialty = specialties.get(0);
+    	newSpecialty.setId(999);
+    	ObjectMapper mapper = new ObjectMapper();
+        String newSpecialtyAsJSON = mapper.writeValueAsString(specialtyMapper.toSpecialtyDto(newSpecialty));
+    	this.mockMvc.perform(post("/api/specialties/")
+    		.content(newSpecialtyAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+    		.andExpect(status().isCreated());
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testCreateSpecialtyError() throws Exception {
+    	Specialty newSpecialty = specialties.get(0);
+    	newSpecialty.setId(null);
+    	newSpecialty.setName(null);
+    	ObjectMapper mapper = new ObjectMapper();
+        String newSpecialtyAsJSON = mapper.writeValueAsString(specialtyMapper.toSpecialtyDto(newSpecialty));
+    	this.mockMvc.perform(post("/api/specialties/")
+        		.content(newSpecialtyAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        		.andExpect(status().isBadRequest());
+     }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testUpdateSpecialtySuccess() throws Exception {
+    	given(this.clinicService.findSpecialtyById(2)).willReturn(specialties.get(1));
+    	Specialty newSpecialty = specialties.get(1);
+    	newSpecialty.setName("surgery I");
+    	ObjectMapper mapper = new ObjectMapper();
+        String newSpecialtyAsJSON = mapper.writeValueAsString(specialtyMapper.toSpecialtyDto(newSpecialty));
+    	this.mockMvc.perform(put("/api/specialties/2")
+    		.content(newSpecialtyAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(content().contentType("application/json"))
+        	.andExpect(status().isNoContent());
+
+    	this.mockMvc.perform(get("/api/specialties/2")
+           	.accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.id").value(2))
+            .andExpect(jsonPath("$.name").value("surgery I"));
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testUpdateSpecialtyError() throws Exception {
+    	Specialty newSpecialty = specialties.get(0);
+    	newSpecialty.setName("");
+    	ObjectMapper mapper = new ObjectMapper();
+        String newSpecialtyAsJSON = mapper.writeValueAsString(specialtyMapper.toSpecialtyDto(newSpecialty));
+    	this.mockMvc.perform(put("/api/specialties/1")
+    		.content(newSpecialtyAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(status().isBadRequest());
+     }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testDeleteSpecialtySuccess() throws Exception {
+    	Specialty newSpecialty = specialties.get(0);
+    	ObjectMapper mapper = new ObjectMapper();
+        String newSpecialtyAsJSON = mapper.writeValueAsString(specialtyMapper.toSpecialtyDto(newSpecialty));
+    	given(this.clinicService.findSpecialtyById(1)).willReturn(specialties.get(0));
+    	this.mockMvc.perform(delete("/api/specialties/1")
+    		.content(newSpecialtyAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(status().isNoContent());
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testDeleteSpecialtyError() throws Exception {
+    	Specialty newSpecialty = specialties.get(0);
+    	ObjectMapper mapper = new ObjectMapper();
+        String newSpecialtyAsJSON = mapper.writeValueAsString(specialtyMapper.toSpecialtyDto(newSpecialty));
+    	given(this.clinicService.findSpecialtyById(999)).willReturn(null);
+    	this.mockMvc.perform(delete("/api/specialties/999")
+    		.content(newSpecialtyAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(status().isNotFound());
+    }
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/rest/controller/UserRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/controller/UserRestControllerTests.java
new file mode 100644
index 00000000..9c5f504d
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/rest/controller/UserRestControllerTests.java
@@ -0,0 +1,75 @@
+package org.springframework.samples.petclinic.rest.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.samples.petclinic.mapper.UserMapper;
+import org.springframework.samples.petclinic.model.User;
+import org.springframework.samples.petclinic.rest.advice.ExceptionControllerAdvice;
+import org.springframework.samples.petclinic.rest.controller.UserRestController;
+import org.springframework.samples.petclinic.service.UserService;
+import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@SpringBootTest
+@ContextConfiguration(classes = ApplicationTestConfig.class)
+@WebAppConfiguration
+class UserRestControllerTests {
+
+    @Mock
+    private UserService userService;
+
+    @Autowired
+    private UserMapper userMapper;
+
+    @Autowired
+    private UserRestController userRestController;
+
+    private MockMvc mockMvc;
+
+    @BeforeEach
+    void initVets() {
+        this.mockMvc = MockMvcBuilders.standaloneSetup(userRestController)
+            .setControllerAdvice(new ExceptionControllerAdvice()).build();
+    }
+
+    @Test
+    @WithMockUser(roles = "ADMIN")
+    void testCreateUserSuccess() throws Exception {
+        User user = new User();
+        user.setUsername("username");
+        user.setPassword("password");
+        user.setEnabled(true);
+        user.addRole("OWNER_ADMIN");
+        ObjectMapper mapper = new ObjectMapper();
+        String newVetAsJSON = mapper.writeValueAsString(userMapper.toUserDto(user));
+        this.mockMvc.perform(post("/api/users/")
+            .content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isCreated());
+    }
+
+    @Test
+    @WithMockUser(roles = "ADMIN")
+    void testCreateUserError() throws Exception {
+        User user = new User();
+        user.setUsername("username");
+        user.setPassword("password");
+        user.setEnabled(true);
+        ObjectMapper mapper = new ObjectMapper();
+        String newVetAsJSON = mapper.writeValueAsString(userMapper.toUserDto(user));
+        this.mockMvc.perform(post("/api/users/")
+            .content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isBadRequest());
+    }
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/rest/controller/VetRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/controller/VetRestControllerTests.java
new file mode 100644
index 00000000..5b570978
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/rest/controller/VetRestControllerTests.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2016-2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.samples.petclinic.rest.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.samples.petclinic.mapper.VetMapper;
+import org.springframework.samples.petclinic.model.Vet;
+import org.springframework.samples.petclinic.rest.advice.ExceptionControllerAdvice;
+import org.springframework.samples.petclinic.rest.controller.VetRestController;
+import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.BDDMockito.given;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+/**
+ * Test class for {@link VetRestController}
+ *
+ * @author Vitaliy Fedoriv
+ */
+@SpringBootTest
+@ContextConfiguration(classes=ApplicationTestConfig.class)
+@WebAppConfiguration
+class VetRestControllerTests {
+
+    @Autowired
+    private VetRestController vetRestController;
+
+    @Autowired
+    private VetMapper vetMapper;
+
+	@MockBean
+    private ClinicService clinicService;
+
+    private MockMvc mockMvc;
+
+    private List vets;
+
+    @BeforeEach
+    void initVets(){
+    	this.mockMvc = MockMvcBuilders.standaloneSetup(vetRestController)
+    			.setControllerAdvice(new ExceptionControllerAdvice())
+    			.build();
+    	vets = new ArrayList();
+
+
+    	Vet vet = new Vet();
+    	vet.setId(1);
+    	vet.setFirstName("James");
+    	vet.setLastName("Carter");
+    	vets.add(vet);
+
+    	vet = new Vet();
+    	vet.setId(2);
+    	vet.setFirstName("Helen");
+    	vet.setLastName("Leary");
+    	vets.add(vet);
+
+    	vet = new Vet();
+    	vet.setId(3);
+    	vet.setFirstName("Linda");
+    	vet.setLastName("Douglas");
+    	vets.add(vet);
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testGetVetSuccess() throws Exception {
+    	given(this.clinicService.findVetById(1)).willReturn(vets.get(0));
+        this.mockMvc.perform(get("/api/vets/1")
+        	.accept(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.id").value(1))
+            .andExpect(jsonPath("$.firstName").value("James"));
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testGetVetNotFound() throws Exception {
+    	given(this.clinicService.findVetById(-1)).willReturn(null);
+        this.mockMvc.perform(get("/api/vets/999")
+        	.accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testGetAllVetsSuccess() throws Exception {
+    	given(this.clinicService.findAllVets()).willReturn(vets);
+        this.mockMvc.perform(get("/api/vets/")
+        	.accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.[0].id").value(1))
+            .andExpect(jsonPath("$.[0].firstName").value("James"))
+            .andExpect(jsonPath("$.[1].id").value(2))
+            .andExpect(jsonPath("$.[1].firstName").value("Helen"));
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testGetAllVetsNotFound() throws Exception {
+    	vets.clear();
+    	given(this.clinicService.findAllVets()).willReturn(vets);
+        this.mockMvc.perform(get("/api/vets/")
+        	.accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testCreateVetSuccess() throws Exception {
+    	Vet newVet = vets.get(0);
+    	newVet.setId(999);
+    	ObjectMapper mapper = new ObjectMapper();
+        String newVetAsJSON = mapper.writeValueAsString(vetMapper.toVetDto(newVet));
+    	this.mockMvc.perform(post("/api/vets/")
+    		.content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+    		.andExpect(status().isCreated());
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testCreateVetError() throws Exception {
+    	Vet newVet = vets.get(0);
+    	newVet.setId(null);
+    	newVet.setFirstName(null);
+    	ObjectMapper mapper = new ObjectMapper();
+        String newVetAsJSON = mapper.writeValueAsString(vetMapper.toVetDto(newVet));
+    	this.mockMvc.perform(post("/api/vets/")
+        		.content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        		.andExpect(status().isBadRequest());
+     }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testUpdateVetSuccess() throws Exception {
+    	given(this.clinicService.findVetById(1)).willReturn(vets.get(0));
+    	Vet newVet = vets.get(0);
+    	newVet.setFirstName("James");
+    	ObjectMapper mapper = new ObjectMapper();
+        String newVetAsJSON = mapper.writeValueAsString(vetMapper.toVetDto(newVet));
+    	this.mockMvc.perform(put("/api/vets/1")
+    		.content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(content().contentType("application/json"))
+        	.andExpect(status().isNoContent());
+
+    	this.mockMvc.perform(get("/api/vets/1")
+           	.accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.id").value(1))
+            .andExpect(jsonPath("$.firstName").value("James"));
+
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testUpdateVetError() throws Exception {
+    	Vet newVet = vets.get(0);
+    	newVet.setFirstName(null);
+    	ObjectMapper mapper = new ObjectMapper();
+        String newVetAsJSON = mapper.writeValueAsString(vetMapper.toVetDto(newVet));
+    	this.mockMvc.perform(put("/api/vets/1")
+    		.content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(status().isBadRequest());
+     }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testDeleteVetSuccess() throws Exception {
+    	Vet newVet = vets.get(0);
+    	ObjectMapper mapper = new ObjectMapper();
+        String newVetAsJSON = mapper.writeValueAsString(vetMapper.toVetDto(newVet));
+    	given(this.clinicService.findVetById(1)).willReturn(vets.get(0));
+    	this.mockMvc.perform(delete("/api/vets/1")
+    		.content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(status().isNoContent());
+    }
+
+    @Test
+    @WithMockUser(roles="VET_ADMIN")
+    void testDeleteVetError() throws Exception {
+    	Vet newVet = vets.get(0);
+    	ObjectMapper mapper = new ObjectMapper();
+        String newVetAsJSON = mapper.writeValueAsString(vetMapper.toVetDto(newVet));
+    	given(this.clinicService.findVetById(-1)).willReturn(null);
+    	this.mockMvc.perform(delete("/api/vets/999")
+    		.content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(status().isNotFound());
+    }
+
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/rest/controller/VisitRestControllerTests.java b/src/test/java/org/springframework/samples/petclinic/rest/controller/VisitRestControllerTests.java
new file mode 100644
index 00000000..74217cc5
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/rest/controller/VisitRestControllerTests.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2016-2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.samples.petclinic.rest.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.samples.petclinic.mapper.VisitMapper;
+import org.springframework.samples.petclinic.model.Owner;
+import org.springframework.samples.petclinic.model.Pet;
+import org.springframework.samples.petclinic.model.PetType;
+import org.springframework.samples.petclinic.model.Visit;
+import org.springframework.samples.petclinic.rest.advice.ExceptionControllerAdvice;
+import org.springframework.samples.petclinic.service.ClinicService;
+import org.springframework.samples.petclinic.service.clinicService.ApplicationTestConfig;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.BDDMockito.given;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+/**
+ * Test class for {@link VisitRestController}
+ *
+ * @author Vitaliy Fedoriv
+ */
+@SpringBootTest
+@ContextConfiguration(classes=ApplicationTestConfig.class)
+@WebAppConfiguration
+class VisitRestControllerTests {
+
+    @Autowired
+    private VisitRestController visitRestController;
+
+    @MockBean
+    private ClinicService clinicService;
+
+    @Autowired
+    private VisitMapper visitMapper;
+
+    private MockMvc mockMvc;
+
+    private List visits;
+
+    @BeforeEach
+    void initVisits(){
+    	this.mockMvc = MockMvcBuilders.standaloneSetup(visitRestController)
+    			.setControllerAdvice(new ExceptionControllerAdvice())
+    			.build();
+
+        visits = new ArrayList<>();
+
+    	Owner owner = new Owner();
+    	owner.setId(1);
+    	owner.setFirstName("Eduardo");
+    	owner.setLastName("Rodriquez");
+    	owner.setAddress("2693 Commerce St.");
+    	owner.setCity("McFarland");
+    	owner.setTelephone("6085558763");
+
+    	PetType petType = new PetType();
+    	petType.setId(2);
+    	petType.setName("dog");
+
+    	Pet pet = new Pet();
+    	pet.setId(8);
+    	pet.setName("Rosy");
+        pet.setBirthDate(LocalDate.now());
+    	pet.setOwner(owner);
+    	pet.setType(petType);
+
+
+    	Visit visit = new Visit();
+    	visit.setId(2);
+    	visit.setPet(pet);
+        visit.setDate(LocalDate.now());
+    	visit.setDescription("rabies shot");
+    	visits.add(visit);
+
+    	visit = new Visit();
+    	visit.setId(3);
+    	visit.setPet(pet);
+        visit.setDate(LocalDate.now());
+    	visit.setDescription("neutered");
+    	visits.add(visit);
+
+
+    }
+
+    @Test
+    @WithMockUser(roles="OWNER_ADMIN")
+    void testGetVisitSuccess() throws Exception {
+    	given(this.clinicService.findVisitById(2)).willReturn(visits.get(0));
+        this.mockMvc.perform(get("/api/visits/2")
+        	.accept(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.id").value(2))
+            .andExpect(jsonPath("$.description").value("rabies shot"));
+    }
+
+    @Test
+    @WithMockUser(roles="OWNER_ADMIN")
+    void testGetVisitNotFound() throws Exception {
+        given(this.clinicService.findVisitById(999)).willReturn(null);
+        this.mockMvc.perform(get("/api/visits/999")
+        	.accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(roles="OWNER_ADMIN")
+    void testGetAllVisitsSuccess() throws Exception {
+    	given(this.clinicService.findAllVisits()).willReturn(visits);
+        this.mockMvc.perform(get("/api/visits/")
+        	.accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+        	.andExpect(jsonPath("$.[0].id").value(2))
+        	.andExpect(jsonPath("$.[0].description").value("rabies shot"))
+        	.andExpect(jsonPath("$.[1].id").value(3))
+        	.andExpect(jsonPath("$.[1].description").value("neutered"));
+    }
+
+    @Test
+    @WithMockUser(roles="OWNER_ADMIN")
+    void testGetAllVisitsNotFound() throws Exception {
+    	visits.clear();
+    	given(this.clinicService.findAllVisits()).willReturn(visits);
+        this.mockMvc.perform(get("/api/visits/")
+        	.accept(MediaType.APPLICATION_JSON))
+            .andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(roles="OWNER_ADMIN")
+    void testCreateVisitSuccess() throws Exception {
+    	Visit newVisit = visits.get(0);
+    	newVisit.setId(999);
+    	ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+        String newVisitAsJSON = mapper.writeValueAsString(visitMapper.toVisitDto(newVisit));
+    	System.out.println("newVisitAsJSON " + newVisitAsJSON);
+    	this.mockMvc.perform(post("/api/visits/")
+    		.content(newVisitAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+    		.andExpect(status().isCreated());
+    }
+
+    @Test
+    @WithMockUser(roles="OWNER_ADMIN")
+    void testCreateVisitError() throws Exception {
+    	Visit newVisit = visits.get(0);
+    	newVisit.setId(null);
+        newVisit.setDescription(null);
+    	ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        String newVisitAsJSON = mapper.writeValueAsString(visitMapper.toVisitDto(newVisit));
+    	this.mockMvc.perform(post("/api/visits/")
+        		.content(newVisitAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        		.andExpect(status().isBadRequest());
+     }
+
+    @Test
+    @WithMockUser(roles="OWNER_ADMIN")
+    void testUpdateVisitSuccess() throws Exception {
+    	given(this.clinicService.findVisitById(2)).willReturn(visits.get(0));
+    	Visit newVisit = visits.get(0);
+    	newVisit.setDescription("rabies shot test");
+    	ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+        String newVisitAsJSON = mapper.writeValueAsString(visitMapper.toVisitDto(newVisit));
+    	this.mockMvc.perform(put("/api/visits/2")
+    		.content(newVisitAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(content().contentType("application/json"))
+        	.andExpect(status().isNoContent());
+
+    	this.mockMvc.perform(get("/api/visits/2")
+           	.accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isOk())
+            .andExpect(content().contentType("application/json"))
+            .andExpect(jsonPath("$.id").value(2))
+            .andExpect(jsonPath("$.description").value("rabies shot test"));
+    }
+
+    @Test
+    @WithMockUser(roles="OWNER_ADMIN")
+    void testUpdateVisitError() throws Exception {
+    	Visit newVisit = visits.get(0);
+        newVisit.setDescription(null);
+    	ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        String newVisitAsJSON = mapper.writeValueAsString(visitMapper.toVisitDto(newVisit));
+    	this.mockMvc.perform(put("/api/visits/2")
+    		.content(newVisitAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(status().isBadRequest());
+     }
+
+    @Test
+    @WithMockUser(roles="OWNER_ADMIN")
+    void testDeleteVisitSuccess() throws Exception {
+    	Visit newVisit = visits.get(0);
+    	ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        String newVisitAsJSON = mapper.writeValueAsString(visitMapper.toVisitDto(newVisit));
+    	given(this.clinicService.findVisitById(2)).willReturn(visits.get(0));
+    	this.mockMvc.perform(delete("/api/visits/2")
+    		.content(newVisitAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(status().isNoContent());
+    }
+
+    @Test
+    @WithMockUser(roles="OWNER_ADMIN")
+    void testDeleteVisitError() throws Exception {
+    	Visit newVisit = visits.get(0);
+    	ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        String newVisitAsJSON = mapper.writeValueAsString(visitMapper.toVisitDto(newVisit));
+        given(this.clinicService.findVisitById(999)).willReturn(null);
+        this.mockMvc.perform(delete("/api/visits/999")
+    		.content(newVisitAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
+        	.andExpect(status().isNotFound());
+    }
+
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceSpringDataJpaTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceSpringDataJpaTests.java
deleted file mode 100644
index f29c2da6..00000000
--- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceSpringDataJpaTests.java
+++ /dev/null
@@ -1,190 +0,0 @@
-package org.springframework.samples.petclinic.service;
-
-import org.joda.time.LocalDate;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.samples.petclinic.model.*;
-import org.springframework.samples.petclinic.util.EntityUtils;
-import org.springframework.stereotype.Service;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.Collection;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-/**
- * Integration test of the Service and the Repository layer.
- * 

- * ClinicServiceSpringDataJpaTests subclasses benefit from the following services provided by the Spring - * TestContext Framework:

  • Spring IoC container caching which spares us unnecessary set up - * time between test execution.
  • Dependency Injection of test fixture instances, meaning that - * we don't need to perform application context lookups. See the use of {@link Autowired @Autowired} on the {@link - * ClinicServiceSpringDataJpaTests#clinicService clinicService} instance variable, which uses autowiring by - * type.
  • Transaction management, meaning each test method is executed in its own transaction, - * which is automatically rolled back by default. Thus, even if tests insert or otherwise change database state, there - * is no need for a teardown or cleanup script.
  • An {@link org.springframework.context.ApplicationContext - * ApplicationContext} is also inherited and can be used for explicit bean lookup if necessary.
- * - * @author Ken Krebs - * @author Rod Johnson - * @author Juergen Hoeller - * @author Sam Brannen - * @author Michael Isvy - */ - -@RunWith(SpringJUnit4ClassRunner.class) -@DataJpaTest(includeFilters = @ComponentScan.Filter(Service.class)) -public class ClinicServiceSpringDataJpaTests { - - @Autowired - protected ClinicService clinicService; - - @Test - public void shouldFindOwnersByLastName() { - Collection owners = this.clinicService.findOwnerByLastName("Davis"); - assertThat(owners.size()).isEqualTo(2); - - owners = this.clinicService.findOwnerByLastName("Daviss"); - assertThat(owners.isEmpty()).isTrue(); - } - - @Test - public void shouldFindSingleOwnerWithPet() { - Owner owner = this.clinicService.findOwnerById(1); - assertThat(owner.getLastName()).startsWith("Franklin"); - assertThat(owner.getPets().size()).isEqualTo(1); - assertThat(owner.getPets().get(0).getType()).isNotNull(); - assertThat(owner.getPets().get(0).getType().getName()).isEqualTo("cat"); - } - - @Test - @Transactional - public void shouldInsertOwner() { - Collection owners = this.clinicService.findOwnerByLastName("Schultz"); - int found = owners.size(); - - Owner owner = new Owner(); - owner.setFirstName("Sam"); - owner.setLastName("Schultz"); - owner.setAddress("4, Evans Street"); - owner.setCity("Wollongong"); - owner.setTelephone("4444444444"); - this.clinicService.saveOwner(owner); - assertThat(owner.getId().longValue()).isNotEqualTo(0); - - owners = this.clinicService.findOwnerByLastName("Schultz"); - assertThat(owners.size()).isEqualTo(found + 1); - } - - @Test - @Transactional - public void shouldUpdateOwner() { - Owner owner = this.clinicService.findOwnerById(1); - String oldLastName = owner.getLastName(); - String newLastName = oldLastName + "X"; - - owner.setLastName(newLastName); - this.clinicService.saveOwner(owner); - - // retrieving new name from database - owner = this.clinicService.findOwnerById(1); - assertThat(owner.getLastName()).isEqualTo(newLastName); - } - - @Test - public void shouldFindPetWithCorrectId() { - Pet pet7 = this.clinicService.findPetById(7); - assertThat(pet7.getName()).startsWith("Samantha"); - assertThat(pet7.getOwner().getFirstName()).isEqualTo("Jean"); - - } - - @Test - public void shouldFindAllPetTypes() { - Collection petTypes = this.clinicService.findPetTypes(); - - PetType petType1 = EntityUtils.getById(petTypes, PetType.class, 1); - assertThat(petType1.getName()).isEqualTo("cat"); - PetType petType4 = EntityUtils.getById(petTypes, PetType.class, 4); - assertThat(petType4.getName()).isEqualTo("snake"); - } - - @Test - @Transactional - public void shouldInsertPetIntoDatabaseAndGenerateId() { - Owner owner6 = this.clinicService.findOwnerById(6); - int found = owner6.getPets().size(); - - Pet pet = new Pet(); - pet.setName("bowser"); - Collection types = this.clinicService.findPetTypes(); - pet.setType(EntityUtils.getById(types, PetType.class, 2)); - pet.setBirthDate(new LocalDate()); - owner6.addPet(pet); - assertThat(owner6.getPets().size()).isEqualTo(found + 1); - - this.clinicService.savePet(pet); - this.clinicService.saveOwner(owner6); - - owner6 = this.clinicService.findOwnerById(6); - assertThat(owner6.getPets().size()).isEqualTo(found + 1); - // checks that id has been generated - assertThat(pet.getId()).isNotNull(); - } - - @Test - @Transactional - public void shouldUpdatePetName() throws Exception { - Pet pet7 = this.clinicService.findPetById(7); - String oldName = pet7.getName(); - - String newName = oldName + "X"; - pet7.setName(newName); - this.clinicService.savePet(pet7); - - pet7 = this.clinicService.findPetById(7); - assertThat(pet7.getName()).isEqualTo(newName); - } - - @Test - public void shouldFindVets() { - Collection vets = this.clinicService.findVets(); - - Vet vet = EntityUtils.getById(vets, Vet.class, 3); - assertThat(vet.getLastName()).isEqualTo("Douglas"); - assertThat(vet.getNrOfSpecialties()).isEqualTo(2); - assertThat(vet.getSpecialties().get(0).getName()).isEqualTo("dentistry"); - assertThat(vet.getSpecialties().get(1).getName()).isEqualTo("surgery"); - } - - @Test - @Transactional - public void shouldAddNewVisitForPet() { - Pet pet7 = this.clinicService.findPetById(7); - int found = pet7.getVisits().size(); - Visit visit = new Visit(); - pet7.addVisit(visit); - visit.setDescription("test"); - this.clinicService.saveVisit(visit); - this.clinicService.savePet(pet7); - - pet7 = this.clinicService.findPetById(7); - assertThat(pet7.getVisits().size()).isEqualTo(found + 1); - assertThat(visit.getId()).isNotNull(); - } - - @Test - public void shouldFindVisitsByPetId() throws Exception { - Collection visits = this.clinicService.findVisitsByPetId(7); - assertThat(visits.size()).isEqualTo(2); - Visit[] visitArr = visits.toArray(new Visit[visits.size()]); - assertThat(visitArr[0].getPet()).isNotNull(); - assertThat(visitArr[0].getDate()).isNotNull(); - assertThat(visitArr[0].getPet().getId()).isEqualTo(7); - } - -} diff --git a/src/test/java/org/springframework/samples/petclinic/service/clinicService/AbstractClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/clinicService/AbstractClinicServiceTests.java new file mode 100644 index 00000000..55a4b423 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/service/clinicService/AbstractClinicServiceTests.java @@ -0,0 +1,509 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.service.clinicService; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.model.*; +import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.samples.petclinic.util.EntityUtils; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + *

Base class for {@link ClinicService} integration tests.

Subclasses should specify Spring context + * configuration using {@link ContextConfiguration @ContextConfiguration} annotation

+ * AbstractclinicServiceTests and its subclasses benefit from the following services provided by the Spring + * TestContext Framework:

  • Spring IoC container caching which spares us unnecessary set up + * time between test execution.
  • Dependency Injection of test fixture instances, meaning that + * we don't need to perform application context lookups. See the use of {@link Autowired @Autowired} on the {@link + * AbstractClinicServiceTests#clinicService clinicService} instance variable, which uses autowiring by + * type.
  • Transaction management, meaning each test method is executed in its own transaction, + * which is automatically rolled back by default. Thus, even if tests insert or otherwise change database state, there + * is no need for a teardown or cleanup script.
  • An {@link org.springframework.context.ApplicationContext + * ApplicationContext} is also inherited and can be used for explicit bean lookup if necessary.
+ * + * @author Ken Krebs + * @author Rod Johnson + * @author Juergen Hoeller + * @author Sam Brannen + * @author Michael Isvy + * @author Vitaliy Fedoriv + */ +abstract class AbstractClinicServiceTests { + + @Autowired + protected ClinicService clinicService; + + @Test + void shouldFindOwnersByLastName() { + Collection owners = this.clinicService.findOwnerByLastName("Davis"); + assertThat(owners.size()).isEqualTo(2); + + owners = this.clinicService.findOwnerByLastName("Daviss"); + assertThat(owners.isEmpty()).isTrue(); + } + + @Test + void shouldFindSingleOwnerWithPet() { + Owner owner = this.clinicService.findOwnerById(1); + assertThat(owner.getLastName()).startsWith("Franklin"); + assertThat(owner.getPets().size()).isEqualTo(1); + assertThat(owner.getPets().get(0).getType()).isNotNull(); + assertThat(owner.getPets().get(0).getType().getName()).isEqualTo("cat"); + } + + @Test + @Transactional + void shouldInsertOwner() { + Collection owners = this.clinicService.findOwnerByLastName("Schultz"); + int found = owners.size(); + + Owner owner = new Owner(); + owner.setFirstName("Sam"); + owner.setLastName("Schultz"); + owner.setAddress("4, Evans Street"); + owner.setCity("Wollongong"); + owner.setTelephone("4444444444"); + this.clinicService.saveOwner(owner); + assertThat(owner.getId().longValue()).isNotEqualTo(0); + assertThat(owner.getPet("null value")).isNull(); + owners = this.clinicService.findOwnerByLastName("Schultz"); + assertThat(owners.size()).isEqualTo(found + 1); + } + + @Test + @Transactional + void shouldUpdateOwner() { + Owner owner = this.clinicService.findOwnerById(1); + String oldLastName = owner.getLastName(); + String newLastName = oldLastName + "X"; + + owner.setLastName(newLastName); + this.clinicService.saveOwner(owner); + + // retrieving new name from database + owner = this.clinicService.findOwnerById(1); + assertThat(owner.getLastName()).isEqualTo(newLastName); + } + + @Test + void shouldFindPetWithCorrectId() { + Pet pet7 = this.clinicService.findPetById(7); + assertThat(pet7.getName()).startsWith("Samantha"); + assertThat(pet7.getOwner().getFirstName()).isEqualTo("Jean"); + + } + +// @Test +// void shouldFindAllPetTypes() { +// Collection petTypes = this.clinicService.findPetTypes(); +// +// PetType petType1 = EntityUtils.getById(petTypes, PetType.class, 1); +// assertThat(petType1.getName()).isEqualTo("cat"); +// PetType petType4 = EntityUtils.getById(petTypes, PetType.class, 4); +// assertThat(petType4.getName()).isEqualTo("snake"); +// } + + @Test + @Transactional + void shouldInsertPetIntoDatabaseAndGenerateId() { + Owner owner6 = this.clinicService.findOwnerById(6); + int found = owner6.getPets().size(); + + Pet pet = new Pet(); + pet.setName("bowser"); + Collection types = this.clinicService.findPetTypes(); + pet.setType(EntityUtils.getById(types, PetType.class, 2)); + pet.setBirthDate(LocalDate.now()); + owner6.addPet(pet); + assertThat(owner6.getPets().size()).isEqualTo(found + 1); + + this.clinicService.savePet(pet); + this.clinicService.saveOwner(owner6); + + owner6 = this.clinicService.findOwnerById(6); + assertThat(owner6.getPets().size()).isEqualTo(found + 1); + // checks that id has been generated + assertThat(pet.getId()).isNotNull(); + } + + @Test + @Transactional + void shouldUpdatePetName() throws Exception { + Pet pet7 = this.clinicService.findPetById(7); + String oldName = pet7.getName(); + + String newName = oldName + "X"; + pet7.setName(newName); + this.clinicService.savePet(pet7); + + pet7 = this.clinicService.findPetById(7); + assertThat(pet7.getName()).isEqualTo(newName); + } + + @Test + void shouldFindVets() { + Collection vets = this.clinicService.findVets(); + + Vet vet = EntityUtils.getById(vets, Vet.class, 3); + assertThat(vet.getLastName()).isEqualTo("Douglas"); + assertThat(vet.getNrOfSpecialties()).isEqualTo(2); + assertThat(vet.getSpecialties().get(0).getName()).isEqualTo("dentistry"); + assertThat(vet.getSpecialties().get(1).getName()).isEqualTo("surgery"); + } + + @Test + @Transactional + void shouldAddNewVisitForPet() { + Pet pet7 = this.clinicService.findPetById(7); + int found = pet7.getVisits().size(); + Visit visit = new Visit(); + pet7.addVisit(visit); + visit.setDescription("test"); + this.clinicService.saveVisit(visit); + this.clinicService.savePet(pet7); + + pet7 = this.clinicService.findPetById(7); + assertThat(pet7.getVisits().size()).isEqualTo(found + 1); + assertThat(visit.getId()).isNotNull(); + } + + @Test + void shouldFindVisitsByPetId() throws Exception { + Collection visits = this.clinicService.findVisitsByPetId(7); + assertThat(visits.size()).isEqualTo(2); + Visit[] visitArr = visits.toArray(new Visit[visits.size()]); + assertThat(visitArr[0].getPet()).isNotNull(); + assertThat(visitArr[0].getDate()).isNotNull(); + assertThat(visitArr[0].getPet().getId()).isEqualTo(7); + } + + @Test + void shouldFindAllPets(){ + Collection pets = this.clinicService.findAllPets(); + Pet pet1 = EntityUtils.getById(pets, Pet.class, 1); + assertThat(pet1.getName()).isEqualTo("Leo"); + Pet pet3 = EntityUtils.getById(pets, Pet.class, 3); + assertThat(pet3.getName()).isEqualTo("Rosy"); + } + + @Test + @Transactional + void shouldDeletePet(){ + Pet pet = this.clinicService.findPetById(1); + this.clinicService.deletePet(pet); + try { + pet = this.clinicService.findPetById(1); + } catch (Exception e) { + pet = null; + } + assertThat(pet).isNull(); + } + + @Test + void shouldFindVisitDyId(){ + Visit visit = this.clinicService.findVisitById(1); + assertThat(visit.getId()).isEqualTo(1); + assertThat(visit.getPet().getName()).isEqualTo("Samantha"); + } + + @Test + void shouldFindAllVisits(){ + Collection visits = this.clinicService.findAllVisits(); + Visit visit1 = EntityUtils.getById(visits, Visit.class, 1); + assertThat(visit1.getPet().getName()).isEqualTo("Samantha"); + Visit visit3 = EntityUtils.getById(visits, Visit.class, 3); + assertThat(visit3.getPet().getName()).isEqualTo("Max"); + } + + @Test + @Transactional + void shouldInsertVisit() { + Collection visits = this.clinicService.findAllVisits(); + int found = visits.size(); + + Pet pet = this.clinicService.findPetById(1); + + Visit visit = new Visit(); + visit.setPet(pet); + visit.setDate(LocalDate.now()); + visit.setDescription("new visit"); + + + this.clinicService.saveVisit(visit); + assertThat(visit.getId().longValue()).isNotEqualTo(0); + + visits = this.clinicService.findAllVisits(); + assertThat(visits.size()).isEqualTo(found + 1); + } + + @Test + @Transactional + void shouldUpdateVisit(){ + Visit visit = this.clinicService.findVisitById(1); + String oldDesc = visit.getDescription(); + String newDesc = oldDesc + "X"; + visit.setDescription(newDesc); + this.clinicService.saveVisit(visit); + visit = this.clinicService.findVisitById(1); + assertThat(visit.getDescription()).isEqualTo(newDesc); + } + + @Test + @Transactional + void shouldDeleteVisit(){ + Visit visit = this.clinicService.findVisitById(1); + this.clinicService.deleteVisit(visit); + try { + visit = this.clinicService.findVisitById(1); + } catch (Exception e) { + visit = null; + } + assertThat(visit).isNull(); + } + + @Test + void shouldFindVetDyId(){ + Vet vet = this.clinicService.findVetById(1); + assertThat(vet.getFirstName()).isEqualTo("James"); + assertThat(vet.getLastName()).isEqualTo("Carter"); + } + + @Test + @Transactional + void shouldInsertVet() { + Collection vets = this.clinicService.findAllVets(); + int found = vets.size(); + + Vet vet = new Vet(); + vet.setFirstName("John"); + vet.setLastName("Dow"); + + this.clinicService.saveVet(vet); + assertThat(vet.getId().longValue()).isNotEqualTo(0); + + vets = this.clinicService.findAllVets(); + assertThat(vets.size()).isEqualTo(found + 1); + } + + @Test + @Transactional + void shouldUpdateVet(){ + Vet vet = this.clinicService.findVetById(1); + String oldLastName = vet.getLastName(); + String newLastName = oldLastName + "X"; + vet.setLastName(newLastName); + this.clinicService.saveVet(vet); + vet = this.clinicService.findVetById(1); + assertThat(vet.getLastName()).isEqualTo(newLastName); + } + + @Test + @Transactional + void shouldDeleteVet(){ + Vet vet = this.clinicService.findVetById(1); + this.clinicService.deleteVet(vet); + try { + vet = this.clinicService.findVetById(1); + } catch (Exception e) { + vet = null; + } + assertThat(vet).isNull(); + } + + @Test + void shouldFindAllOwners(){ + Collection owners = this.clinicService.findAllOwners(); + Owner owner1 = EntityUtils.getById(owners, Owner.class, 1); + assertThat(owner1.getFirstName()).isEqualTo("George"); + Owner owner3 = EntityUtils.getById(owners, Owner.class, 3); + assertThat(owner3.getFirstName()).isEqualTo("Eduardo"); + } + + @Test + @Transactional + void shouldDeleteOwner(){ + Owner owner = this.clinicService.findOwnerById(1); + this.clinicService.deleteOwner(owner); + try { + owner = this.clinicService.findOwnerById(1); + } catch (Exception e) { + owner = null; + } + assertThat(owner).isNull(); + } + + @Test + void shouldFindPetTypeById(){ + PetType petType = this.clinicService.findPetTypeById(1); + assertThat(petType.getName()).isEqualTo("cat"); + } + + @Test + void shouldFindAllPetTypes(){ + Collection petTypes = this.clinicService.findAllPetTypes(); + PetType petType1 = EntityUtils.getById(petTypes, PetType.class, 1); + assertThat(petType1.getName()).isEqualTo("cat"); + PetType petType3 = EntityUtils.getById(petTypes, PetType.class, 3); + assertThat(petType3.getName()).isEqualTo("lizard"); + } + + @Test + @Transactional + void shouldInsertPetType() { + Collection petTypes = this.clinicService.findAllPetTypes(); + int found = petTypes.size(); + + PetType petType = new PetType(); + petType.setName("tiger"); + + this.clinicService.savePetType(petType); + assertThat(petType.getId().longValue()).isNotEqualTo(0); + + petTypes = this.clinicService.findAllPetTypes(); + assertThat(petTypes.size()).isEqualTo(found + 1); + } + + @Test + @Transactional + void shouldUpdatePetType(){ + PetType petType = this.clinicService.findPetTypeById(1); + String oldLastName = petType.getName(); + String newLastName = oldLastName + "X"; + petType.setName(newLastName); + this.clinicService.savePetType(petType); + petType = this.clinicService.findPetTypeById(1); + assertThat(petType.getName()).isEqualTo(newLastName); + } + + @Test + @Transactional + void shouldDeletePetType(){ + PetType petType = this.clinicService.findPetTypeById(1); + this.clinicService.deletePetType(petType); + try { + petType = this.clinicService.findPetTypeById(1); + } catch (Exception e) { + petType = null; + } + assertThat(petType).isNull(); + } + + @Test + void shouldFindSpecialtyById(){ + Specialty specialty = this.clinicService.findSpecialtyById(1); + assertThat(specialty.getName()).isEqualTo("radiology"); + } + + @Test + void shouldFindAllSpecialtys(){ + Collection specialties = this.clinicService.findAllSpecialties(); + Specialty specialty1 = EntityUtils.getById(specialties, Specialty.class, 1); + assertThat(specialty1.getName()).isEqualTo("radiology"); + Specialty specialty3 = EntityUtils.getById(specialties, Specialty.class, 3); + assertThat(specialty3.getName()).isEqualTo("dentistry"); + } + + @Test + @Transactional + void shouldInsertSpecialty() { + Collection specialties = this.clinicService.findAllSpecialties(); + int found = specialties.size(); + + Specialty specialty = new Specialty(); + specialty.setName("dermatologist"); + + this.clinicService.saveSpecialty(specialty); + assertThat(specialty.getId().longValue()).isNotEqualTo(0); + + specialties = this.clinicService.findAllSpecialties(); + assertThat(specialties.size()).isEqualTo(found + 1); + } + + @Test + @Transactional + void shouldUpdateSpecialty(){ + Specialty specialty = this.clinicService.findSpecialtyById(1); + String oldLastName = specialty.getName(); + String newLastName = oldLastName + "X"; + specialty.setName(newLastName); + this.clinicService.saveSpecialty(specialty); + specialty = this.clinicService.findSpecialtyById(1); + assertThat(specialty.getName()).isEqualTo(newLastName); + } + + @Test + @Transactional + void shouldDeleteSpecialty(){ + Specialty specialty = new Specialty(); + specialty.setName("test"); + this.clinicService.saveSpecialty(specialty); + Integer specialtyId = specialty.getId(); + assertThat(specialtyId).isNotNull(); + specialty = this.clinicService.findSpecialtyById(specialtyId); + assertThat(specialty).isNotNull(); + this.clinicService.deleteSpecialty(specialty); + try { + specialty = this.clinicService.findSpecialtyById(specialtyId); + } catch (Exception e) { + specialty = null; + } + assertThat(specialty).isNull(); + } + + @Test + @Transactional + void shouldFindSpecialtiesByNameIn() { + Specialty specialty1 = new Specialty(); + specialty1.setName("radiology"); + specialty1.setId(1); + Specialty specialty2 = new Specialty(); + specialty2.setName("surgery"); + specialty2.setId(2); + Specialty specialty3 = new Specialty(); + specialty3.setName("dentistry"); + specialty3.setId(3); + List expectedSpecialties = List.of(specialty1, specialty2, specialty3); + Set specialtyNames = expectedSpecialties.stream() + .map(Specialty::getName) + .collect(Collectors.toSet()); + Collection actualSpecialties = this.clinicService.findSpecialtiesByNameIn(specialtyNames); + assertThat(actualSpecialties).isNotNull(); + assertThat(actualSpecialties.size()).isEqualTo(expectedSpecialties.size()); + for (Specialty expected : expectedSpecialties) { + assertThat(actualSpecialties.stream() + .anyMatch( + actual -> actual.getName().equals(expected.getName()) + && actual.getId().equals(expected.getId()))).isTrue(); + } + } + + @Test + @Transactional + void shouldFindPetTypeByName(){ + PetType petType = this.clinicService.findPetTypeByName("cat"); + assertThat(petType.getId()).isEqualTo(1); + } +} diff --git a/src/test/java/org/springframework/samples/petclinic/service/clinicService/ApplicationTestConfig.java b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ApplicationTestConfig.java new file mode 100644 index 00000000..79398dc1 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ApplicationTestConfig.java @@ -0,0 +1,13 @@ +package org.springframework.samples.petclinic.service.clinicService; + +import org.mockito.MockitoAnnotations; +import org.springframework.boot.test.context.TestConfiguration; + +@TestConfiguration +public class ApplicationTestConfig { + + public ApplicationTestConfig(){ + MockitoAnnotations.openMocks(this); + } + +} diff --git a/src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceJdbcTests.java b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceJdbcTests.java new file mode 100644 index 00000000..43724aa3 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceJdbcTests.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.samples.petclinic.service.clinicService; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +/** + *

Integration test using the jdbc profile. + * + * @author Thomas Risberg + * @author Michael Isvy + * @see AbstractClinicServiceTests AbstractClinicServiceTests for more details.

+ */ +@SpringBootTest +@ActiveProfiles({"jdbc", "hsqldb"}) +class ClinicServiceJdbcTests extends AbstractClinicServiceTests { + +} diff --git a/src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceJpaTests.java b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceJpaTests.java new file mode 100644 index 00000000..1a730507 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceJpaTests.java @@ -0,0 +1,19 @@ +package org.springframework.samples.petclinic.service.clinicService; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +/** + *

Integration test using the jpa profile. + * + * @author Rod Johnson + * @author Sam Brannen + * @author Michael Isvy + * @see AbstractClinicServiceTests AbstractClinicServiceTests for more details.

+ */ + +@SpringBootTest +@ActiveProfiles({"jpa", "hsqldb"}) +class ClinicServiceJpaTests extends AbstractClinicServiceTests { + +} diff --git a/src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceSpringDataJpaTests.java b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceSpringDataJpaTests.java new file mode 100644 index 00000000..b5c57c0c --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/service/clinicService/ClinicServiceSpringDataJpaTests.java @@ -0,0 +1,17 @@ +package org.springframework.samples.petclinic.service.clinicService; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +/** + *

Integration test using the 'Spring Data' profile. + * + * @author Michael Isvy + * @see AbstractClinicServiceTests AbstractClinicServiceTests for more details.

+ */ + +@SpringBootTest +@ActiveProfiles({"spring-data-jpa", "hsqldb"}) +class ClinicServiceSpringDataJpaTests extends AbstractClinicServiceTests { + +} diff --git a/src/test/java/org/springframework/samples/petclinic/service/userService/AbstractUserServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/userService/AbstractUserServiceTests.java new file mode 100644 index 00000000..54ecdded --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/service/userService/AbstractUserServiceTests.java @@ -0,0 +1,35 @@ +package org.springframework.samples.petclinic.service.userService; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.samples.petclinic.model.User; +import org.springframework.samples.petclinic.service.UserService; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public abstract class AbstractUserServiceTests { + + @Autowired + private UserService userService; + + @BeforeEach + public void init() { + MockitoAnnotations.openMocks(this); + } + + @Test + public void shouldAddUser() throws Exception { + User user = new User(); + user.setUsername("username"); + user.setPassword("password"); + user.setEnabled(true); + user.addRole("OWNER_ADMIN"); + + userService.saveUser(user); + assertThat(user.getRoles().parallelStream().allMatch(role -> role.getName().startsWith("ROLE_")), is(true)); + assertThat(user.getRoles().parallelStream().allMatch(role -> role.getUser() != null), is(true)); + } +} diff --git a/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceJdbcTests.java b/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceJdbcTests.java new file mode 100644 index 00000000..8cfbdaf7 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceJdbcTests.java @@ -0,0 +1,10 @@ +package org.springframework.samples.petclinic.service.userService; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +@SpringBootTest +@ActiveProfiles({"jdbc", "hsqldb"}) +class UserServiceJdbcTests extends AbstractUserServiceTests { + +} diff --git a/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceJpaTests.java b/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceJpaTests.java new file mode 100644 index 00000000..0db9a127 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceJpaTests.java @@ -0,0 +1,10 @@ +package org.springframework.samples.petclinic.service.userService; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +@SpringBootTest +@ActiveProfiles({"jpa", "hsqldb"}) +class UserServiceJpaTests extends AbstractUserServiceTests { + +} diff --git a/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceSpringDataJpaTests.java b/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceSpringDataJpaTests.java new file mode 100644 index 00000000..d7240c81 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/service/userService/UserServiceSpringDataJpaTests.java @@ -0,0 +1,10 @@ +package org.springframework.samples.petclinic.service.userService; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +@SpringBootTest +@ActiveProfiles({"spring-data-jpa", "hsqldb"}) +class UserServiceSpringDataJpaTests extends AbstractUserServiceTests { + +} diff --git a/src/test/java/org/springframework/samples/petclinic/web/CrashControllerTests.java b/src/test/java/org/springframework/samples/petclinic/web/CrashControllerTests.java deleted file mode 100644 index 30a0a647..00000000 --- a/src/test/java/org/springframework/samples/petclinic/web/CrashControllerTests.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.springframework.samples.petclinic.web; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.samples.petclinic.PetClinicApplication; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -/** - * Test class for {@link CrashController} - * - * @author Colin But - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = PetClinicApplication.class) -@WebAppConfiguration -// Waiting https://github.com/spring-projects/spring-boot/issues/5574 -@Ignore -public class CrashControllerTests { - - @Autowired - private CrashController crashController; - - private MockMvc mockMvc; - - @Before - public void setup() { - this.mockMvc = MockMvcBuilders - .standaloneSetup(crashController) - //.setHandlerExceptionResolvers(new SimpleMappingExceptionResolver()) - .build(); - } - - @Test - public void testTriggerException() throws Exception { - mockMvc.perform(get("/oups")) - .andExpect(view().name("exception")) - .andExpect(model().attributeExists("exception")) - .andExpect(forwardedUrl("exception")) - .andExpect(status().isOk()); - } -} diff --git a/src/test/java/org/springframework/samples/petclinic/web/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/web/OwnerControllerTests.java deleted file mode 100644 index ee061e6c..00000000 --- a/src/test/java/org/springframework/samples/petclinic/web/OwnerControllerTests.java +++ /dev/null @@ -1,176 +0,0 @@ -package org.springframework.samples.petclinic.web; - -import org.assertj.core.util.Lists; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.web.servlet.MockMvc; - -import static org.hamcrest.Matchers.hasProperty; -import static org.hamcrest.Matchers.is; -import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -/** - * Test class for {@link OwnerController} - * - * @author Colin But - */ -@RunWith(SpringJUnit4ClassRunner.class) -@WebMvcTest(OwnerController.class) -public class OwnerControllerTests { - - private static final int TEST_OWNER_ID = 1; - - @Autowired - private MockMvc mockMvc; - - @MockBean - private ClinicService clinicService; - - private Owner george; - - @Before - public void setup() { - george = new Owner(); - george.setId(TEST_OWNER_ID); - george.setFirstName("George"); - george.setLastName("Franklin"); - george.setAddress("110 W. Liberty St."); - george.setCity("Madison"); - george.setTelephone("6085551023"); - given(this.clinicService.findOwnerById(TEST_OWNER_ID)).willReturn(george); - } - - @Test - public void testInitCreationForm() throws Exception { - mockMvc.perform(get("/owners/new")) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); - } - - @Test - public void testProcessCreationFormSuccess() throws Exception { - mockMvc.perform(post("/owners/new") - .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("address", "123 Caramel Street") - .param("city", "London") - .param("telephone", "01316761638") - ) - .andExpect(status().is3xxRedirection()); - } - - @Test - public void testProcessCreationFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/new") - .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("city", "London") - ) - .andExpect(status().isOk()) - .andExpect(model().attributeHasErrors("owner")) - .andExpect(model().attributeHasFieldErrors("owner", "address")) - .andExpect(model().attributeHasFieldErrors("owner", "telephone")) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); - } - - @Test - public void testInitFindForm() throws Exception { - mockMvc.perform(get("/owners/find")) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) - .andExpect(view().name("owners/findOwners")); - } - - @Test - public void testProcessFindFormSuccess() throws Exception { - given(this.clinicService.findOwnerByLastName("")).willReturn(Lists.newArrayList(george, new Owner())); - mockMvc.perform(get("/owners")) - .andExpect(status().isOk()) - .andExpect(view().name("owners/ownersList")); - } - - @Test - public void testProcessFindFormByLastName() throws Exception { - given(this.clinicService.findOwnerByLastName(george.getLastName())).willReturn(Lists.newArrayList(george)); - mockMvc.perform(get("/owners") - .param("lastName", "Franklin") - ) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/" + TEST_OWNER_ID)); - } - - @Test - public void testProcessFindFormNoOwnersFound() throws Exception { - mockMvc.perform(get("/owners") - .param("lastName", "Unknown Surname") - ) - .andExpect(status().isOk()) - .andExpect(model().attributeHasFieldErrors("owner", "lastName")) - .andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound")) - .andExpect(view().name("owners/findOwners")); - } - - @Test - public void testInitUpdateOwnerForm() throws Exception { - mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID)) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) - .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) - .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) - .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) - .andExpect(model().attribute("owner", hasProperty("city", is("Madison")))) - .andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023")))) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); - } - - @Test - public void testProcessUpdateOwnerFormSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID) - .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("address", "123 Caramel Street") - .param("city", "London") - .param("telephone", "01616291589") - ) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); - } - - @Test - public void testProcessUpdateOwnerFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID) - .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("city", "London") - ) - .andExpect(status().isOk()) - .andExpect(model().attributeHasErrors("owner")) - .andExpect(model().attributeHasFieldErrors("owner", "address")) - .andExpect(model().attributeHasFieldErrors("owner", "telephone")) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); - } - - @Test - public void testShowOwner() throws Exception { - mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID)) - .andExpect(status().isOk()) - .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) - .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) - .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) - .andExpect(model().attribute("owner", hasProperty("city", is("Madison")))) - .andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023")))) - .andExpect(view().name("owners/ownerDetails")); - } - -} diff --git a/src/test/java/org/springframework/samples/petclinic/web/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/web/PetControllerTests.java deleted file mode 100644 index b7515a85..00000000 --- a/src/test/java/org/springframework/samples/petclinic/web/PetControllerTests.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.springframework.samples.petclinic.web; - -import org.assertj.core.util.Lists; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.FilterType; -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.web.servlet.MockMvc; - -import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -/** - * Test class for the {@link PetController} - * - * @author Colin But - */ -@RunWith(SpringJUnit4ClassRunner.class) -@WebMvcTest(value = PetController.class, - includeFilters = @ComponentScan.Filter( - value = PetTypeFormatter.class, - type = FilterType.ASSIGNABLE_TYPE)) -public class PetControllerTests { - - private static final int TEST_OWNER_ID = 1; - private static final int TEST_PET_ID = 1; - - - @Autowired - private MockMvc mockMvc; - - @MockBean - private ClinicService clinicService; - - @Before - public void setup() { - PetType cat = new PetType(); - cat.setId(3); - cat.setName("hamster"); - given(this.clinicService.findPetTypes()).willReturn(Lists.newArrayList(cat)); - given(this.clinicService.findOwnerById(TEST_OWNER_ID)).willReturn(new Owner()); - given(this.clinicService.findPetById(TEST_PET_ID)).willReturn(new Pet()); - - } - - @Test - public void testInitCreationForm() throws Exception { - mockMvc.perform(get("/owners/{ownerId}/pets/new", TEST_OWNER_ID)) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdatePetForm")) - .andExpect(model().attributeExists("pet")); - } - - @Test - public void testProcessCreationFormSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID) - .param("name", "Betty") - .param("type", "hamster") - .param("birthDate", "2015/02/12") - ) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); - } - - @Test - public void testProcessCreationFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) - .param("name", "Betty") - .param("birthDate", "2015/02/12") - ) - .andExpect(model().attributeHasNoErrors("owner")) - .andExpect(model().attributeHasErrors("pet")) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdatePetForm")); - } - - @Test - public void testInitUpdateForm() throws Exception { - mockMvc.perform(get("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID)) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("pet")) - .andExpect(view().name("pets/createOrUpdatePetForm")); - } - - @Test - public void testProcessUpdateFormSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) - .param("name", "Betty") - .param("type", "hamster") - .param("birthDate", "2015/02/12") - ) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); - } - - @Test - public void testProcessUpdateFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) - .param("name", "Betty") - .param("birthDate", "2015/02/12") - ) - .andExpect(model().attributeHasNoErrors("owner")) - .andExpect(model().attributeHasErrors("pet")) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdatePetForm")); - } - -} diff --git a/src/test/java/org/springframework/samples/petclinic/web/PetTypeFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/web/PetTypeFormatterTests.java deleted file mode 100644 index e1b2a53f..00000000 --- a/src/test/java/org/springframework/samples/petclinic/web/PetTypeFormatterTests.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.springframework.samples.petclinic.web; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.runners.MockitoJUnitRunner; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.service.ClinicService; - -import java.text.ParseException; -import java.util.*; - -import static org.junit.Assert.assertEquals; - -/** - * Test class for {@link PetTypeFormatter} - * - * @author Colin But - */ -@RunWith(MockitoJUnitRunner.class) -public class PetTypeFormatterTests { - - @Mock - private ClinicService clinicService; - - private PetTypeFormatter petTypeFormatter; - - @Before - public void setup() { - petTypeFormatter = new PetTypeFormatter(clinicService); - } - - @Test - public void testPrint() { - PetType petType = new PetType(); - petType.setName("Hamster"); - String petTypeName = petTypeFormatter.print(petType, Locale.ENGLISH); - assertEquals("Hamster", petTypeName); - } - - @Test - public void shouldParse() throws ParseException { - Mockito.when(clinicService.findPetTypes()).thenReturn(makePetTypes()); - PetType petType = petTypeFormatter.parse("Bird", Locale.ENGLISH); - assertEquals("Bird", petType.getName()); - } - - @Test(expected = ParseException.class) - public void shouldThrowParseException() throws ParseException { - Mockito.when(clinicService.findPetTypes()).thenReturn(makePetTypes()); - petTypeFormatter.parse("Fish", Locale.ENGLISH); - } - - /** - * Helper method to produce some sample pet types just for test purpose - * - * @return {@link Collection} of {@link PetType} - */ - private Collection makePetTypes() { - Collection petTypes = new ArrayList<>(); - petTypes.add(new PetType(){ - { - setName("Dog"); - } - }); - petTypes.add(new PetType(){ - { - setName("Bird"); - } - }); - return petTypes; - } - -} diff --git a/src/test/java/org/springframework/samples/petclinic/web/VetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/web/VetControllerTests.java deleted file mode 100644 index 90d626bd..00000000 --- a/src/test/java/org/springframework/samples/petclinic/web/VetControllerTests.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.springframework.samples.petclinic.web; - -import org.assertj.core.util.Lists; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.samples.petclinic.model.Specialty; -import org.springframework.samples.petclinic.model.Vet; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.ResultActions; - -import static org.hamcrest.xml.HasXPath.hasXPath; -import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -/** - * Test class for the {@link VetController} - */ -@RunWith(SpringJUnit4ClassRunner.class) -@WebMvcTest(VetController.class) -public class VetControllerTests { - - @Autowired - private MockMvc mockMvc; - - @MockBean - private ClinicService clinicService; - - @Before - public void setup() { - Vet james = new Vet(); - james.setFirstName("James"); - james.setLastName("Carter"); - james.setId(1); - Vet helen = new Vet(); - helen.setFirstName("Helen"); - helen.setLastName("Leary"); - helen.setId(2); - Specialty radiology = new Specialty(); - radiology.setId(1); - radiology.setName("radiology"); - helen.addSpecialty(radiology); - given(this.clinicService.findVets()).willReturn(Lists.newArrayList(james, helen)); - } - - @Test - public void testShowVetListHtml() throws Exception { - mockMvc.perform(get("/vets.html")) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("vets")) - .andExpect(view().name("vets/vetList")); - } - - @Test - public void testShowResourcesVetList() throws Exception { - ResultActions actions = mockMvc.perform(get("/vets.json").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); - actions.andExpect(content().contentType("application/json;charset=UTF-8")) - .andExpect(jsonPath("$.vetList[0].id").value(1)); - } - - @Test - public void testShowVetListXml() throws Exception { - mockMvc.perform(get("/vets.xml").accept(MediaType.APPLICATION_XML)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_XML_VALUE)) - .andExpect(content().node(hasXPath("/vets/vetList[id=1]/id"))); - } - -} diff --git a/src/test/java/org/springframework/samples/petclinic/web/VisitControllerTests.java b/src/test/java/org/springframework/samples/petclinic/web/VisitControllerTests.java deleted file mode 100644 index 970d2dcf..00000000 --- a/src/test/java/org/springframework/samples/petclinic/web/VisitControllerTests.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.springframework.samples.petclinic.web; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.web.servlet.MockMvc; - -import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -/** - * Test class for {@link VisitController} - * - * @author Colin But - */ -@RunWith(SpringJUnit4ClassRunner.class) -@WebMvcTest(VisitController.class) -public class VisitControllerTests { - - private static final int TEST_PET_ID = 1; - - @Autowired - private MockMvc mockMvc; - - @MockBean - private ClinicService clinicService; - - @Before - public void init() { - given(this.clinicService.findPetById(TEST_PET_ID)).willReturn(new Pet()); - } - - @Test - public void testInitNewVisitForm() throws Exception { - mockMvc.perform(get("/owners/*/pets/{petId}/visits/new", TEST_PET_ID)) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdateVisitForm")); - } - - @Test - public void testProcessNewVisitFormSuccess() throws Exception { - mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID) - .param("name", "George") - .param("description", "Visit Description") - ) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); - } - - @Test - public void testProcessNewVisitFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID) - .param("name", "George") - ) - .andExpect(model().attributeHasErrors("visit")) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdateVisitForm")); - } - - @Test - public void testShowVisits() throws Exception { - mockMvc.perform(get("/owners/*/pets/{petId}/visits", TEST_PET_ID)) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("visits")) - .andExpect(view().name("visitList")); - } - - -} diff --git a/src/test/java/org/springframework/samples/petclinic/web/api/OwnerResourceTests.java b/src/test/java/org/springframework/samples/petclinic/web/api/OwnerResourceTests.java deleted file mode 100755 index 28de8492..00000000 --- a/src/test/java/org/springframework/samples/petclinic/web/api/OwnerResourceTests.java +++ /dev/null @@ -1,157 +0,0 @@ -package org.springframework.samples.petclinic.web.api; - -import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Mockito.doAnswer; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.util.LinkedList; -import java.util.List; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MockMvc; - -import com.fasterxml.jackson.databind.ObjectMapper; - -@RunWith(SpringRunner.class) -@WebMvcTest(OwnerResource.class) -public class OwnerResourceTests { - - @Autowired - private MockMvc mvc; - - @MockBean - ClinicService clinicService; - - @Test - public void shouldNotGetOwnerById() throws Exception { - - mvc.perform(get("/api/owner/20") // - .accept(MediaType.APPLICATION_JSON)) // - .andExpect(status().is4xxClientError()) // - .andExpect(content().contentType("application/json")); // - - } - - @Test - public void shouldGetOwnerById() throws Exception { - given(clinicService.findOwnerById(1)).willReturn(setupOwners().get(1)); - - mvc.perform(get("/api/owner/1") // - .accept(MediaType.APPLICATION_JSON)) // - .andExpect(status().isOk()) // - .andExpect(content().contentType("application/json;charset=UTF-8")) // - .andExpect(jsonPath("$.id").value(1)) // - .andExpect(jsonPath("$.city").value("Mainz")) // - .andExpect(jsonPath("$.lastName").value("Mueck")); // - } - - @Test - public void shouldFindOwners() throws Exception { - final List owners = setupOwners(); - owners.remove(1); - given(clinicService.findOwnerByLastName("mueller")).willReturn(owners); - mvc.perform(get("/api/owner/list/?lastName=mueller") // - .accept(MediaType.APPLICATION_JSON)) // - .andExpect(status().isOk()) - .andExpect(content().contentType("application/json;charset=UTF-8")) // - .andExpect(jsonPath("$.[0].id").value(0)) - .andExpect(jsonPath("$.[1].id").value(2)); // - } - - - @Test - public void shouldCreateOwner() throws Exception { - - doAnswer(new Answer() { - public Void answer(InvocationOnMock invocation) { - Owner receivedOwner = (Owner) invocation.getArguments()[0]; - receivedOwner.setId(666); - return null; - } - }).when(clinicService).saveOwner((Owner) anyObject()); - - final Owner newOwner = setupOwners().get(0); - newOwner.setId(null); - - ObjectMapper mapper = new ObjectMapper(); - String ownerAsJsonString = mapper.writeValueAsString(newOwner); - newOwner.setId(666); - String newOwnerAsJsonString = - mapper.writeValueAsString(newOwner); - - mvc.perform(post("/api/owner") // - .content(ownerAsJsonString).accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON)) // - .andExpect(status().isCreated()) - .andExpect(content().json(newOwnerAsJsonString)) - ; - } - - @Test - public void shouldReturnBindingErrors() throws Exception { - - final Owner newOwner = setupOwners().get(0); - newOwner.setId(null); - newOwner.setLastName(null); - - ObjectMapper mapper = new ObjectMapper(); - String ownerAsJsonString = mapper.writeValueAsString(newOwner); - - mvc.perform(post("/api/owner") // - .content(ownerAsJsonString).accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON)) // - .andExpect(status().isUnprocessableEntity()) - .andExpect(content().contentType("application/json")) // - .andExpect(jsonPath("$.fieldErrors.lastName").isNotEmpty()) // - - ; - } - - private List setupOwners() { - - final List owners = new LinkedList(); - - Owner owner = new Owner(); - owner.setId(0); - owner.setAddress("My Street 123"); - owner.setCity("Hamburg"); - owner.setFirstName("Klaus-Dieter"); - owner.setLastName("Mueller"); - owner.setTelephone("1234567"); - owners.add(owner); - - owner = new Owner(); - owner.setId(1); - owner.setAddress("Hier und Da 123"); - owner.setCity("Mainz"); - owner.setFirstName("Hein"); - owner.setLastName("Mueck"); - owner.setTelephone("765432"); - owners.add(owner); - - owner = new Owner(); - owner.setId(2); - owner.setAddress("Lange Reihe"); - owner.setCity("Hamburg"); - owner.setFirstName("Peter"); - owner.setLastName("Mueller"); - owner.setTelephone("445566"); - owners.add(owner); - - return owners; - - } -} \ No newline at end of file diff --git a/src/test/java/org/springframework/samples/petclinic/web/api/PetResourceTests.java b/src/test/java/org/springframework/samples/petclinic/web/api/PetResourceTests.java deleted file mode 100644 index 3d64fad6..00000000 --- a/src/test/java/org/springframework/samples/petclinic/web/api/PetResourceTests.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.springframework.samples.petclinic.web.api; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MockMvc; - -import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@RunWith(SpringRunner.class) -@WebMvcTest(PetResource.class) -public class PetResourceTests { - - @Autowired - private MockMvc mvc; - - @MockBean - ClinicService clinicService; - - @Test - public void shouldGetAPetInJSonFormat() throws Exception { - - Pet pet = setupPet(); - - given(clinicService.findPetById(2)).willReturn(pet); - - mvc.perform(get("/api/owners/2/pets/2") // - .accept(MediaType.APPLICATION_JSON)) // - .andExpect(status().isOk()) // - .andExpect(content().contentType("application/json;charset=UTF-8")) // - .andExpect(jsonPath("$.id").value(2)) // - .andExpect(jsonPath("$.name").value("Basil")) // - .andExpect(jsonPath("$.typeId").value(6)); // - } - - private Pet setupPet() { - Owner owner = new Owner(); - owner.setFirstName("George"); - owner.setLastName("Bush"); - - Pet pet = new Pet(); - - pet.setName("Basil"); - pet.setId(2); - - PetType petType = new PetType(); - petType.setId(6); - pet.setType(petType); - - owner.addPet(pet); - return pet; - } -} \ No newline at end of file diff --git a/src/test/java/org/springframework/samples/petclinic/web/api/VetResourceTests.java b/src/test/java/org/springframework/samples/petclinic/web/api/VetResourceTests.java deleted file mode 100644 index 6752b075..00000000 --- a/src/test/java/org/springframework/samples/petclinic/web/api/VetResourceTests.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.springframework.samples.petclinic.web.api; - -import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.util.Arrays; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.samples.petclinic.model.Vet; -import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MockMvc; - -@RunWith(SpringRunner.class) -@WebMvcTest(VetResource.class) -public class VetResourceTests { - - @Autowired - private MockMvc mvc; - - @MockBean - ClinicService clinicService; - - @Test - public void shouldGetAListOfVetsInJSonFormat() throws Exception { - - Vet vet = new Vet(); - vet.setId(1); - - given(clinicService.findVets()).willReturn(Arrays.asList(vet)); - - mvc.perform(get("/api/vets.json") // - .accept(MediaType.APPLICATION_JSON)) // - .andExpect(status().isOk()) // - .andExpect(jsonPath("$[0].id").value(1)); - } - -} \ No newline at end of file diff --git a/src/test/jmeter/petclinic_test_plan.jmx b/src/test/jmeter/petclinic_test_plan.jmx deleted file mode 100644 index 5e942b13..00000000 --- a/src/test/jmeter/petclinic_test_plan.jmx +++ /dev/null @@ -1,411 +0,0 @@ - - - - - - false - false - - - - PETCLINIC_HOST - localhost - = - - - PETCLINIC_PORT - 8080 - = - - - CONTEXT_WEB - - = - - - - - - - - continue - - false - 10 - - 500 - 10 - 1361531541000 - 1361531541000 - false - - - true - Original : 500 - 10 - 10 - - - - 300 - - - - - - - ${PETCLINIC_HOST} - ${PETCLINIC_PORT} - - - - - - 4 - - - - - true - - - - 1 - 10 - 1 - count - - false - - - - 1 - 13 - 1 - petCount - - false - - - - - - - - - - - - - ${CONTEXT_WEB}/ - GET - true - false - true - false - false - - - - - - - - - - - - - - ${CONTEXT_WEB}/resources/css/petclinic.css - GET - true - false - true - false - false - - - - - - - - - - - - - - ${CONTEXT_WEB}/vendors/jquery/jquery.js - GET - true - false - true - false - false - - - - - - - - - - - - - - ${CONTEXT_WEB}/vets.html - GET - true - false - true - false - false - - - - - - - - - - - - - - ${CONTEXT_WEB}/owners/find.html - GET - true - false - true - false - false - - - - - - - - - - - - - - ${CONTEXT_WEB}/owners.html?lastName= - GET - true - false - true - false - false - - - - - - - - - - - - - - ${CONTEXT_WEB}/owners/${count}.html - GET - true - false - true - false - false - - - - - - - - - - - - - - ${CONTEXT_WEB}/owners/${count}/edit.html - GET - true - false - true - false - false - - - - - true - - - - false - firstName=Test&lastName=${count}&address=1234+Test+St.&city=TestCity&telephone=612345678 - = - - - - - - - - - - ${CONTEXT_WEB}/owners/${count}/edit.html - POST - true - false - true - false - false - - - - - - - - - - - - - - ${CONTEXT_WEB}/owners/${count}/pets/${petCount}/visits/new - GET - true - false - true - false - false - - - - - true - - - - false - date=2013%2F02%2F22&description=visit - = - - - - - - - - - - ${CONTEXT_WEB}/owners/${count}/pets/${petCount}/visits/new - POST - true - false - true - false - false - - - - - - - - - - - - - - ${CONTEXT_WEB}/owners/${count}.html - GET - true - false - true - false - false - - - - - false - - saveConfig - - - true - true - true - - true - true - true - true - false - true - true - false - false - false - false - false - false - false - false - 0 - true - true - - - - - - - false - - saveConfig - - - true - true - true - - true - true - true - true - false - true - true - false - false - false - false - false - false - false - false - 0 - true - true - - - - - - - - - diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties new file mode 100644 index 00000000..31f3b808 --- /dev/null +++ b/src/test/resources/application.properties @@ -0,0 +1,39 @@ +# active profiles config +# +# application use two active profiles +# +# one for select repository layer +# ------------------------------------------------ +# When using HSQL, use: hsqldb +# When using MySQL, use: mysql +# When using PostgeSQL, use: postgresql +# ------------------------------------------------ +# +# one - for select database +# ------------------------------------------------ +# When using Spring jpa, use: jpa +# When using Spring JDBC, use: jdbc +# When using Spring Data JPA, use: spring-data-jpa +# ------------------------------------------------ + +spring.profiles.active=hsqldb,spring-data-jpa + +# ------------------------------------------------ + +server.port=9966 +server.servlet.context-path=/petclinic/ +spring.jpa.open-in-view=false + +spring.messages.basename=messages/messages +logging.level.org.springframework=INFO +#logging.level.org.springframework=DEBUG + +#logging.level.org.hibernate.SQL=DEBUG +#logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE + +# enable the desired authentication type +# by default the authentication is disabled +security.ignored=/** +basic.authentication.enabled=true +petclinic.security.enable=true +