diff --git a/.eslintrc b/.eslintrc index 7fb97d884d338ddfa1a4b3df9f16f8922b4d5ea1..29c077b01d5f285d44c0443c781dcfa2d74361cc 100644 --- a/.eslintrc +++ b/.eslintrc @@ -4,10 +4,7 @@ "mocha": true, "es6": true }, - "extends": [ - "eslint:recommended", - "plugin:react/recommended" - ], + "extends": ["eslint:recommended", "plugin:react/recommended"], "parser": "babel-eslint", "parserOptions": { "sourceType": "module", @@ -16,31 +13,18 @@ }, "ecmaVersion": 2018 }, - "plugins": [ - "react" - ], + "plugins": ["react"], "settings": { "react": { - "version": require('./package.json').dependencies.react, - }, + "version": require("./package.json").dependencies.react + } }, "rules": { - "indent": [ - "error", - 2 - ], - "no-console": [ - "error", - { allow: ["warn", "error"] } - ], + "indent": ["error", 2], + "no-console": ["error", { "allow": ["warn", "error"] }], "space-before-function-paren": 0, - "semi": [ - "warn", - "never" - ], - "space-infix-ops": [ - "warn" - ], + "semi": ["warn", "never"], + "space-infix-ops": ["warn"], "no-var": "error", "prefer-const": "error", "no-trailing-spaces": "error", @@ -53,6 +37,6 @@ "ignoreTemplateLiterals": true } ], - "no-multi-spaces": 2, + "no-multi-spaces": 2 } } diff --git a/.gitignore b/.gitignore index 2e0ebe6262b38bade28232bd0325017c010b4e42..2266a24fe246539458cc1de4e4cf1749b65c495a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ # .DS_Store +# VSCode +.vscode/ + # Xcode # build/ @@ -65,6 +68,7 @@ android/app/.project ios/Podfile.lock android/app/src/main/res/drawable-* +android/app/src/main/assets/* # nodejs-mobile creates these with every npm install nodejs-assets/nodejs-project/sample-* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 11be4dff58e0b26b99f8a0d13876f8095351cef2..2bbf312c3898e6220844550e6e88bf580ca92347 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to drip aka CONDRIBUTING +# Contributing to drip aka CONDRIPUTING So good to see you here, hello :wave\_tone1: :wave\_tone2: :wave\_tone3: :wave\_tone4: :wave\_tone5: @@ -8,7 +8,7 @@ So good to see you here, hello :wave\_tone1: :wave\_tone2: :wave\_tone3: :wave\_ [What should I know before I get started?](#what-should-i-know-before-i-get-started) -[How can I condribute?](#how-can-i-condribute) +[How can I condripute?](#how-can-i-condripute) [Thank you](#thank-you) @@ -23,9 +23,9 @@ We have prepared something for **you**: check out our [README](https://gitlab.co Let us know if you want to suggest improvements for the README and open a merge request (which is just like Github's pull request) -## How can I condribute? +## How can I condripute? -### Your First Code Condribution +### Your First Code Condripution We are fans of labels, at least for our issues. You can find a list of `newbie` issues [here](https://gitlab.com/bloodyhealth/drip/issues?label_name%5B%5D=Newbie). If you decide to work on an issue, please click on `Create branch` based on that issue. You can find this as a dropdown option right under `Create merge request`. @@ -54,5 +54,5 @@ To send us a new issue you can also use our [gitlab email](mailto:incoming+blood  -Thank you for condributing to open source, thank you for condributing to drip! +Thank you for condriputing to open source, thank you for condriputing to drip! Much love from Bloody Health :heart\_exclamation: diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index e1f7e77e45f21ba0b155f9f53e9a7ac76d232661..c5d85cf7b11df89377a435d9bbd2db838d506b6b 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -23,13 +23,15 @@ android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" + android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize" - android:windowSoftInputMode="adjustResize"> + android:windowSoftInputMode="adjustResize" + android:screenOrientation="sensorPortrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> diff --git a/android/app/src/main/assets/fonts/Jost-400-Book.otf b/android/app/src/main/assets/fonts/Jost-400-Book.otf new file mode 100644 index 0000000000000000000000000000000000000000..7abf6cf32f1ddaccfe24bb94406995096b62539a Binary files /dev/null and b/android/app/src/main/assets/fonts/Jost-400-Book.otf differ diff --git a/android/app/src/main/assets/fonts/Jost-700-Bold.otf b/android/app/src/main/assets/fonts/Jost-700-Bold.otf new file mode 100644 index 0000000000000000000000000000000000000000..0c7d6759a5564fc03872f5bf05f8c6fd7fd772cf Binary files /dev/null and b/android/app/src/main/assets/fonts/Jost-700-Bold.otf differ diff --git a/android/app/src/main/ic_launcher-web.png b/android/app/src/main/ic_launcher-web.png old mode 100644 new mode 100755 index ddb8d27df7820120ede78650424d4cf29d361bbe..80bf3b97c412ac56ae4fd91fb1bf521529ce3d79 Binary files a/android/app/src/main/ic_launcher-web.png and b/android/app/src/main/ic_launcher-web.png differ diff --git a/android/app/src/main/res/font/jost400.otf b/android/app/src/main/res/font/jost400.otf new file mode 100644 index 0000000000000000000000000000000000000000..7abf6cf32f1ddaccfe24bb94406995096b62539a Binary files /dev/null and b/android/app/src/main/res/font/jost400.otf differ diff --git a/android/app/src/main/res/font/jost_normal.xml b/android/app/src/main/res/font/jost_normal.xml new file mode 100644 index 0000000000000000000000000000000000000000..c5222c384d49e257fb0c236d768ecdc82210ff7d --- /dev/null +++ b/android/app/src/main/res/font/jost_normal.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<font-family xmlns:android="http://schemas.android.com/apk/res/android"> + <font + android:font="@font/jost400" + android:fontStyle="normal" + android:fontWeight="400" /> +</font-family> \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index 036d09bc5fd523323794379703c4a111d1e28a04..0000000000000000000000000000000000000000 --- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> - <background android:drawable="@color/ic_launcher_background"/> - <foreground android:drawable="@mipmap/ic_launcher_foreground"/> -</adaptive-icon> \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index 036d09bc5fd523323794379703c4a111d1e28a04..0000000000000000000000000000000000000000 --- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> - <background android:drawable="@color/ic_launcher_background"/> - <foreground android:drawable="@mipmap/ic_launcher_foreground"/> -</adaptive-icon> \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png old mode 100644 new mode 100755 index e5a65c8d061f88d74c7cda412e290ac51e967f95..66a8ef350a14bf6bd51ec7f0ad89d127f7d967b0 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png deleted file mode 100644 index fd2730dae9e5e5a0ec0aa5aa6d00893aa145e212..0000000000000000000000000000000000000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png old mode 100644 new mode 100755 index e5a65c8d061f88d74c7cda412e290ac51e967f95..eb3a7f9a41d07ae12fdc241e39ed134e9b851f4c Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_notification.png b/android/app/src/main/res/mipmap-hdpi/ic_notification.png old mode 100644 new mode 100755 index 58405822bf648ee118a2416345c123b3fcd13c61..8ba134795100609a1813d685d04e032001ec72f7 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_notification.png and b/android/app/src/main/res/mipmap-hdpi/ic_notification.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png old mode 100644 new mode 100755 index d89472084779542c16826cb25e8c09b5179d5cc9..3973daef7c0f912c8e2d5e7393bb616ef7ef9dc6 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png deleted file mode 100644 index f127df225cccce7f106b8ad0216c3fdc360500a6..0000000000000000000000000000000000000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png old mode 100644 new mode 100755 index d89472084779542c16826cb25e8c09b5179d5cc9..1ad111e632e1921d731b0e2d33076eb1643830bb Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_notification.png b/android/app/src/main/res/mipmap-mdpi/ic_notification.png old mode 100644 new mode 100755 index 003156a561f7fb781c3a8e95d310147e5ca59505..5093ea01123d38fcb27369f66de462f125f6b924 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_notification.png and b/android/app/src/main/res/mipmap-mdpi/ic_notification.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png old mode 100644 new mode 100755 index 9654b8701077d42321cb7257c5349b98581c0ba1..424386b201651e1cf366c9f0e083a7783446f86c Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png deleted file mode 100644 index ea3a6ba78792a96d51ed5f83ed3a8cc7136f52e7..0000000000000000000000000000000000000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png old mode 100644 new mode 100755 index 9654b8701077d42321cb7257c5349b98581c0ba1..945bf23eedbc1669fa99acedab23b09b9cbe561b Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_notification.png b/android/app/src/main/res/mipmap-xhdpi/ic_notification.png old mode 100644 new mode 100755 index 1bdb4bd53e9e6b94bf8daf92b194331d50f6c9d0..9d6e5eea33161ee9dee92c820b9098a4a784942f Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_notification.png and b/android/app/src/main/res/mipmap-xhdpi/ic_notification.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png old mode 100644 new mode 100755 index 49cef5311fde2a0fb38213a96ed7613001f625d9..4d024f0e9937c5d4294df0ea94e332b8d14ec9af Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png deleted file mode 100644 index c637a3fc2388080667d41895ff3f8ea36064775d..0000000000000000000000000000000000000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png old mode 100644 new mode 100755 index 49cef5311fde2a0fb38213a96ed7613001f625d9..9d5aafe927a003b6f1aeb634f8e0e6c31c816a96 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_notification.png b/android/app/src/main/res/mipmap-xxhdpi/ic_notification.png old mode 100644 new mode 100755 index 9af70b030606f70a4d6666dd5434aa2d998ea239..8a6edab4d451f9c20e32428c9b5fe6242079f91c Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_notification.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_notification.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png old mode 100644 new mode 100755 index 11c63249a68a9e12b290bf9da761365c0a92bc25..5ad1890a738ff2c263a24ed8d9bd88f9c694cec7 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png deleted file mode 100644 index a1eed6e1b9566284d0c809bcca5af1d3578a32a8..0000000000000000000000000000000000000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png old mode 100644 new mode 100755 index 11c63249a68a9e12b290bf9da761365c0a92bc25..50cb4adae34ab1088cbb75ab2866361a00b40e75 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_notification.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_notification.png old mode 100644 new mode 100755 index 45e66248aff96311c3ea623827fd3a1dd88669be..d646430ae31a31cfb2b88af8614bc00552e168e7 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_notification.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_notification.png differ diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml index 6f1943f11f511295454f0e9be46644b56ab324ff..caab5fcf882c299fb668f311b6b8c0109944274f 100644 --- a/android/app/src/main/res/values/colors.xml +++ b/android/app/src/main/res/values/colors.xml @@ -9,4 +9,9 @@ <!-- a secondary color for controls like checkboxes and text fields --> <color name="colorAccent">#4FAFA7</color> + + <!-- custom colors --> + <color name="grey">#A5A5A5</color> + <color name="orange">#F38337</color> + <color name="purple">#3A2671</color> </resources> \ No newline at end of file diff --git a/android/app/src/main/res/values/ic_launcher_background.xml b/android/app/src/main/res/values/ic_launcher_background.xml index 2f6d956d83a884b25dabee9551f1f74b04167a46..fde0f6a6de9c3a9f4340cd2a2e0675dd4103cdd2 100644 --- a/android/app/src/main/res/values/ic_launcher_background.xml +++ b/android/app/src/main/res/values/ic_launcher_background.xml @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <color name="ic_launcher_background">#000D19</color> -</resources> \ No newline at end of file + <color name="ic_launcher_background">#3A2671</color> +</resources> diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index 553627547dbff979337a41fe1b6a93433ba2887f..97b7d4f91235e29e6c1a2be8c4078699e0d36de8 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -3,7 +3,27 @@ <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!-- Customize your theme here. --> + <item name="colorPrimary">@color/colorPrimary</item> + <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> + <style name="ButtonBarStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog"> + <item name="android:textSize">16sp</item> + <item name="android:textColor">@color/grey</item> + </style> + + <style name="PositiveButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog"> + <item name="android:textSize">16sp</item> + <item name="android:textStyle">bold</item> + <item name="android:textColor">@color/orange</item> + </style> + + <style name="TitleStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog"> + <item name="android:gravity">left</item> + <item name="android:textColor">@color/purple</item> + <item name="android:textSize">22sp</item> + <item name="android:textStyle">bold</item> + </style> + </resources> diff --git a/assets/cycle-icon.png b/assets/cycle-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..aa225b33c335eb00adf59f5e181743f1439a9ead Binary files /dev/null and b/assets/cycle-icon.png differ diff --git a/assets/fonts/Jost-400-Book.otf b/assets/fonts/Jost-400-Book.otf new file mode 100644 index 0000000000000000000000000000000000000000..7abf6cf32f1ddaccfe24bb94406995096b62539a Binary files /dev/null and b/assets/fonts/Jost-400-Book.otf differ diff --git a/assets/fonts/Jost-700-Bold.otf b/assets/fonts/Jost-700-Bold.otf new file mode 100644 index 0000000000000000000000000000000000000000..0c7d6759a5564fc03872f5bf05f8c6fd7fd772cf Binary files /dev/null and b/assets/fonts/Jost-700-Bold.otf differ diff --git a/assets/fonts/Menu.ttf b/assets/fonts/Menu.ttf new file mode 100644 index 0000000000000000000000000000000000000000..985d8eeebc1d9fea33d57f044b75805f8329cb6a Binary files /dev/null and b/assets/fonts/Menu.ttf differ diff --git a/assets/swipe.png b/assets/swipe.png new file mode 100644 index 0000000000000000000000000000000000000000..5ddf77a60613ded3ba79eaa9e0cf5274df919d1f Binary files /dev/null and b/assets/swipe.png differ diff --git a/components/app-loading.js b/components/app-loading.js deleted file mode 100644 index ebac28fde0e527f2d07d4be54393c2d0d7cb7914..0000000000000000000000000000000000000000 --- a/components/app-loading.js +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react' - -import { View } from 'react-native' - -import AppText from './app-text' -import { shared } from '../i18n/en/labels' - -const AppLoadingView = () => { - return ( - <View flex={1}> - <View style={{flex:1, justifyContent: 'center'}}> - <AppText style={{alignSelf: 'center'}}>{shared.loading}</AppText> - </View> - </View> - ) -} - -export default AppLoadingView diff --git a/components/app-text-input.js b/components/app-text-input.js deleted file mode 100644 index 54e4a19d82a41f7ae5f510847f05a8dcf31f7449..0000000000000000000000000000000000000000 --- a/components/app-text-input.js +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { TextInput } from 'react-native' -import styles from '../styles' - -export default function AppTextInput({ style, ...props }) { - if (!Array.isArray(style)) style = [style] - return ( - <TextInput - style={[styles.textInputField, ...style]} - autoFocus={props.autoFocus} - onChangeText={props.onChangeText} - value={props.value} - placeholder={props.placeholder} - {...props} - /> - ) -} - -AppTextInput.propTypes = { - autoFocus: PropTypes.bool, - onChangeText: PropTypes.func, - placeholder: PropTypes.string, - style: PropTypes.oneOfType([PropTypes.array, PropTypes.object]), - value: PropTypes.string, -} - -AppTextInput.defaultProps = { - style: [] -} diff --git a/components/app-text.js b/components/app-text.js deleted file mode 100644 index e2c621004cb640ed21dbb11cf5ae2ae1349ff375..0000000000000000000000000000000000000000 --- a/components/app-text.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { Text } from 'react-native' -import styles from "../styles" -import Link from './link' - -export default function AppText({ children, onPress, numberOfLines, style}) { - // we parse for links in case the text contains any - return ( - <Link> - <Text style={[styles.appText, style]} - onPress={onPress} - numberOfLines={numberOfLines} - > - {children} - </Text> - </Link> - ) -} - -AppText.propTypes = { - children: PropTypes.node, - onPress: PropTypes.func, - numberOfLines: PropTypes.number, - style: PropTypes.oneOfType([PropTypes.array, PropTypes.object]), -} diff --git a/components/app-wrapper.js b/components/app-wrapper.js index fc70bcd8b3645a68285b9d2798c253a5df6dfab7..cef5d0667cb7c40edb260d585b4b8c59f09a04b8 100644 --- a/components/app-wrapper.js +++ b/components/app-wrapper.js @@ -7,7 +7,7 @@ import { openDb } from '../db' import App from './app' import PasswordPrompt from './password-prompt' import License from './license' -import AppLoadingView from './app-loading' +import AppLoadingView from './common/app-loading' import store from "../store" import { Provider } from 'react-redux' diff --git a/components/app.js b/components/app.js index 37ba5c5a3e3e821345bdf79a26ede649706887b5..f8a03501bea95ffc00c320d7583b10786c6386ec 100644 --- a/components/app.js +++ b/components/app.js @@ -1,5 +1,5 @@ import React, { Component } from 'react' -import { View, BackHandler } from 'react-native' +import { BackHandler, StyleSheet, View } from 'react-native' import PropTypes from 'prop-types' import { connect } from 'react-redux' @@ -10,7 +10,7 @@ import { getNavigation, navigate, goBack } from '../slices/navigation' import Header from './header' import Menu from './menu' import { viewsList } from './views' -import { isSymptomView, isSettingsView } from './pages' +import { isSettingsView } from './pages' import { headerTitles } from '../i18n/en/labels' import setupNotifications from '../lib/notifications' @@ -64,9 +64,8 @@ class App extends Component { const Page = viewsList[currentPage] const title = headerTitles[currentPage] - const isSymptomEditView = isSymptomView(currentPage) const isSettingsSubView = isSettingsView(currentPage) - const isCycleDayView = currentPage === 'CycleDay' + const isTemperatureEditView = currentPage === 'TemperatureEditView' const headerProps = { title, @@ -76,24 +75,25 @@ class App extends Component { const pageProps = { cycleDay: date && getCycleDay(date), date, + isTemperatureEditView, } return ( - <View style={{ flex: 1 }}> - { - !isSymptomEditView && - !isCycleDayView && - <Header { ...headerProps } /> - } - + <View style={styles.container}> + <Header { ...headerProps } /> <Page { ...pageProps } /> - - { !isSymptomEditView && <Menu /> } + <Menu /> </View> ) } } +const styles = StyleSheet.create({ + container: { + flex: 1 + } +}) + const mapStateToProps = (state) => { return({ date: getDate(state), diff --git a/components/button.js b/components/button.js deleted file mode 100644 index be06408152cfc2095d3e9c5a17e85163d89a52aa..0000000000000000000000000000000000000000 --- a/components/button.js +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { TouchableOpacity } from 'react-native' -import AppText from './app-text' -import styles from '../styles' - -export default function Button({ - backgroundColor, - children, - onPress, - style, - testID -}) { - return ( - <TouchableOpacity - onPress={onPress} - style={[styles.button, style, { backgroundColor }]} - testID={testID} - > - <AppText style={styles.homeButtonText}>{children}</AppText> - </TouchableOpacity> - ) -} - -Button.propTypes = { - backgroundColor: PropTypes.string, - children: PropTypes.node, - onPress: PropTypes.func, - style: PropTypes.object, - testID: PropTypes.string -} diff --git a/components/calendar.js b/components/calendar.js index 2340168d3ec28aa30b255334add4b6219540127f..80ac49f9ef59b3d7d800df33ace6ed6653d2212a 100644 --- a/components/calendar.js +++ b/components/calendar.js @@ -1,22 +1,26 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' +import { StyleSheet, View } from 'react-native' import { CalendarList } from 'react-native-calendars' -import { connect } from 'react-redux' +import { connect } from 'react-redux' import { setDate } from '../slices/date' import { navigate } from '../slices/navigation' -import { LocalDate } from 'js-joda' import { getBleedingDaysSortedByDate } from '../db' import cycleModule from '../lib/cycle' -import { shadesOfRed, calendarTheme } from '../styles/index' -import styles from '../styles/index' import nothingChanged from '../db/db-unchanged' +import { + calendarTheme, + predictionToCalFormat, + toCalFormat, + todayToCalFormat, +} from './helpers/calendar' class CalendarView extends Component { static propTypes = { setDate: PropTypes.func.isRequired, - navigate: PropTypes.func.isRequired + navigate: PropTypes.func.isRequired, } constructor(props) { @@ -26,7 +30,7 @@ class CalendarView extends Component { this.state = { bleedingDaysInCalFormat: toCalFormat(this.bleedingDays), predictedBleedingDaysInCalFormat: predictionToCalFormat(predictedMenses), - todayInCalFormat: todayToCalFormat() + todayInCalFormat: todayToCalFormat(), } this.bleedingDays.addListener(this.setStateWithCalFormattedDays) @@ -38,7 +42,7 @@ class CalendarView extends Component { this.setState({ bleedingDaysInCalFormat: toCalFormat(this.bleedingDays), predictedBleedingDaysInCalFormat: predictionToCalFormat(predictedMenses), - todayInCalFormat: todayToCalFormat() + todayInCalFormat: todayToCalFormat(), }) } @@ -52,93 +56,44 @@ class CalendarView extends Component { } render() { + const { + todayInCalFormat, + bleedingDaysInCalFormat, + predictedBleedingDaysInCalFormat, + } = this.state + const markedDates = Object.assign( + {}, + todayInCalFormat, + bleedingDaysInCalFormat, + predictedBleedingDaysInCalFormat + ) + return ( - <CalendarList - onDayPress={this.passDateToDayView.bind(this)} - markedDates={ - Object.assign( - {}, - this.state.todayInCalFormat, - this.state.bleedingDaysInCalFormat, - this.state.predictedBleedingDaysInCalFormat - ) - } - markingType={'custom'} - // If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday. - firstDay={1} - theme={calendarTheme} - /> + <View style={styles.container}> + <CalendarList + // If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday. + firstDay={1} + onDayPress={this.passDateToDayView.bind(this)} + markedDates={markedDates} + markingType='custom' + theme={calendarTheme} + // Max amount of months allowed to scroll to the past. + pastScrollRange={120} + /> + </View> ) } } +const styles = StyleSheet.create({ + container: { flex: 1 }, +}) + const mapDispatchToProps = (dispatch) => { - return({ + return { setDate: (date) => dispatch(setDate(date)), navigate: (page) => dispatch(navigate(page)), - }) -} - -export default connect( - null, - mapDispatchToProps, -)(CalendarView) - - -function toCalFormat(bleedingDaysSortedByDate) { - const todayDateString = LocalDate.now().toString() - return bleedingDaysSortedByDate.reduce((acc, day) => { - acc[day.date] = { - customStyles: { - container: { - backgroundColor: shadesOfRed[day.bleeding.value], - } - } - } - if (day.date === todayDateString) { - acc[day.date].customStyles.text = styles.calendarToday - } - return acc - }, {}) -} - -function predictionToCalFormat(predictedDays) { - if (!predictedDays.length) return {} - const todayDateString = LocalDate.now().toString() - const middleIndex = (predictedDays[0].length - 1) / 2 - return predictedDays.reduce((acc, setOfDays) => { - setOfDays.reduce((accSet, day, i) => { - accSet[day] = { - customStyles: { - container: { - borderColor: (i === middleIndex) ? shadesOfRed[3] : shadesOfRed[2], - borderWidth: 3, - }, - text: { - marginTop: 1, - } - } - } - if (day === todayDateString) { - accSet[day].customStyles.text = Object.assign( - {}, - styles.calendarToday, - {marginTop: -2} - ) - } - return accSet - }, acc) - return acc - }, {}) + } } -function todayToCalFormat() { - const todayDateString = LocalDate.now().toString() - const todayFormated = {} - todayFormated[todayDateString] = { - customStyles: { - text: styles.calendarToday - } - } - return todayFormated -} \ No newline at end of file +export default connect(null, mapDispatchToProps)(CalendarView) diff --git a/components/chart/chart-legend.js b/components/chart/chart-legend.js index 4dc00b629f8051e40b55893c1cba9c9426b0ed4d..9d6e8cc3de60c3bd351ec05dd4d17bf900322dff 100644 --- a/components/chart/chart-legend.js +++ b/components/chart/chart-legend.js @@ -1,32 +1,38 @@ import React from 'react' import PropTypes from 'prop-types' -import { View } from 'react-native' +import { StyleSheet, View } from 'react-native' -import AppText from '../app-text' -import DripHomeIcon from '../../assets/drip-home-icons' - -import styles from './styles' -import { cycleDayColor } from '../../styles' +import AppText from '../common/app-text' +import { Typography } from '../../styles' +import { CHART_YAXIS_WIDTH } from '../../config' import { shared as labels } from '../../i18n/en/labels' -const ChartLegend = ({ xAxisHeight }) => { +const ChartLegend = ({ height }) => { return ( - <View style={[styles.yAxis, styles.chartLegend, {height: xAxisHeight}]}> - <DripHomeIcon - name="circle" - size={styles.yAxis.width - 7} - color={cycleDayColor} - /> - <AppText style={styles.yAxisLabels.dateLabel}> - {labels.date.toLowerCase()} - </AppText> + <View style={[styles.container, { height }]}> + <AppText style={styles.textBold}>#</AppText> + <AppText style={styles.text}>{labels.date}</AppText> </View> ) } ChartLegend.propTypes = { - xAxisHeight: PropTypes.number.isRequired + height: PropTypes.number.isRequired } +const styles = StyleSheet.create({ + container: { + alignItems: 'center', + justifyContent: 'flex-end', + width: CHART_YAXIS_WIDTH + }, + text: { + ...Typography.label, + }, + textBold: { + ...Typography.labelBold + } +}) + export default ChartLegend diff --git a/components/chart/chart-line.js b/components/chart/chart-line.js index 95300ad3bcb3dce3c59eb308656763f831cc0ff3..30f27327448fe1a4de6596382c0c79a074e59ad4 100644 --- a/components/chart/chart-line.js +++ b/components/chart/chart-line.js @@ -3,20 +3,16 @@ import PropTypes from 'prop-types' import { Shape } from 'react-native/Libraries/ART/ReactNativeART' -import styles from './styles' +import { Colors } from '../../styles' +import { CHART_STROKE_WIDTH, CHART_GRID_LINE_HORIZONTAL_WIDTH } from '../../config' -const ChartLine = ({ path, isNfpLine = false }) => { - const strokeStyle = - isNfpLine ? styles.nfpLine.stroke : styles.column.stroke.color - const strokeWidth = - isNfpLine ? styles.nfpLine.strokeWidth : styles.column.stroke.width +const ChartLine = ({ path, isNfpLine }) => { + const color = isNfpLine ? Colors.orange : Colors.grey + const width = isNfpLine + ? CHART_STROKE_WIDTH : CHART_GRID_LINE_HORIZONTAL_WIDTH * 2.5 return ( - <Shape - stroke={strokeStyle} - strokeWidth={strokeWidth} - d={path} - /> + <Shape d={path} stroke={color} strokeWidth={width} /> ) } @@ -25,4 +21,8 @@ ChartLine.propTypes = { isNfpLine: PropTypes.bool, } +ChartLine.defaultProps = { + isNfpLine: false +} + export default ChartLine diff --git a/components/chart/chart.js b/components/chart/chart.js index 9b6b7c35f2844dc22ff438d1d83188ff15a7a1c5..0dc364e09778500f5da5859602ae937615b7e793 100644 --- a/components/chart/chart.js +++ b/components/chart/chart.js @@ -1,26 +1,33 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { View, FlatList, ActivityIndicator } from 'react-native' +import { ActivityIndicator, FlatList, Dimensions, StyleSheet, View } from 'react-native' + +import AppLoadingView from '../common/app-loading' +import AppPage from '../common/app-page' +import AppText from '../common/app-text' -import NoData from './no-data' -import AppLoadingView from '../app-loading' -import YAxis from './y-axis' -import nfpLines from './nfp-lines' import DayColumn from './day-column' import HorizontalGrid from './horizontal-grid' -import AppText from '../app-text' +import NoData from './no-data' +import Tutorial from './tutorial' +import YAxis from './y-axis' import { connect } from 'react-redux' import { navigate } from '../../slices/navigation' import { getCycleDaysSortedByDate } from '../../db' import nothingChanged from '../../db/db-unchanged' -import { scaleObservable } from '../../local-storage' -import { makeColumnInfo } from '../helpers/chart' - -import config from '../../config' +import { getChartFlag, scaleObservable, setChartFlag } from '../../local-storage' +import { makeColumnInfo, nfpLines } from '../helpers/chart' + +import { + CHART_COLUMN_WIDTH, + SYMPTOMS, + CHART_SYMPTOM_HEIGHT_RATIO, + CHART_XAXIS_HEIGHT_RATIO +} from '../../config' import { shared } from '../../i18n/en/labels' -import styles from './styles' +import { Colors, Spacing } from '../../styles' class CycleChart extends Component { static propTypes = { @@ -36,13 +43,37 @@ class CycleChart extends Component { this.getFhmAndLtlInfo = nfpLines() this.shouldShowTemperatureColumn = false + this.checkShouldShowHint() this.prepareSymptomData() } + componentWillUnmount() { + this.cycleDaysSortedByDate.removeListener(this.handleDbChange) + this.removeObvListener() + } + + checkShouldShowHint = async () => { + const flag = await getChartFlag() + const shouldShowHint = flag === 'true' ? true : false + this.setState({ shouldShowHint }) + } + + setShouldShowHint = async () => { + await setChartFlag() + this.setState({ shouldShowHint: false }) + } + + onLayout = () => { + if (this.state.chartHeight) return false + + this.reCalculateChartInfo() + this.updateListeners(this.reCalculateChartInfo) + } + prepareSymptomData = () => { - this.symptomRowSymptoms = config.symptoms.filter((symptomName) => { + this.symptomRowSymptoms = SYMPTOMS.filter((symptomName) => { return this.cycleDaysSortedByDate.some(cycleDay => { - return cycleDay[symptomName] + return (symptomName !== 'temperature') && cycleDay[symptomName] }) }) this.chartSymptoms = [...this.symptomRowSymptoms] @@ -69,35 +100,23 @@ class CycleChart extends Component { ) } - reCalculateChartInfo = (nativeEvent) => { - const { height, width } = nativeEvent.layout - const xAxisCoefficient = this.shouldShowTemperatureColumn ? - config.xAxisHeightPercentage : config.xAxisHeightPercentageLarge - const symptomCoefficient = this.shouldShowTemperatureColumn ? - config.symptomHeightPercentage : config.symptomHeightPercentageLarge + reCalculateChartInfo = () => { + const { width, height } = Dimensions.get('window') - this.xAxisHeight = height * xAxisCoefficient - const remainingHeight = height - this.xAxisHeight - this.symptomHeight = remainingHeight * symptomCoefficient + this.xAxisHeight = height * 0.7 * CHART_XAXIS_HEIGHT_RATIO + const remainingHeight = height * 0.7 - this.xAxisHeight + this.symptomHeight = remainingHeight * CHART_SYMPTOM_HEIGHT_RATIO this.symptomRowHeight = this.symptomRowSymptoms.length * this.symptomHeight this.columnHeight = remainingHeight - this.symptomRowHeight const chartHeight = this.shouldShowTemperatureColumn ? - height : (this.symptomRowHeight + this.xAxisHeight) - - const numberOfColumnsToRender = Math.round(width / config.columnWidth) + height * 0.7 : (this.symptomRowHeight + this.xAxisHeight) + const numberOfColumnsToRender = Math.round(width / CHART_COLUMN_WIDTH) const columns = makeColumnInfo() this.setState({ columns, chartHeight, numberOfColumnsToRender }) } - onLayout = ({ nativeEvent }) => { - if (this.state.chartHeight) return - - this.reCalculateChartInfo(nativeEvent) - this.updateListeners(this.reCalculateChartInfo) - } - updateListeners(dataUpdateHandler) { // remove existing listeners if(this.handleDbChange) { @@ -114,38 +133,47 @@ class CycleChart extends Component { this.removeObvListener = scaleObservable(dataUpdateHandler, false) } - componentWillUnmount() { - this.cycleDaysSortedByDate.removeListener(this.handleDbChange) - this.removeObvListener() - } - render() { - const { chartHeight, chartLoaded, numberOfColumnsToRender } = this.state - const shouldShowChart = this.chartSymptoms.length > 0 ? true : false + const { + chartHeight, + chartLoaded, + shouldShowHint, + numberOfColumnsToRender + } = this.state + const hasDataToDisplay = this.chartSymptoms.length > 0 return ( - <View onLayout={this.onLayout} style={styles.container}> - {!shouldShowChart && <NoData navigate={this.props.navigate}/>} - {shouldShowChart && !chartHeight && !chartLoaded && <AppLoadingView />} + <AppPage + contentContainerStyle={styles.pageContainer} + onLayout={this.onLayout} + scrollViewStyle={styles.page} + > + {!hasDataToDisplay && <NoData />} + {hasDataToDisplay && !chartHeight && !chartLoaded && <AppLoadingView />} <View style={styles.chartContainer}> - {shouldShowChart && ( + {shouldShowHint && chartLoaded && + <Tutorial onClose={this.setShouldShowHint} /> + } + {hasDataToDisplay && chartLoaded && + !this.shouldShowTemperatureColumn && + <View style={styles.centerItem}> + <AppText style={styles.warning}> + {shared.noTemperatureWarning} + </AppText> + </View> + } + {hasDataToDisplay && ( <View style={styles.chartArea}> {chartHeight && chartLoaded && ( - <React.Fragment> - <YAxis - height={this.columnHeight} - symptomsToDisplay={this.symptomRowSymptoms} - symptomsSectionHeight={this.symptomRowHeight} - shouldShowTemperatureColumn= - {this.shouldShowTemperatureColumn} - xAxisHeight={this.xAxisHeight} - /> - {this.shouldShowTemperatureColumn && (<HorizontalGrid - height={this.columnHeight} - startPosition={this.symptomRowHeight} - />)} - </React.Fragment> + <YAxis + height={this.columnHeight} + symptomsToDisplay={this.symptomRowSymptoms} + symptomsSectionHeight={this.symptomRowHeight} + shouldShowTemperatureColumn= + {this.shouldShowTemperatureColumn} + xAxisHeight={this.xAxisHeight} + /> )} {chartHeight && @@ -162,27 +190,28 @@ class CycleChart extends Component { onEndReached={() => this.setState({end: true})} ListFooterComponent={<LoadingMoreView end={this.state.end}/>} updateCellsBatchingPeriod={800} - contentContainerStyle={{height: chartHeight}} + contentContainerStyle={{ height: chartHeight }} /> } + {chartHeight && chartLoaded && ( + <React.Fragment> + {this.shouldShowTemperatureColumn && + <HorizontalGrid height={this.columnHeight} /> + } + </React.Fragment> + )} </View> )} </View> - {shouldShowChart && chartLoaded && !this.shouldShowTemperatureColumn - && ( - <View style={styles.centerItem}> - <AppText style={{textAlign: 'center'}}>{shared.noTemperatureWarning}</AppText> - </View> - )} - </View> + </AppPage> ) } } function LoadingMoreView({ end }) { return ( - <View style={styles.loadingMore}> - {!end && <ActivityIndicator size={'large'} color={'white'}/>} + <View style={styles.loadingContainer}> + {!end && <ActivityIndicator size={'large'} color={Colors.orange}/>} </View> ) } @@ -191,6 +220,29 @@ LoadingMoreView.propTypes = { end: PropTypes.bool } +const styles = StyleSheet.create({ + chartArea: { + flexDirection: 'row' + }, + chartContainer: { + flexDirection: 'column' + }, + loadingContainer: { + height: '100%', + backgroundColor: Colors.turquoiseLight, + justifyContent: 'center' + }, + page: { + marginVertical: Spacing.small + }, + pageContainer: { + paddingHorizontal: Spacing.base + }, + warning: { + padding: Spacing.large + } +}) + const mapDispatchToProps = (dispatch) => { return({ navigate: (page) => dispatch(navigate(page)), diff --git a/components/chart/cycle-day-label.js b/components/chart/cycle-day-label.js index bb794f4f9e3e36c7cef01b74b50a70594300c979..1f8a82fa34405aec2a768d216c63e2f6cfeb4bdb 100644 --- a/components/chart/cycle-day-label.js +++ b/components/chart/cycle-day-label.js @@ -1,32 +1,35 @@ import React from 'react' import PropTypes from 'prop-types' - -import { Text, View } from 'react-native' - +import { StyleSheet, View } from 'react-native' import moment from 'moment' -import { LocalDate } from 'js-joda' -import styles from './styles' +import AppText from '../common/app-text' + import cycleModule from '../../lib/cycle' +import { getOrdinalSuffix } from '../helpers/home' +import { Containers, Typography, Sizes } from '../../styles' const CycleDayLabel = ({ height, date }) => { - const { label } = styles.column - const dayDate = LocalDate.parse(date) const cycleDayNumber = cycleModule().getCycleDayNumber(date) + const cycleDayLabel = cycleDayNumber ? cycleDayNumber : ' ' - const isFirstDayOfMonth = dayDate.dayOfMonth() === 1 - const dateFormatting = isFirstDayOfMonth ? 'MMM' : 'Do' - const shortDate = moment(date, "YYYY-MM-DD").format(dateFormatting) - const boldDateLabel = isFirstDayOfMonth ? {fontWeight: 'bold'} : {} + const momentDate = moment(date) + const dayOfMonth = momentDate.date() + const isFirstDayOfMonth = dayOfMonth === 1 return ( - <View style={[styles.chartLegend, { height }]}> - <Text style={label.number}> - {cycleDayNumber ? cycleDayNumber : ' '} - </Text> - <Text style={[label.date, boldDateLabel]}> - {shortDate} - </Text> + <View style={[styles.container, { height }]}> + <AppText style={styles.textBold}>{cycleDayLabel}</AppText> + <View style={styles.dateLabel}> + <AppText style={styles.text}> + {isFirstDayOfMonth ? momentDate.format('MMM') : dayOfMonth} + </AppText> + {!isFirstDayOfMonth && + <AppText style={styles.textLight}> + {getOrdinalSuffix(dayOfMonth)} + </AppText> + } + </View> </View> ) } @@ -36,4 +39,30 @@ CycleDayLabel.propTypes = { date: PropTypes.string, } +const styles = StyleSheet.create({ + container: { + alignItems: 'flex-start', + justifyContent: 'flex-end', + left: 4, + }, + containerRow: { + ...Containers.rowContainer + }, + text: { + ...Typography.label, + fontSize: Sizes.small, + }, + textBold: { + ...Typography.labelBold + }, + textLight: { + ...Typography.labelLight, + }, + dateLabel: { + flexDirection: 'row', + justifyContent: 'space-around', + alignItems: 'center', + } +}) + export default CycleDayLabel diff --git a/components/chart/day-column.js b/components/chart/day-column.js index efefe2ed4fc9f0e22f0316f0dfcfcdb223e1aea4..2eb37107ef8a0ca5192ff9a441448f63b236e1d8 100644 --- a/components/chart/day-column.js +++ b/components/chart/day-column.js @@ -92,10 +92,23 @@ class DayColumn extends Component { activeOpacity={1} > - { symptomRowSymptoms.map(symptom => { + {shouldShowTemperatureColumn && <TemperatureColumn + horizontalLinePosition={this.fhmAndLtl.drawLtlAt} + isVerticalLine={this.fhmAndLtl.drawFhmLine} + data={this.data && this.data.temperature} + columnHeight={columnHeight} + />} + + <CycleDayLabel + height={xAxisHeight} + date={dateString} + /> + + { symptomRowSymptoms.map((symptom, i) => { const hasSymptomData = this.data.hasOwnProperty(symptom) return ( <SymptomCell + index={i} key={symptom} symptom={symptom} symptomValue={hasSymptomData && this.data[symptom]} @@ -107,18 +120,6 @@ class DayColumn extends Component { } )} - {shouldShowTemperatureColumn && <TemperatureColumn - horizontalLinePosition={this.fhmAndLtl.drawLtlAt} - isVerticalLine={this.fhmAndLtl.drawFhmLine} - data={this.data && this.data.temperature} - columnHeight={columnHeight} - />} - - <CycleDayLabel - height={xAxisHeight} - date={dateString} - /> - </TouchableOpacity> ) } diff --git a/components/chart/dot-and-line.js b/components/chart/dot-and-line.js index be5be85271bc2305c37c0762c33abefdd75f2e98..335e72ccde20a8f39a476cf05e57d27ab0eb5820 100644 --- a/components/chart/dot-and-line.js +++ b/components/chart/dot-and-line.js @@ -2,8 +2,14 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import { Path, Shape } from 'react-native/Libraries/ART/ReactNativeART' -import styles from './styles' -import config from '../../config' +import { Colors } from '../../styles' + +import { + CHART_COLUMN_WIDTH, + CHART_COLUMN_MIDDLE, + CHART_DOT_RADIUS, + CHART_STROKE_WIDTH +} from '../../config' export default class DotAndLine extends Component { static propTypes = { @@ -20,48 +26,62 @@ export default class DotAndLine extends Component { } render() { - const y = this.props.y - const exclude = this.props.exclude - let lineToRight - let lineToLeft + const { + exclude, + leftTemperatureExclude, + leftY, + rightTemperatureExclude, + rightY, + y + } = this.props + let excludeLeftLine, excludeRightLine, lineLeft, lineRight - if (this.props.leftY) { - const middleY = ((this.props.leftY - y) / 2) + y - const excludedLine = this.props.leftTemperatureExclude || exclude - lineToLeft = makeLine(y, middleY, 0, excludedLine) + if (leftY) { + const middleY = ((leftY - y) / 2) + y + excludeLeftLine = leftTemperatureExclude || exclude + lineLeft = new Path() + .moveTo(CHART_COLUMN_MIDDLE, y) + .lineTo(0, middleY) } - if (this.props.rightY) { - const middleY = ((y - this.props.rightY) / 2) + this.props.rightY - const excludedLine = this.props.rightTemperatureExclude || exclude - lineToRight = makeLine(y, middleY, config.columnWidth, excludedLine) + if (rightY) { + const middleY = ((y - rightY) / 2) + rightY + excludeRightLine = rightTemperatureExclude || exclude + lineRight = new Path() + .moveTo(CHART_COLUMN_MIDDLE, y) + .lineTo(CHART_COLUMN_WIDTH, middleY) } - const dotStyle = exclude ? styles.curveDotsExcluded : styles.curveDots - const radius = dotStyle.r - const dot = ( - <Shape - d={new Path() - .moveTo(config.columnMiddle, y - radius) - .arc(0, radius * 2, radius) - .arc(0, radius * -2, radius) - } - fill={dotStyle.fill} - key='dot' - /> + const dot = new Path().moveTo(CHART_COLUMN_MIDDLE , y - CHART_DOT_RADIUS) + .arc(0, CHART_DOT_RADIUS * 2, CHART_DOT_RADIUS) + .arc(0, CHART_DOT_RADIUS * -2, CHART_DOT_RADIUS) + const dotColor = exclude ? Colors.turquoise : Colors.turquoiseDark + const lineColorLeft = excludeLeftLine ? + Colors.turquoise : Colors.turquoiseDark + const lineColorRight = excludeRightLine ? + Colors.turquoise : Colors.turquoiseDark + + return( + <React.Fragment> + <Shape + d={lineLeft} + stroke={lineColorLeft} + strokeWidth={CHART_STROKE_WIDTH} + key={y} + /> + <Shape + d={lineRight} + stroke={lineColorRight} + strokeWidth={CHART_STROKE_WIDTH} + key={y + CHART_DOT_RADIUS} + /> + <Shape + d={dot} + stroke={dotColor} + strokeWidth={CHART_STROKE_WIDTH} + fill="white" + key='dot' + /> + </React.Fragment> ) - return [lineToLeft, lineToRight, dot] } } - -function makeLine(currY, middleY, x, excludeLine) { - const lineStyle = excludeLine ? styles.curveExcluded : styles.curve - - return <Shape - stroke={lineStyle.stroke} - d={new Path() - .moveTo(config.columnMiddle, currY) - .lineTo(x, middleY) - } - key={x.toString()} - /> -} \ No newline at end of file diff --git a/components/chart/horizontal-grid.js b/components/chart/horizontal-grid.js index e7cf7cc1b7fe7ee6f6d1cd72f60d998028121a35..95502486a2e3f0643c43eb65baa75361b51637ba 100644 --- a/components/chart/horizontal-grid.js +++ b/components/chart/horizontal-grid.js @@ -1,26 +1,33 @@ import React from 'react' import PropTypes from 'prop-types' -import { View } from 'react-native' +import { StyleSheet, View } from 'react-native' import { getTickPositions } from '../helpers/chart' -import styles from './styles' +import { Colors } from '../../styles' +import { CHART_GRID_LINE_HORIZONTAL_WIDTH, CHART_YAXIS_WIDTH } from '../../config' -const HorizontalGrid = ({ height, startPosition }) => { +const HorizontalGrid = ({ height }) => { return getTickPositions(height).map(tick => { return ( - <View - top={startPosition + tick} - {...styles.horizontalGrid} - key={tick} - /> + <View key={tick} top={tick} {...styles.line}/> ) }) } HorizontalGrid.propTypes = { - height: PropTypes.number, - startPosition: PropTypes.number, + height: PropTypes.number } +const styles = StyleSheet.create({ + line: { + borderStyle: 'solid', + borderBottomColor: Colors.grey, + borderBottomWidth: CHART_GRID_LINE_HORIZONTAL_WIDTH, + left: CHART_YAXIS_WIDTH, + position:'absolute', + right: 0 + } +}) + export default HorizontalGrid diff --git a/components/chart/nfp-lines.js b/components/chart/nfp-lines.js deleted file mode 100644 index 853dde54f634dc27c330be9d05a3fbf31b88a977..0000000000000000000000000000000000000000 --- a/components/chart/nfp-lines.js +++ /dev/null @@ -1,85 +0,0 @@ -import { getCycleStatusForDay } from '../../lib/sympto-adapter' -import { normalizeToScale } from '../helpers/chart' - -export default function () { - const cycle = { - status: null - } - - function updateCurrentCycle(dateString) { - // for the NFP lines, we don't care about potentially extending the - // preOvu phase, so we don't include all earlier cycles, as that is - // an expensive db operation at the moment - cycle.status = getCycleStatusForDay( - dateString, { excludeEarlierCycles: true } - ) - if(!cycle.status) { - cycle.noMoreCycles = true - return - } - if (cycle.status.phases.preOvulatory) { - cycle.startDate = cycle.status.phases.preOvulatory.start.date - } else { - cycle.startDate = cycle.status.phases.periOvulatory.start.date - } - } - - function dateIsInPeriOrPostPhase(dateString) { - return ( - dateString >= cycle.status.phases.periOvulatory.start.date - ) - } - - function precededByAnotherTempValue(dateString) { - return ( - // we are only interested in days that have a preceding - // temp - Object.keys(cycle.status.phases).some(phaseName => { - return cycle.status.phases[phaseName].cycleDays.some(day => { - return day.temperature && day.date < dateString - }) - }) - // and also a following temp, so we don't draw the line - // longer than necessary - && - cycle.status.phases.postOvulatory.cycleDays.some(day => { - return day.temperature && day.date > dateString - }) - ) - } - - function isInTempMeasuringPhase(temperature, dateString) { - return ( - temperature || precededByAnotherTempValue(dateString) - ) - } - - return function(dateString, temperature, columnHeight) { - const ret = { - drawLtlAt: null, - drawFhmLine: false - } - if (!cycle.status && !cycle.noMoreCycles) updateCurrentCycle(dateString) - if (cycle.noMoreCycles) return ret - - if (dateString < cycle.startDate) updateCurrentCycle(dateString) - if (cycle.noMoreCycles) return ret - - const tempShift = cycle.status.temperatureShift - - if (tempShift) { - if (tempShift.firstHighMeasurementDay.date === dateString) { - ret.drawFhmLine = true - } - - if ( - dateIsInPeriOrPostPhase(dateString) && - isInTempMeasuringPhase(temperature, dateString) - ) { - ret.drawLtlAt = normalizeToScale(tempShift.ltl, columnHeight) - } - } - - return ret - } -} \ No newline at end of file diff --git a/components/chart/no-data.js b/components/chart/no-data.js index efb1ce3c1b87057482d8b8ad25688ee5d34d7d08..154ca516dd57f5897437d33d7b60fa5a98d171f1 100644 --- a/components/chart/no-data.js +++ b/components/chart/no-data.js @@ -1,31 +1,44 @@ import React from 'react' +import { StyleSheet, View } from 'react-native' import PropTypes from 'prop-types' -import { View } from 'react-native' -import AppText from '../app-text' -import SettingsButton from '../settings/shared/settings-button' +import AppText from '../common/app-text' +import Button from '../common/button' +import { connect } from 'react-redux' +import { navigate } from '../../slices/navigation' + +import { Containers } from '../../styles' import { shared } from '../../i18n/en/labels' -import styles from './styles' const NoData = ({ navigate }) => { return ( - <View flex={1}> - <View style={styles.centerItem}> - <AppText>{shared.noDataWarning}</AppText> - <SettingsButton - onPress={() => {navigate('CycleDay')}} - style={{marginHorizontal: 40}} - > - {shared.noDataButtonText} - </SettingsButton> - </View> + <View style={styles.container}> + <AppText>{shared.noDataWarning}</AppText> + <Button isCTA onPress={() => {navigate('CycleDay')}}> + {shared.noDataButtonText} + </Button> </View> ) } NoData.propTypes = { - navigate: PropTypes.func, + navigate: PropTypes.func.isRequired, +} + +const styles = StyleSheet.create({ + container: { + ...Containers.centerItems + } +}) + +const mapDispatchToProps = (dispatch) => { + return({ + navigate: (page) => dispatch(navigate(page)), + }) } -export default NoData \ No newline at end of file +export default connect( + null, + mapDispatchToProps, +)(NoData) \ No newline at end of file diff --git a/components/chart/styles.js b/components/chart/styles.js deleted file mode 100644 index fba4df1806d82c27328acabb4ec9ce4344506942..0000000000000000000000000000000000000000 --- a/components/chart/styles.js +++ /dev/null @@ -1,174 +0,0 @@ -import config from '../../config' -import { shadesOfRed, cycleDayColor } from '../../styles/index' - -const colorTemperature = '#765285' -const colorTemperatureLight = '#a67fb5' -export const dotRadius = 5 -const lineWidth = 1.5 -const colorLtl = '#feb47b' -const gridColor = '#d3d3d3' -const gridLineWidthVertical = 0.6 -const gridLineWidthHorizontal = 0.3 -const numberLabelFontSize = 13 - -const redColor = '#c3000d' -const violetColor = '#6a7b98' -const shadesOfViolet = ['#e3e7ed', '#c8cfdc', '#acb8cb', '#91a0ba', '#7689a9', violetColor] // light to dark -const yellowColor = '#dbb40c' -const shadesOfYellow = ['#f0e19d', '#e9d26d', '#e2c33c', yellowColor] // light to dark -const magentaColor = '#6f2565' -const shadesOfMagenta = ['#a87ca2', '#8b5083', magentaColor] // light to dark -const pinkColor = '#9e346c' -const shadesOfPink = ['#c485a6', '#b15c89', pinkColor] // light to dark -const lightGreenColor = '#bccd67' -const orangeColor = '#bc6642' -const mintColor = '#6ca299' - -const styles = { - container: { flex: 1 }, - chartContainer: { flexDirection: 'column' }, - chartArea: { flexDirection: 'row' }, - centerItem: { - flex:1, - alignItems: 'center', - justifyContent: 'center', - marginHorizontal: 25, - }, - curve: { - stroke: colorTemperature, - strokeWidth: lineWidth, - }, - curveExcluded: { - stroke: colorTemperatureLight, - strokeWidth: lineWidth - }, - curveDots: { - fill: colorTemperature, - r: dotRadius - }, - curveDotsExcluded: { - fill: colorTemperatureLight, - r: dotRadius - }, - column: { - label: { - date: { - color: 'grey', - fontSize: 9, - fontWeight: '100', - textAlign: 'center', - paddingTop: 2.5 - }, - number: { - color: cycleDayColor, - fontSize: numberLabelFontSize, - textAlign: 'center', - } - }, - stroke: { - color: gridColor, - width: gridLineWidthVertical, - } - }, - symptomDot: { - width: 12, - height: 12, - borderRadius: 50, - }, - iconColors: { - 'bleeding': { - color: redColor, - shades: shadesOfRed, - }, - 'mucus': { - color: violetColor, - shades: shadesOfViolet, - }, - 'cervix': { - color: yellowColor, - shades: shadesOfYellow, - }, - 'sex': { - color: magentaColor, - shades: shadesOfMagenta, - }, - 'desire': { - color: pinkColor, - shades: shadesOfPink, - }, - 'pain': { - color: lightGreenColor, - shades: [lightGreenColor], - }, - 'mood': { - color: orangeColor, - shades: [orangeColor], - }, - 'note': { - color: mintColor, - shades: [mintColor], - }, - }, - yAxis: { - width: 27, - borderRightWidth: 1, - borderColor: 'lightgrey', - borderStyle: 'solid' - }, - yAxisLabels: { - tempScale: { - position: 'absolute', - right: 2, - color: 'grey', - fontSize: 9, - textAlign: 'left' - }, - cycleDayLabel: { - textAlign: 'center', - justifyContent: 'center', - fontSize: Math.ceil(numberLabelFontSize / 2) - }, - dateLabel: { - textAlign: 'center', - justifyContent: 'center', - color: 'grey', - fontSize: 9, - fontWeight: '100', - } - }, - symptomIcon: { - alignItems: 'center', - justifyContent: 'center', - }, - chartLegend: { - alignItems: 'center', - justifyContent: 'flex-end', - }, - boldTick: { - fontWeight: 'bold', - fontSize: 11, - }, - horizontalGrid: { - position:'absolute', - borderStyle: 'solid', - borderBottomColor: gridColor, - borderBottomWidth: gridLineWidthHorizontal, - width: '100%', - left: config.columnWidth - }, - nfpLine: { - stroke: colorLtl, - strokeWidth: lineWidth, - }, - symptomRow: { - alignItems: 'center', - justifyContent: 'center', - }, - loadingMore: { - height: '100%', - backgroundColor: 'lightgrey', - justifyContent: 'center' - } -} - -export default styles \ No newline at end of file diff --git a/components/chart/symptom-cell.js b/components/chart/symptom-cell.js index 4b1124c181b0d9a523ec59d217302dbe7216cc41..ef8caa143bbf2f922a3da765f6d5ebec195bfdc4 100644 --- a/components/chart/symptom-cell.js +++ b/components/chart/symptom-cell.js @@ -1,47 +1,49 @@ import React from 'react' import PropTypes from 'prop-types' -import { View } from 'react-native' +import { StyleSheet, View } from 'react-native' -import styles from './styles' -import config from '../../config' +import { Colors, Containers } from '../../styles' +import { + CHART_COLUMN_WIDTH, + CHART_DOT_RADIUS, + CHART_GRID_LINE_HORIZONTAL_WIDTH +} from '../../config' const SymptomCell = ({ height, + index, symptom, symptomValue, isSymptomDataComplete }) => { const shouldDrawDot = symptomValue !== false - const styleParent = [styles.symptomRow, { height, width: config.columnWidth }] - let styleChild + const styleCell = index !== 0 + ? [styles.cell, { height, width: CHART_COLUMN_WIDTH }] + : [styles.cell, { height, width: CHART_COLUMN_WIDTH }, styles.topBorder] + let styleDot if (shouldDrawDot) { - const styleSymptom = styles.iconColors[symptom] + const styleSymptom = Colors.iconColors[symptom] const symptomColor = styleSymptom.shades[symptomValue] - const isMucusOrCervix = (symptom === 'mucus') || (symptom === 'cervix') - const backgroundColor = (isMucusOrCervix && !isSymptomDataComplete) ? 'white' : symptomColor const borderWidth = (isMucusOrCervix && !isSymptomDataComplete) ? 2 : 0 const borderColor = symptomColor - styleChild = [styles.symptomDot, { - backgroundColor, - borderColor, - borderWidth - }] + styleDot = [styles.dot, { backgroundColor, borderColor, borderWidth }] } return ( - <View style={styleParent} key={symptom}> - {shouldDrawDot && <View style={styleChild} />} + <View style={styleCell} key={symptom}> + {shouldDrawDot && <View style={styleDot} />} </View> ) } SymptomCell.propTypes = { height: PropTypes.number, + index: PropTypes.number.isRequired, symptom: PropTypes.string, symptomValue: PropTypes.oneOfType([ PropTypes.bool, @@ -50,4 +52,23 @@ SymptomCell.propTypes = { isSymptomDataComplete: PropTypes.bool, } +const styles = StyleSheet.create({ + cell: { + backgroundColor: 'white', + borderBottomColor: Colors.grey, + borderBottomWidth: CHART_GRID_LINE_HORIZONTAL_WIDTH, + borderLeftColor: Colors.grey, + borderLeftWidth: CHART_GRID_LINE_HORIZONTAL_WIDTH, + ...Containers.centerItems + }, + topBorder: { + borderTopColor: Colors.grey, + borderTopWidth: CHART_GRID_LINE_HORIZONTAL_WIDTH, + }, + dot: { + width: CHART_DOT_RADIUS * 2, + height: CHART_DOT_RADIUS * 2, + borderRadius: 50 + } +}) export default SymptomCell diff --git a/components/chart/symptom-icon.js b/components/chart/symptom-icon.js index 3236c3b044009c998bff77c8f065beb769aa20e2..1bd5c6c632b9a471ccea089f7db2c282a601e428 100644 --- a/components/chart/symptom-icon.js +++ b/components/chart/symptom-icon.js @@ -1,18 +1,19 @@ import React from 'react' import PropTypes from 'prop-types' -import { View } from 'react-native' +import { StyleSheet , View } from 'react-native' import DripIcon from '../../assets/drip-icons' -import styles from './styles' +import { Colors, Containers } from '../../styles' +import { CHART_YAXIS_WIDTH, CHART_ICON_SIZE } from '../../config' const SymptomIcon = ({ symptom, height }) => { return ( - <View style={styles.symptomIcon} width={styles.yAxis.width} height={height}> + <View style={styles.container} width={CHART_YAXIS_WIDTH} height={height}> <DripIcon - size={16} + size={CHART_ICON_SIZE} name={`drip-icon-${symptom}`} - color={styles.iconColors[symptom].color} + color={Colors.iconColors[symptom].color} /> </View> ) @@ -23,4 +24,10 @@ SymptomIcon.propTypes = { symptom: PropTypes.string, } +const styles = StyleSheet.create({ + container: { + ...Containers.centerItems + } +}) + export default SymptomIcon diff --git a/components/chart/temperature-column.js b/components/chart/temperature-column.js index fab3d976970198ee2e66c9af2d15a6000c4c32bf..3ae377902210103c142a2c260dafbfb6b6f92034 100644 --- a/components/chart/temperature-column.js +++ b/components/chart/temperature-column.js @@ -1,13 +1,13 @@ import React from 'react' import PropTypes from 'prop-types' +import { StyleSheet } from 'react-native' import { Surface , Path } from 'react-native/Libraries/ART/ReactNativeART' import ChartLine from './chart-line' import DotAndLine from './dot-and-line' -import styles from './styles' -import config from '../../config' +import { CHART_COLUMN_WIDTH, CHART_STROKE_WIDTH } from '../../config' const TemperatureColumn = ({ horizontalLinePosition, @@ -15,20 +15,21 @@ const TemperatureColumn = ({ data, columnHeight }) => { - - const x = styles.nfpLine.strokeWidth / 2 + const x = CHART_STROKE_WIDTH / 2 return ( - <Surface width={config.columnWidth} height={columnHeight}> + <Surface + width={CHART_COLUMN_WIDTH} + height={columnHeight} + style={styles.container} + > - <ChartLine - path={new Path().lineTo(0, columnHeight)} - /> + <ChartLine path={new Path().lineTo(0, columnHeight)}/> {horizontalLinePosition && <ChartLine path={new Path() .moveTo(0, horizontalLinePosition) - .lineTo(config.columnWidth, horizontalLinePosition) + .lineTo(CHART_COLUMN_WIDTH, horizontalLinePosition) } isNfpLine={true} key='ltl' @@ -40,7 +41,7 @@ const TemperatureColumn = ({ key='fhm' />} - {data && data.y && <DotAndLine + {data && typeof(data.y) !== 'undefined' && <DotAndLine y={data.y} exclude={data.temperatureExclude} rightY={data.rightY} @@ -61,4 +62,10 @@ TemperatureColumn.propTypes = { columnHeight: PropTypes.number, } +const styles = StyleSheet.create({ + container: { + backgroundColor: 'white' + } +}) + export default TemperatureColumn diff --git a/components/chart/tick-list.js b/components/chart/tick-list.js index 16fba0af4065148a95ae0d743748d25e15e42cf7..63af7da7c4e637b606b681b7889c3926c6cd5dbf 100644 --- a/components/chart/tick-list.js +++ b/components/chart/tick-list.js @@ -1,29 +1,31 @@ import React from 'react' import PropTypes from 'prop-types' -import { View } from 'react-native' +import { StyleSheet, View } from 'react-native' import Tick from './tick' import { getTickList } from '../helpers/chart' -import styles from './styles' - const TickList = ({ height }) => { + return ( - <View style={[styles.yAxis, { height }]}>{ - getTickList(height) - .map(({ label, position, isBold, shouldShowLabel}) => { - return ( - <Tick - key={label} - yPosition={position} - isBold={isBold} - shouldShowLabel={shouldShowLabel} - label={label} - /> - ) - }) - }</View> + <View style={[styles.container, height]}> + { + getTickList(height) + .map(({ isBold, label, position, shouldShowLabel, tickHeight}) => { + return ( + <Tick + height={tickHeight} + isBold={isBold} + key={label} + label={label} + shouldShowLabel={shouldShowLabel} + yPosition={position} + /> + ) + }) + } + </View> ) } @@ -31,4 +33,10 @@ TickList.propTypes = { height: PropTypes.number, } +const styles = StyleSheet.create({ + container: { + flex: 1 + } +}) + export default TickList diff --git a/components/chart/tick.js b/components/chart/tick.js index 173cfbe6036f47a1005b3fe6f9fa8f88cd3f6a40..f492c80d1332aeb95b391f81531cf44b5e791fb7 100644 --- a/components/chart/tick.js +++ b/components/chart/tick.js @@ -1,29 +1,53 @@ import React from 'react' +import { StyleSheet, View } from 'react-native' import PropTypes from 'prop-types' -import AppText from '../app-text' +import AppText from '../common/app-text' -import styles from './styles' +import { Sizes } from '../../styles' -const Tick = ({ yPosition, isBold, shouldShowLabel, label }) => { - // this eyeballing is sadly necessary because RN does not - // support percentage values for transforms, which we'd need - // to reliably place the label vertically centered to the grid - const topPosition = yPosition - 8 - const style = [ - styles.yAxisLabels.tempScale, - {top: topPosition}, - isBold && styles.boldTick - ] +const Tick = ({ yPosition, height, isBold, shouldShowLabel, label }) => { + const top = yPosition - height / 2 + const containerStyle = [ styles.container, { flexBasis: height, height, top }] + const textStyle = isBold ? styles.textBold : styles.textNormal - return <AppText style={style}>{shouldShowLabel && label}</AppText> + return( + <View style={containerStyle}> + <AppText style={textStyle}>{shouldShowLabel && label}</AppText> + </View> + ) } Tick.propTypes = { yPosition: PropTypes.number, + height: PropTypes.number.isRequired, isBold: PropTypes.bool, shouldShowLabel: PropTypes.bool, label: PropTypes.string, } + +const text = { + lineHeight: Sizes.base, + right: 4, + textAlign: 'right' +} +const styles = StyleSheet.create({ + container: { + justifyContent: 'center', + position: 'absolute', + right: 0, + width: 40 + }, + textBold: { + fontSize: Sizes.base, + fontWeight: 'bold', + ...text + }, + textNormal: { + fontSize: Sizes.small, + ...text + } +}) + export default Tick diff --git a/components/chart/tutorial.js b/components/chart/tutorial.js new file mode 100644 index 0000000000000000000000000000000000000000..fefe28784d8de01e3fabf27baa9d4d7cf6d393a3 --- /dev/null +++ b/components/chart/tutorial.js @@ -0,0 +1,42 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Image, StyleSheet, View } from 'react-native' + +import AppText from '../common/app-text' +import CloseIcon from '../common/close-icon' + +import { Containers, Spacing } from '../../styles' +import { chart } from '../../i18n/en/labels' + +const image = require('../../assets/swipe.png') + +const Tutorial = ({ onClose }) => { + return ( + <View style={styles.container}> + <Image resizeMode='contain' source={image} style={styles.image} /> + <View style={styles.textContainer}> + <AppText>{chart.tutorial}</AppText> + </View> + <CloseIcon onClose={onClose} /> + </View> + ) +} + +Tutorial.propTypes = { + onClose: PropTypes.func.isRequired +} + +const styles = StyleSheet.create({ + container: { + ...Containers.rowContainer, + padding: Spacing.large + }, + image: { + height: 40 + }, + textContainer: { + width: '70%' + } +}) + +export default Tutorial \ No newline at end of file diff --git a/components/chart/y-axis.js b/components/chart/y-axis.js index db27e1008966a14290b4f26f4b27926a62b3f708..c9e13f20daab32db90a6c84c6969f9de3dbda59a 100644 --- a/components/chart/y-axis.js +++ b/components/chart/y-axis.js @@ -1,12 +1,12 @@ import React from 'react' import PropTypes from 'prop-types' -import { View } from 'react-native' +import { StyleSheet, View } from 'react-native' import SymptomIcon from './symptom-icon' import TickList from './tick-list' import ChartLegend from './chart-legend' -import styles from './styles' +import { CHART_YAXIS_WIDTH } from '../../config' const YAxis = ({ height, @@ -19,6 +19,8 @@ const YAxis = ({ return ( <View> + {shouldShowTemperatureColumn && <TickList height={height} />} + <ChartLegend height={xAxisHeight} /> <View style={[styles.yAxis, {height: symptomsSectionHeight}]}> {symptomsToDisplay.map(symptom => ( <SymptomIcon @@ -29,8 +31,6 @@ const YAxis = ({ ) )} </View> - {shouldShowTemperatureColumn && <TickList height={height} />} - <ChartLegend xAxisHeight={xAxisHeight} /> </View> ) } @@ -43,4 +43,10 @@ YAxis.propTypes = { xAxisHeight: PropTypes.number.isRequired } +const styles = StyleSheet.create({ + yAxis: { + width: CHART_YAXIS_WIDTH + } +}) + export default YAxis diff --git a/components/common/app-icon.js b/components/common/app-icon.js new file mode 100644 index 0000000000000000000000000000000000000000..717c1e0675767499fb42f082c693a58dcacfcb29 --- /dev/null +++ b/components/common/app-icon.js @@ -0,0 +1,30 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { StyleSheet } from 'react-native' +import Icon from 'react-native-vector-icons/Entypo' + +import { Sizes } from '../../styles' + +const AppIcon = ({ color, name, style, ...props }) => { + const iconStyle = [styles.icon, style, { color }] + + return <Icon name={name} style={iconStyle} {...props} /> +} + +AppIcon.propTypes = { + color: PropTypes.string, + name: PropTypes.string.isRequired, + style: PropTypes.object +} + +AppIcon.defaultProps = { + color: 'black' +} + +const styles = StyleSheet.create({ + icon: { + fontSize: Sizes.subtitle + } +}) + +export default AppIcon \ No newline at end of file diff --git a/components/common/app-loading.js b/components/common/app-loading.js new file mode 100644 index 0000000000000000000000000000000000000000..115d2dc84b08e8efeef240e29d3371349bb55510 --- /dev/null +++ b/components/common/app-loading.js @@ -0,0 +1,24 @@ +import React from 'react' +import { StyleSheet, View } from 'react-native' + +import AppText from './app-text' + +import { Containers } from '../../styles' + +import { shared } from '../../i18n/en/labels' + +const AppLoadingView = () => { + return ( + <View style={styles.container}> + <AppText>{shared.loading}</AppText> + </View> + ) +} + +const styles = StyleSheet.create({ + container: { + ...Containers.centerItems + } +}) + +export default AppLoadingView diff --git a/components/common/app-modal.js b/components/common/app-modal.js new file mode 100644 index 0000000000000000000000000000000000000000..0f28882042d397258c359f118ffcf34f605bffa2 --- /dev/null +++ b/components/common/app-modal.js @@ -0,0 +1,32 @@ +import React from 'react' +import { Modal, StyleSheet, TouchableOpacity } from 'react-native' +import PropTypes from 'prop-types' + +const AppModal = ({ children, onClose }) => { + return( + <Modal + animationType='fade' + onRequestClose={onClose} + transparent={true} + visible={true} + > + <TouchableOpacity onPress={onClose} style={styles.blackBackground} /> + {children} + </Modal> + ) +} + +AppModal.propTypes = { + children: PropTypes.node, + onClose: PropTypes.func +} + +const styles = StyleSheet.create({ + blackBackground: { + backgroundColor: 'black', + flex: 1, + opacity: 0.5, + } +}) + +export default AppModal diff --git a/components/common/app-page.js b/components/common/app-page.js new file mode 100644 index 0000000000000000000000000000000000000000..0ffde8d04c29f2b9a00277ff65be2c31bd0b4cdb --- /dev/null +++ b/components/common/app-page.js @@ -0,0 +1,51 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { ScrollView, StyleSheet, View } from 'react-native' + +import AppText from '../common/app-text' + +import { Colors, Typography } from '../../styles' + +const AppPage = ({ + children, + contentContainerStyle, + scrollViewStyle, + title, + ...props +}) => { + return( + <View style={styles.container}> + <ScrollView + contentContainerStyle={[styles.scrollView, contentContainerStyle]} + style={scrollViewStyle} + {...props} + > + {title && <AppText style={styles.title}>{title}</AppText>} + {children} + </ScrollView> + </View> + ) +} + +AppPage.propTypes = { + children: PropTypes.node, + contentContainerStyle: PropTypes.object, + scrollViewStyle: PropTypes.object, + title: PropTypes.string +} + +const styles = StyleSheet.create({ + container: { + backgroundColor: Colors.turquoiseLight, + flex: 1 + }, + scrollView: { + backgroundColor: Colors.turquoiseLight, + flexGrow: 1 + }, + title: { + ...Typography.title + } +}) + +export default AppPage \ No newline at end of file diff --git a/components/common/app-switch.js b/components/common/app-switch.js new file mode 100644 index 0000000000000000000000000000000000000000..c0592532750fdfa7e708a028cd2be264991c39bb --- /dev/null +++ b/components/common/app-switch.js @@ -0,0 +1,38 @@ +import React from 'react' +import { StyleSheet, Switch, View } from 'react-native' +import PropTypes from 'prop-types' + +import AppText from './app-text' + +import { Containers } from '../../styles' + +const AppSwitch = ({ onToggle, text, value }) => { + return ( + <View style={styles.container}> + <View style={styles.textContainer}> + <AppText>{text}</AppText> + </View> + <Switch onValueChange={onToggle} style={styles.switch} value={value} /> + </View> + ) +} + +AppSwitch.propTypes = { + onToggle: PropTypes.func.isRequired, + text: PropTypes.string, + value: PropTypes.bool +} + +const styles = StyleSheet.create({ + container: { + ...Containers.rowContainer + }, + switch: { + flex: 1, + }, + textContainer: { + flex: 4, + } +}) + +export default AppSwitch \ No newline at end of file diff --git a/components/common/app-text-input.js b/components/common/app-text-input.js new file mode 100644 index 0000000000000000000000000000000000000000..3ec9369680c95804f6e37e0ac2ce8d4809608c91 --- /dev/null +++ b/components/common/app-text-input.js @@ -0,0 +1,37 @@ +import React from 'react' +import { KeyboardAvoidingView, StyleSheet, TextInput } from 'react-native' +import PropTypes from 'prop-types' + +import { Colors, Spacing, Typography } from '../../styles' + +const AppTextInput = ({ style, ...props }) => { + return ( + <KeyboardAvoidingView + behavior="padding" + keyboardVerticalOffset={300} + > + <TextInput style={[styles.input, style]} {...props} /> + </KeyboardAvoidingView> + ) +} + +AppTextInput.propTypes = { + style: PropTypes.object +} + +const styles = StyleSheet.create({ + input: { + backgroundColor: 'white', + borderColor: Colors.grey, + borderRadius: 5, + borderStyle: 'solid', + borderWidth: 1, + color: Colors.greyDark, + marginTop: Spacing.base, + minWidth: '80%', + paddingHorizontal: Spacing.base, + ...Typography.mainText + } +}) + +export default AppTextInput diff --git a/components/common/app-text.js b/components/common/app-text.js new file mode 100644 index 0000000000000000000000000000000000000000..5d696f3799f9df0477ca8f91ad267b38fd68d031 --- /dev/null +++ b/components/common/app-text.js @@ -0,0 +1,33 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { StyleSheet, Text } from 'react-native' + +import Link from './link' + +import { Colors, Typography } from '../../styles' + +const AppText = ({ children, linkStyle, style, ...props }) => { + // we parse for links in case the text contains any + return ( + <Link style={linkStyle}> + <Text style={[styles.text, style]} {...props}> + {children} + </Text> + </Link> + ) +} + +AppText.propTypes = { + children: PropTypes.node, + linkStyle: PropTypes.object, + style: PropTypes.oneOfType([PropTypes.array, PropTypes.object]), +} + +const styles = StyleSheet.create({ + text: { + color: Colors.greyDark, + ...Typography.mainText + } +}) + +export default AppText \ No newline at end of file diff --git a/components/common/button.js b/components/common/button.js new file mode 100644 index 0000000000000000000000000000000000000000..79e17d8bccbceebd0e7490222166bac1da078da2 --- /dev/null +++ b/components/common/button.js @@ -0,0 +1,87 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { StyleSheet, TouchableOpacity } from 'react-native' + +import AppIcon from './app-icon' +import AppText from './app-text' + +import { Colors, Fonts, Spacing } from '../../styles' + +const Button = ({ + children, + iconName, + isCTA, + isSmall, + onPress, + testID, + ...props +}) => { + const buttonStyle = isCTA ? styles.cta : styles.regular + const textCTA = isCTA ? styles.buttonTextBold : styles.buttonTextRegular + const textStyle = [textCTA, isSmall ? textSmall : text] + + return ( + <TouchableOpacity + onPress={onPress} + style={buttonStyle} + testID={testID} + {...props} + > + <AppText style={textStyle}>{children}</AppText> + {iconName && <AppIcon color={Colors.orange} name={iconName} />} + </TouchableOpacity> + ) +} + +Button.propTypes = { + children: PropTypes.node, + iconName: PropTypes.string, + isCTA: PropTypes.bool, + isSmall: PropTypes.bool, + onPress: PropTypes.func, + testID: PropTypes.string +} + +Button.defaultProps = { + isSmall: true +} + +const text = { + padding: Spacing.base, + textTransform: 'uppercase' +} + +const textSmall = { + fontSize: Fonts.small, + padding: Spacing.small, + textTransform: 'uppercase' +} + +const button = { + alignItems: 'center', + flexDirection: 'row', + justifyContent: 'center', + margin: Spacing.base, + minWidth: '15%' +} + +const styles = StyleSheet.create({ + regular: { + ...button + }, + cta: { + backgroundColor: Colors.orange, + borderRadius: 25, + ...button + }, + buttonTextBold: { + color: 'white', + fontFamily: Fonts.bold + }, + buttonTextRegular: { + color: Colors.greyDark, + fontFamily: Fonts.main + } +}) + +export default Button diff --git a/components/common/close-icon.js b/components/common/close-icon.js new file mode 100644 index 0000000000000000000000000000000000000000..862fc73bb4a58ec102a9a0208e2e0bcf478ab777 --- /dev/null +++ b/components/common/close-icon.js @@ -0,0 +1,32 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { StyleSheet, TouchableOpacity } from 'react-native' + +import AppIcon from './app-icon' + +import { Colors, Sizes } from '../../styles' + +const CloseIcon = ({ onClose, ...props }) => { + return ( + <TouchableOpacity + onPress={onClose} + style={styles.container} + {...props} + > + <AppIcon name='cross' color={Colors.orange} /> + </TouchableOpacity> + ) +} + +CloseIcon.propTypes = { + onClose: PropTypes.func.isRequired +} + +const styles = StyleSheet.create({ + container: { + alignSelf: 'flex-start', + marginBottom: Sizes.base + } +}) + +export default CloseIcon \ No newline at end of file diff --git a/components/common/link.js b/components/common/link.js new file mode 100644 index 0000000000000000000000000000000000000000..aec7bfcb1af712ea3a751839ae8d7f2e16689761 --- /dev/null +++ b/components/common/link.js @@ -0,0 +1,40 @@ +import React from 'react' +import PropTypes from 'prop-types' +import Hyperlink from 'react-native-hyperlink' +import { StyleSheet } from 'react-native' + +import { Colors, Typography } from '../../styles' + +import links from '../../i18n/en/links' + +const Link = ({ children, style }) => { + return ( + <Hyperlink + linkStyle={[styles.link, style]} + linkText={replaceUrlWithText} + linkDefault + > + {children} + </Hyperlink> + ) +} + +Link.propTypes = { + children: PropTypes.node, + style: PropTypes.object +} + +const styles = StyleSheet.create({ + link: { + color: Colors.purple, + textDecorationLine: 'underline', + ...Typography.mainText, + } +}) + +function replaceUrlWithText(url) { + const link = Object.values(links).find(l => l.url === url) + return (link && link.text) || url +} + +export default Link \ No newline at end of file diff --git a/components/common/menu-icon.js b/components/common/menu-icon.js new file mode 100644 index 0000000000000000000000000000000000000000..8ef9b9a0a982f87240b3243084715a3959b763b7 --- /dev/null +++ b/components/common/menu-icon.js @@ -0,0 +1,21 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { createIconSetFromIcoMoon } from 'react-native-vector-icons' +import iconConfig from '../../selection.json' + +import { Colors, Sizes } from '../../styles' + +const Icon = createIconSetFromIcoMoon(iconConfig, '', 'Menu') + +const MenuIcon = ({ isActive, name }) => { + const color = isActive ? Colors.greyDark : Colors.grey + + return <Icon name={name} size={Sizes.icon} color={color} /> +} + +MenuIcon.propTypes = { + isActive: PropTypes.bool, + name: PropTypes.string.isRequired +} + +export default MenuIcon \ No newline at end of file diff --git a/components/common/segment.js b/components/common/segment.js new file mode 100644 index 0000000000000000000000000000000000000000..af96dcf7930704f6f0f2a3ac3482aff976a9e1bd --- /dev/null +++ b/components/common/segment.js @@ -0,0 +1,49 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { StyleSheet, View } from 'react-native' + +import AppText from './app-text' + +import { Colors, Spacing, Typography } from '../../styles' + +const Segment = ({ children, last, title }) => { + const containerStyle = last ? styles.containerLast : styles.container + const commonStyle = Object.assign({}, containerStyle) + + return ( + <View style={commonStyle}> + {title && <AppText style={styles.title}>{title}</AppText>} + {children} + </View> + ) +} + +Segment.propTypes = { + children: PropTypes.node, + last: PropTypes.bool, + style: PropTypes.object, + title: PropTypes.string, +} + +const segmentContainer = { + marginHorizontal: Spacing.base, + marginBottom: Spacing.base, +} + +const styles = StyleSheet.create({ + container: { + borderStyle: 'solid', + borderBottomWidth: 1, + borderBottomColor: Colors.greyLight, + paddingBottom: Spacing.base, + ...segmentContainer, + }, + containerLast: { + ...segmentContainer, + }, + title: { + ...Typography.subtitle, + } +}) + +export default Segment \ No newline at end of file diff --git a/components/common/table.js b/components/common/table.js new file mode 100644 index 0000000000000000000000000000000000000000..bb84f2715ce705e34e583b89f8caff9ab669d329 --- /dev/null +++ b/components/common/table.js @@ -0,0 +1,80 @@ +import React from 'react' +import { StyleSheet, View } from 'react-native' +import PropTypes from 'prop-types' + +import AppText from './app-text' + +import { Sizes, Spacing, Typography } from '../../styles' + +const Table = ({ tableContent }) => { + return ( + tableContent.map((rowContent, i) => <Row key={i} rowContent={rowContent} />) + ) +} + +Table.propTypes = { + tableContent: PropTypes.array.isRequired +} + +const Row = ({ rowContent }) => { + return( + <View style={styles.row}> + <Cell content={rowContent[0]} isLeft /> + <Cell content={rowContent[1]} /> + </View> + ) +} + +Row.propTypes = { + rowContent: PropTypes.array.isRequired +} + +const Cell = ({ content, isLeft }) => { + const styleContainer = isLeft ? styles.cellLeft : styles.cellRight + const styleText = isLeft ? styles.accentPurpleBig : styles.accentOrange + const numberOfLines = isLeft ? 1 : 2 + const ellipsizeMode = isLeft ? 'clip' : 'tail' + + return( + <View style={styleContainer}> + <AppText + numberOfLines={numberOfLines} + ellipsizeMode={ellipsizeMode} + style={styleText} + > + {content} + </AppText> + </View> + ) +} + +Cell.propTypes = { + content: PropTypes.node.isRequired, + isLeft: PropTypes.bool, +} + +const styles = StyleSheet.create({ + accentOrange: { + ...Typography.accentOrange, + fontSize: Sizes.small, + }, + accentPurpleBig: { + ...Typography.accentPurpleBig, + marginRight: Spacing.small, + }, + cellLeft: { + alignItems: 'flex-end', + flex: 5, + justifyContent: 'center', + }, + cellRight: { + flex: 6, + justifyContent: 'center', + }, + row: { + flexDirection: 'row', + marginBottom: Spacing.tiny, + } +}) + +export default Table \ No newline at end of file diff --git a/components/cycle-day/FillerBoxes.js b/components/cycle-day/FillerBoxes.js deleted file mode 100644 index f0e0c024ac1c125de35efcbbca942f141761e5e1..0000000000000000000000000000000000000000 --- a/components/cycle-day/FillerBoxes.js +++ /dev/null @@ -1,20 +0,0 @@ -import React, { Component } from 'react' -import { View, Dimensions } from 'react-native' -import styles from '../../styles' - -export default class FillerBoxes extends Component { - render() { - const n = Dimensions.get('window').width / styles.symptomBox.width - const fillerBoxes = [] - for (let i = 0; i < Math.ceil(n); i++) { - fillerBoxes.push( - <View - width={styles.symptomBox.width} - height={0} - key={i.toString()} - /> - ) - } - return fillerBoxes - } -} \ No newline at end of file diff --git a/components/cycle-day/SymptomBox.js b/components/cycle-day/SymptomBox.js deleted file mode 100644 index 62f5df0a96a3bd49db859a19c09236f2cb01322f..0000000000000000000000000000000000000000 --- a/components/cycle-day/SymptomBox.js +++ /dev/null @@ -1,174 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { View, TouchableOpacity } from 'react-native' - -import AppText from '../app-text' -import DripIcon from '../../assets/drip-icons' - -import styles from '../../styles' - -import { headerTitles as symptomTitles } from '../../i18n/en/labels' -import * as labels from '../../i18n/en/cycle-day' -const bleedingLabels = labels.bleeding.labels -const intensityLabels = labels.intensity -const sexLabels = labels.sex.categories -const contraceptiveLabels = labels.contraceptives.categories -const painLabels = labels.pain.categories -const moodLabels = labels.mood.categories - -function isNumber(val) { - return typeof val === 'number' -} - -const l = { - bleeding: ({ value, exclude }) => { - if (isNumber(value)) { - const bleedingLabel = bleedingLabels[value] - return exclude ? `(${bleedingLabel})` : bleedingLabel - } - }, - temperature: ({ value, time, exclude }) => { - if (isNumber(value)) { - let temperatureLabel = `${value} °C` - if (time) { - temperatureLabel += ` - ${time}` - } - if (exclude) { - temperatureLabel = `(${temperatureLabel})` - } - return temperatureLabel - } - }, - mucus: mucus => { - const filledCategories = ['feeling', 'texture'].filter(c => isNumber(mucus[c])) - let label = filledCategories.map(category => { - return labels.mucus.subcategories[category] + ': ' + labels.mucus[category].categories[mucus[category]] - }).join(', ') - - if (isNumber(mucus.value)) label += `\n => ${labels.mucusNFP[mucus.value]}` - if (mucus.exclude) label = `(${label})` - - return label - }, - cervix: cervix => { - const filledCategories = ['opening', 'firmness', 'position'].filter(c => isNumber(cervix[c])) - let label = filledCategories.map(category => { - return labels.cervix.subcategories[category] + ': ' + labels.cervix[category].categories[cervix[category]] - }).join(', ') - - if (cervix.exclude) label = `(${label})` - - return label - }, - note: note => note.value, - desire: ({ value }) => { - if (isNumber(value)) { - return intensityLabels[value] - } - }, - sex: sex => { - const sexLabel = [] - if (sex && Object.values({...sex}).some(val => val)){ - Object.keys(sex).forEach(key => { - if(sex[key] && key !== 'other' && key !== 'note') { - sexLabel.push( - sexLabels[key] || - contraceptiveLabels[key] - ) - } - if(key === 'other' && sex.other) { - let label = contraceptiveLabels[key] - if(sex.note) { - label = `${label} (${sex.note})` - } - sexLabel.push(label) - } - }) - return sexLabel.join(', ') - } - }, - pain: pain => { - const painLabel = [] - if (pain && Object.values({...pain}).some(val => val)){ - Object.keys(pain).forEach(key => { - if(pain[key] && key !== 'other' && key !== 'note') { - painLabel.push(painLabels[key]) - } - if(key === 'other' && pain.other) { - let label = painLabels[key] - if(pain.note) { - label = `${label} (${pain.note})` - } - painLabel.push(label) - } - }) - return painLabel.join(', ') - } - }, - mood: mood => { - const moodLabel = [] - if (mood && Object.values({...mood}).some(val => val)){ - Object.keys(mood).forEach(key => { - if(mood[key] && key !== 'other' && key !== 'note') { - moodLabel.push(moodLabels[key]) - } - if(key === 'other' && mood.other) { - let label = moodLabels[key] - if(mood.note) { - label = `${label} (${mood.note})` - } - moodLabel.push(label) - } - }) - return moodLabel.join(', ') - } - } -} - -const getLabel = (symptom, symptomData) => { - return symptomData && l[symptom](symptomData) -} - -export default function SymptomBox( - { disabled, onPress, symptom, symptomData }) { - - const data = getLabel(symptom, symptomData) - const iconName = `drip-icon-${symptom}` - - const disabledStyle = disabled ? styles.symptomInFuture : null - const containerStyle = [ - styles.symptomBox, - data && styles.symptomBoxActive, - disabledStyle - ] - const titleStyle = [ - data && styles.symptomTextActive, - disabledStyle, - {fontSize: 15} - ] - const dataBoxStyle = [styles.symptomDataBox, disabledStyle] - const iconColor = data ? 'white' : 'black' - - return ( - <TouchableOpacity onPress={onPress} disabled={disabled} testID={iconName}> - <View style={containerStyle}> - <DripIcon name={iconName} size={50} color={iconColor} /> - <AppText style={titleStyle} numberOfLines={1}> - {symptomTitles[symptom].toLowerCase()} - </AppText> - </View> - <View style={dataBoxStyle}> - <AppText style={styles.symptomDataText} numberOfLines={3}> - {data} - </AppText> - </View> - </TouchableOpacity> - ) -} - -SymptomBox.propTypes = { - disabled: PropTypes.bool.isRequired, - onPress: PropTypes.func.isRequired, - symptom: PropTypes.string.isRequired, - symptomData: PropTypes.object -} \ No newline at end of file diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js index ceab0f59690d21a5d2bb2f1f63a4a51e89917adf..3fcfe64c39c492c45d27477d6ecd6d97f5f54531 100644 --- a/components/cycle-day/cycle-day-overview.js +++ b/components/cycle-day/cycle-day-overview.js @@ -1,118 +1,98 @@ import React, { Component } from 'react' -import { ScrollView, View } from 'react-native' +import { StyleSheet, View } from 'react-native' import PropTypes from 'prop-types' +import { LocalDate } from 'js-joda' + +import AppPage from '../common/app-page' +import SymptomBox from './symptom-box' +import SymptomPageTitle from './symptom-page-title' import { connect } from 'react-redux' import { getDate, setDate } from '../../slices/date' import { navigate } from '../../slices/navigation' -import { LocalDate } from 'js-joda' -import Header from '../header' -import FillerBoxes from './FillerBoxes' -import SymptomBox from './SymptomBox' - import cycleModule from '../../lib/cycle' -import formatDate from '../helpers/format-date' +import { dateToTitle } from '../helpers/format-date' import { getCycleDay } from '../../db' -import styles from '../../styles' +import { getData } from '../helpers/cycle-day' + +import { general as labels} from '../../i18n/en/cycle-day' +import { Spacing } from '../../styles' +import { SYMPTOMS } from '../../config' class CycleDayOverView extends Component { static propTypes = { navigate: PropTypes.func, setDate: PropTypes.func, - // The following are not being used, - // we could see if it's possible to not pass them from the <App /> cycleDay: PropTypes.object, date: PropTypes.string, + isTemperatureEditView: PropTypes.bool, } constructor(props) { super(props) - this.state = { - cycleDay: getCycleDay(props.date) + + this.state = { cycleDay: getCycleDay(props.date), data: null } + if (props.isTemperatureEditView) { + const todayDateString = LocalDate.now().toString() + props.setDate(todayDateString) } } updateCycleDay = (date) => { this.props.setDate(date) - this.setState({ - cycleDay: getCycleDay(date) - }) - } - - goToPrevDay = () => { - const { date } = this.props - const prevDate = LocalDate.parse(date).minusDays(1).toString() - this.updateCycleDay(prevDate) - } - - goToNextDay = () => { - const { date } = this.props - const nextDate = LocalDate.parse(date).plusDays(1).toString() - this.updateCycleDay(nextDate) + this.setState({ cycleDay: getCycleDay(date) }) } render() { const { cycleDay } = this.state - const { date } = this.props - - const dateInFuture = LocalDate.now().isBefore(LocalDate.parse(date)) - - const symptomBoxesList = [ - 'bleeding', - 'temperature', - 'mucus', - 'cervix', - 'desire', - 'sex', - 'pain', - 'mood', - 'note', - ] + const { date, isTemperatureEditView } = this.props const { getCycleDayNumber } = cycleModule() const cycleDayNumber = getCycleDayNumber(date) - const headerSubtitle = cycleDayNumber && `Cycle day ${cycleDayNumber}` + const subtitle = cycleDayNumber && `${labels.cycleDayNumber}${cycleDayNumber}` return ( - <View style={{ flex: 1 }}> - <Header - handleBack={this.goToPrevDay} - handleNext={this.goToNextDay} - title={formatDate(date)} - subtitle={headerSubtitle} + <AppPage> + <SymptomPageTitle + reloadSymptomData={this.updateCycleDay} + subtitle={subtitle} + title={dateToTitle(date)} /> - <ScrollView> - <View style={styles.symptomBoxesView}> - { - symptomBoxesList.map(symptom => { - const symptomEditView = - `${symptom[0].toUpperCase() + symptom.substring(1)}EditView` - const symptomData = - cycleDay && cycleDay[symptom] ? cycleDay[symptom] : null - return( - <SymptomBox - key={symptom} - symptom={symptom} - symptomData={symptomData} - onPress={() => this.props.navigate(symptomEditView)} - disabled={dateInFuture && symptom !== 'note'} - />) - }) - } - { - // this is just to make the last row adhere to the grid - // (and) because there are no pseudo properties in RN - } - <FillerBoxes /> - </View> - </ScrollView> - </View> + <View style={styles.container}> + {SYMPTOMS.map(symptom => { + const symptomData = cycleDay && cycleDay[symptom] + ? cycleDay[symptom] : null + + const isSymptomEdited = isTemperatureEditView && symptom === 'temperature' + + return( + <SymptomBox + key={symptom} + symptom={symptom} + symptomData={symptomData} + symptomDataToDisplay={getData(symptom, symptomData)} + updateCycleDayData={this.updateCycleDay} + isSymptomEdited={isSymptomEdited} + /> + ) + })} + </View> + </AppPage> ) } } +const styles = StyleSheet.create({ + container: { + flexDirection: 'row', + flexWrap: 'wrap', + justifyContent: 'space-between', + padding: Spacing.base + } +}) + const mapStateToProps = (state) => { return({ date: getDate(state), diff --git a/components/cycle-day/select-box-group.js b/components/cycle-day/select-box-group.js index ee64d00e7547db46b4491afa79cc3a16ed82c1e4..773ef5e6c5a43d5bfec3633e118265ff7ad8ad87 100644 --- a/components/cycle-day/select-box-group.js +++ b/components/cycle-day/select-box-group.js @@ -1,29 +1,26 @@ import React from 'react' import PropTypes from 'prop-types' -import { View, TouchableOpacity } from 'react-native' +import { StyleSheet, TouchableOpacity, View } from 'react-native' -import AppText from '../app-text' +import AppText from '../common/app-text' -import styles from '../../styles' +import { Colors, Containers } from '../../styles' -export default function SelectBoxGroup({ labels, onSelect, optionsState }) { +const SelectBoxGroup = ({ labels, optionsState, onSelect }) => { return ( - <View style={styles.selectBoxSection}> + <View style={styles.container}> {Object.keys(labels).map(key => { - const style = [styles.selectBox] - const textStyle = [] - if (optionsState[key]) { - style.push(styles.selectBoxActive) - textStyle.push(styles.selectBoxTextActive) - } + const isActive = optionsState[key] + const boxStyle = [styles.box, isActive && styles.boxActive] + const textStyle = [styles.text, isActive && styles.textActive] + return ( <TouchableOpacity - onPress={() => onSelect(key)} key={key} + onPress={() => onSelect(key)} + style={boxStyle} > - <View style={style}> - <AppText style={textStyle}>{labels[key]}</AppText> - </View> + <AppText style={textStyle}>{labels[key]}</AppText> </TouchableOpacity> ) })} @@ -36,3 +33,23 @@ SelectBoxGroup.propTypes = { onSelect: PropTypes.func.isRequired, optionsState: PropTypes.object.isRequired } + +const styles = StyleSheet.create({ + box: { + ...Containers.box + }, + boxActive: { + ...Containers.boxActive + }, + container: { + ...Containers.selectGroupContainer + }, + text: { + color: Colors.orange + }, + textActive: { + color: 'white' + } +}) + +export default SelectBoxGroup diff --git a/components/cycle-day/select-tab-group.js b/components/cycle-day/select-tab-group.js index a8fffc64202e633458440825d7647c96f2138045..29c2e2f56b0c4711f7b12ebcfc8d07a7af55e605 100644 --- a/components/cycle-day/select-tab-group.js +++ b/components/cycle-day/select-tab-group.js @@ -1,40 +1,27 @@ import React from 'react' import PropTypes from 'prop-types' -import { View, TouchableOpacity } from 'react-native' +import { StyleSheet, TouchableOpacity, View } from 'react-native' -import AppText from '../app-text' +import AppText from '../common/app-text' -import styles from '../../styles' +import { Colors, Containers } from '../../styles' -export default function SelectTabGroup({ active, buttons, onSelect }) { +export default function SelectTabGroup({ activeButton, buttons, onSelect }) { return ( - <View style={styles.selectTabGroup}> + <View style={styles.container}> { buttons.map(({ label, value }, i) => { - let firstOrLastStyle - if (i === buttons.length - 1) { - firstOrLastStyle = styles.selectTabLast - } else if (i === 0) { - firstOrLastStyle = styles.selectTabFirst - } - let activeStyle - const isActive = value === active - if (isActive) activeStyle = styles.selectTabActive + const isActive = value === activeButton + const boxStyle = [styles.box, isActive && styles.boxActive] + const textStyle = [styles.text, isActive && styles.textActive] + return ( <TouchableOpacity - onPress={() => onSelect(isActive ? null : value)} + onPress={() => onSelect(value)} key={i} - activeOpacity={1} + style={boxStyle} > - <View> - <View style={[ - styles.selectTab, - firstOrLastStyle, - activeStyle - ]}> - <AppText style={activeStyle}>{label}</AppText> - </View> - </View> + <AppText style={textStyle}>{label}</AppText> </TouchableOpacity> ) }) @@ -44,7 +31,25 @@ export default function SelectTabGroup({ active, buttons, onSelect }) { } SelectTabGroup.propTypes = { - active: PropTypes.number, + activeButton: PropTypes.number, buttons: PropTypes.array.isRequired, onSelect: PropTypes.func.isRequired -} \ No newline at end of file +} + +const styles = StyleSheet.create({ + box: { + ...Containers.box + }, + boxActive: { + ...Containers.boxActive + }, + container: { + ...Containers.selectGroupContainer + }, + text: { + color: Colors.orange + }, + textActive: { + color: 'white' + } +}) \ No newline at end of file diff --git a/components/cycle-day/symptom-box.js b/components/cycle-day/symptom-box.js new file mode 100644 index 0000000000000000000000000000000000000000..af9e51439a83ffc95815ae3f32800e9a0a71b018 --- /dev/null +++ b/components/cycle-day/symptom-box.js @@ -0,0 +1,168 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { StyleSheet, View, TouchableOpacity } from 'react-native' + +import AppText from '../common/app-text' +import DripIcon from '../../assets/drip-icons' +import SymptomEditView from './symptom-edit-view' + +import { connect } from 'react-redux' +import { getDate } from '../../slices/date' +import { isDateInFuture } from '../helpers/cycle-day' + +import { Colors, Sizes, Spacing } from '../../styles' +import { headerTitles as symptomTitles } from '../../i18n/en/labels' + +class SymptomBox extends Component { + + static propTypes = { + date: PropTypes.string.isRequired, + isSymptomEdited: PropTypes.bool, + symptom: PropTypes.string.isRequired, + symptomData: PropTypes.object, + symptomDataToDisplay: PropTypes.string, + updateCycleDayData: PropTypes.func.isRequired, + } + + static defaultProps = { + isSymptomEdited: false, + } + + constructor(props) { + super(props) + + this.state = { + isSymptomEdited: props.isSymptomEdited + } + } + + onFinishEditing = () => { + const { date, updateCycleDayData } = this.props + + updateCycleDayData(date) + this.setState({ isSymptomEdited: false }) + } + + onEditSymptom = () => { + this.setState({ isSymptomEdited: true }) + } + + render() { + const { date, symptom, symptomData, symptomDataToDisplay } = this.props + const { isSymptomEdited } = this.state + const isSymptomDisabled = isDateInFuture(date) && symptom !== 'note' + const isExcluded = symptomData !== null ? symptomData.exclude : false + + const iconColor = isSymptomDisabled ? Colors.greyLight : Colors.grey + const iconName = `drip-icon-${symptom}` + const symptomNameStyle = [ + styles.symptomName, + (isSymptomDisabled && styles.symptomNameDisabled), + (isExcluded && styles.symptomNameExcluded) + ] + const textStyle = [ + styles.text, + (isSymptomDisabled && styles.textDisabled), + (isExcluded && styles.textExcluded) + ] + + return ( + <React.Fragment> + {isSymptomEdited && + <SymptomEditView + symptom={symptom} + symptomData={symptomData} + onClose={this.onFinishEditing} + /> + } + + <TouchableOpacity + disabled={isSymptomDisabled} + onPress={this.onEditSymptom} + style={styles.container} + testID={iconName} + > + <DripIcon + color={iconColor} + isActive={!isSymptomDisabled} + name={iconName} + size={40} + /> + <View style={styles.textContainer}> + <AppText style={symptomNameStyle}> + {symptomTitles[symptom].toLowerCase()} + </AppText> + {symptomDataToDisplay && + <AppText style={textStyle} numberOfLines={4}> + {symptomDataToDisplay} + </AppText> + } + </View> + </TouchableOpacity> + </React.Fragment> + ) + } +} + +const hint = { + fontSize: Sizes.small, + fontStyle: 'italic' +} + +const main = { + fontSize: Sizes.base, + height: Sizes.base * 2, + lineHeight: Sizes.base, + marginBottom: (-1) * Sizes.tiny, + textAlignVertical: 'center' +} + +const styles = StyleSheet.create({ + container: { + alignItems: 'center', + backgroundColor: 'white', + borderRadius: 10, + elevation: 4, + flexDirection: 'row', + height: 110, + marginBottom: Spacing.base, + paddingHorizontal: Spacing.small, + paddingVertical: Spacing.base, + width: Spacing.symptomTileWidth + }, + symptomName: { + color: Colors.purple, + ...main + }, + symptomNameDisabled: { + color: Colors.grey + }, + symptomNameExcluded: { + color: Colors.greyDark, + }, + textContainer: { + flexDirection: 'column', + marginLeft: Spacing.small, + maxWidth: Spacing.textWidth + }, + text: { + ...hint + }, + textDisabled: { + color: Colors.greyLight + }, + textExcluded: { + color: Colors.grey, + } +}) + +const mapStateToProps = (state) => { + return({ + date: getDate(state), + }) +} + +export default connect( + mapStateToProps, + null, +)(SymptomBox) diff --git a/components/cycle-day/symptom-edit-view.js b/components/cycle-day/symptom-edit-view.js new file mode 100644 index 0000000000000000000000000000000000000000..b6e4195d312b2482934852bce8cf174b8a844ab5 --- /dev/null +++ b/components/cycle-day/symptom-edit-view.js @@ -0,0 +1,287 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { Dimensions, ScrollView, StyleSheet, View } from 'react-native' + +import AppModal from '../common/app-modal' +import AppSwitch from '../common/app-switch' +import AppText from '../common/app-text' +import AppTextInput from '../common/app-text-input' +import Button from '../common/button' +import CloseIcon from '../common/close-icon' +import Segment from '../common/segment' +import SelectBoxGroup from './select-box-group' +import SelectTabGroup from './select-tab-group' +import Temperature from './temperature' + +import { connect } from 'react-redux' +import { getDate } from '../../slices/date' +import { blank, save, shouldShow, symtomPage } from '../helpers/cycle-day' + +import { shared as sharedLabels } from '../../i18n/en/labels' +import info from '../../i18n/en/symptom-info' +import { Colors, Containers, Sizes, Spacing } from '../../styles' + +class SymptomEditView extends Component { + + static propTypes = { + date: PropTypes.string.isRequired, + onClose: PropTypes.func.isRequired, + symptom: PropTypes.string.isRequired, + symptomData: PropTypes.object + } + + constructor(props) { + super(props) + + const { symptomData, symptom } = this.props + const data = symptomData ? symptomData : blank[symptom] + + const symptomConfig = symtomPage[symptom] + const shouldShowExclude = shouldShow(symptomConfig.excludeText) + const shouldShowNote = shouldShow(symptomConfig.note) + const shouldBoxGroup = shouldShow(symptomConfig.selectBoxGroups) + const shouldTabGroup = shouldShow(symptomConfig.selectTabGroups) + + this.state = { + data, + shouldShowExclude, + shouldShowInfo: false, + shouldShowNote, + shouldBoxGroup, + shouldTabGroup + } + } + + componentDidUpdate() { + this.saveData() + } + + getParsedData = () => JSON.parse(JSON.stringify(this.state.data)) + + onEditNote = (note) => { + const data = this.getParsedData() + const { symptom } = this.props + + if (symptom === 'note') { + Object.assign(data, { value: note }) + } else { + data['note'] = note + } + + this.setState({ data }) + } + + onExcludeToggle = () => { + const data = this.getParsedData() + Object.assign(data, { exclude: !data.exclude }) + + this.setState({ data }) + } + + onPressLearnMore = () => { + this.setState({ shouldShowInfo: !this.state.shouldShowInfo }) + } + + onRemove = () => { + this.saveData(true) + this.props.onClose() + } + + onSave = () => { + this.saveData() + this.props.onClose() + } + + onSaveTemperature = (value, field) => { + const data = this.getParsedData() + const dataToSave = field === 'value' + ? { [field]: Number(value) } : { [field]: value } + Object.assign(data, { ...dataToSave }) + + this.setState({ data }) + } + + onSelectBox = (key) => { + const data = this.getParsedData() + if (key === "other") { + Object.assign(data, { + note: null, + [key]: !this.state.data[key] + }) + } else { + Object.assign(data, { [key]: !this.state.data[key] }) + } + + this.setState({ data }) + } + + onSelectBoxNote= (value) => { + const data = this.getParsedData() + Object.assign(data, { note: value !== '' ? value : null }) + + this.setState({ data }) + } + + onSelectTab = (group, value) => { + const data = this.getParsedData() + Object.assign(data, { [group.key]: value }) + + this.setState({ data }) + } + + saveData = (shouldDeleteData) => { + const { date, symptom } = this.props + const { data } = this.state + save[symptom](data, date, shouldDeleteData) + } + + render() { + const { onClose, symptom } = this.props + const { data, + shouldShowExclude, + shouldShowInfo, + shouldShowNote, + shouldBoxGroup, + shouldTabGroup + } = this.state + const iconName = shouldShowInfo ? "chevron-down" : "chevron-up" + const noteText = symptom === 'note' ? data.value : data.note + + return ( + <AppModal onClose={onClose}> + <ScrollView + contentContainerStyle={styles.modalContainer} + style={styles.modalWindow} + > + <View style={styles.headerContainer}> + <CloseIcon onClose={onClose} /> + </View> + {symptom === 'temperature' && + <Temperature + data={data} + save={(value, field) => this.onSaveTemperature(value, field)} + /> + } + {shouldTabGroup && symtomPage[symptom].selectTabGroups.map(group => { + return ( + <Segment key={group.key} style={styles.segmentBorder}> + <AppText style={styles.title}>{group.title}</AppText> + <SelectTabGroup + activeButton={data[group.key]} + buttons={group.options} + onSelect={value => this.onSelectTab(group, value)} + /> + </Segment> + ) + }) + } + {shouldBoxGroup && symtomPage[symptom].selectBoxGroups.map(group => { + const isOtherSelected = + data['other'] !== null + && data['other'] !== false + && Object.keys(group.options).includes('other') + + return ( + <Segment key={group.key} style={styles.segmentBorder} > + <AppText style={styles.title}>{group.title}</AppText> + <SelectBoxGroup + labels={group.options} + onSelect={value => this.onSelectBox(value)} + optionsState={data} + /> + {isOtherSelected && + <AppTextInput + multiline={true} + placeholder={sharedLabels.enter} + value={data.note} + onChangeText={value => this.onSelectBoxNote(value)} + /> + } + </Segment> + ) + }) + } + {shouldShowExclude && + <Segment style={styles.segmentBorder} > + <AppSwitch + onToggle={this.onExcludeToggle} + text={symtomPage[symptom].excludeText} + value={data.exclude} + /> + </Segment> + } + {shouldShowNote && + <Segment style={styles.segmentBorder} > + <AppText>{symtomPage[symptom].note}</AppText> + <AppTextInput + multiline={true} + numberOfLines={3} + onChangeText={this.onEditNote} + placeholder={sharedLabels.enter} + testID='noteInput' + value={noteText !== null ? noteText : ''} + /> + </Segment> + } + <View style={styles.buttonsContainer}> + <Button iconName={iconName} isSmall onPress={this.onPressLearnMore}> + {sharedLabels.learnMore} + </Button> + <Button isSmall onPress={this.onRemove}> + {sharedLabels.remove} + </Button> + <Button isCTA isSmall onPress={this.onSave}> + {sharedLabels.save} + </Button> + </View> + {shouldShowInfo && + <Segment last style={styles.segmentBorder} > + <AppText>{info[symptom].text}</AppText> + </Segment> + } + </ScrollView> + </AppModal> + ) + } +} + +const styles = StyleSheet.create({ + buttonsContainer: { + ...Containers.rowContainer + }, + headerContainer: { + flexDirection: 'row', + justifyContent: 'flex-end', + paddingVertical: Spacing.tiny, + }, + modalContainer: { + flex: 1, + padding: Spacing.small, + paddingBottom: Spacing.base + }, + modalWindow: { + backgroundColor: 'white', + borderRadius: 10, + marginVertical: Sizes.huge * 2, + position: 'absolute', + minHeight: '40%', + maxHeight: Dimensions.get('window').height * 0.7 + }, + segmentBorder: { + borderBottomColor: Colors.greyLight + }, + title: { + fontSize: Sizes.subtitle + } +}) + +const mapStateToProps = (state) => { + return({ + date: getDate(state), + }) +} + +export default connect( + mapStateToProps, + null, +)(SymptomEditView) \ No newline at end of file diff --git a/components/cycle-day/symptom-page-title.js b/components/cycle-day/symptom-page-title.js new file mode 100644 index 0000000000000000000000000000000000000000..6203c1c40e3fb09fe6cafaff01b8055719aa06c8 --- /dev/null +++ b/components/cycle-day/symptom-page-title.js @@ -0,0 +1,79 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { StyleSheet, TouchableOpacity, View } from 'react-native' + +import AppIcon from '../common/app-icon' +import AppText from '../common/app-text' + +import { connect } from 'react-redux' +import { getDate, setDate } from '../../slices/date' + +import { nextDate, prevDate } from '../helpers/cycle-day' +import { Colors, Containers, Spacing, Typography } from '../../styles' +import { HIT_SLOP } from '../../config' + +const SymptomPageTitle = ({ + date, + reloadSymptomData, + setDate, + subtitle, + title, +}) => { + const navigate = (isForward) => { + const nextDay = isForward ? nextDate(date) : prevDate(date) + reloadSymptomData(nextDay) + setDate(nextDay) + } + + return ( + <View style={styles.container}> + <TouchableOpacity onPress={() => navigate(false)} hitSlop={HIT_SLOP}> + <AppIcon name='chevron-left' color={Colors.orange}/> + </TouchableOpacity> + <View style={styles.textContainer}> + <AppText style={styles.title}>{title}</AppText> + {subtitle && <AppText style={styles.subtitle}>{subtitle}</AppText>} + </View> + <TouchableOpacity onPress={() => navigate(true)} hitSlop={HIT_SLOP}> + <AppIcon name='chevron-right' color={Colors.orange}/> + </TouchableOpacity> + </View> + ) +} + +SymptomPageTitle.propTypes = { + date: PropTypes.string.isRequired, + reloadSymptomData: PropTypes.func.isRequired, + setDate: PropTypes.func.isRequired, + subtitle: PropTypes.string, + title: PropTypes.string, +} + +const styles = StyleSheet.create({ + container: { + height: Spacing.base * 4, + marginHorizontal: Spacing.base, + marginTop: Spacing.base, + ...Containers.rowContainer, + }, + textContainer: { + alignItems: 'center', + }, + title: { + ...Typography.titleWithoutMargin, + }, +}) + +const mapStateToProps = (state) => { + return { + date: getDate(state), + } +} + +const mapDispatchToProps = (dispatch) => { + return { + setDate: (date) => dispatch(setDate(date)), + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(SymptomPageTitle) diff --git a/components/cycle-day/symptoms/bleeding.js b/components/cycle-day/symptoms/bleeding.js deleted file mode 100644 index f0579c17ab7db31dd9c7e9b4986a5435307c3c31..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/bleeding.js +++ /dev/null @@ -1,85 +0,0 @@ -import React, { Component } from 'react' -import { Switch } from 'react-native' -import PropTypes from 'prop-types' - -import { bleeding } from '../../../i18n/en/cycle-day' -import SelectTabGroup from '../select-tab-group' -import SymptomSection from './symptom-section' -import SymptomView from './symptom-view' - -import { getLabelsList } from '../../helpers/labels' -import { saveSymptom } from '../../../db' - -class Bleeding extends Component { - - static propTypes = { - cycleDay: PropTypes.object, - date: PropTypes.string.isRequired, - } - - constructor(props) { - super(props) - const symptom = 'bleeding' - const { cycleDay } = props - - const defaultSymptomData = { - value: null, - exclude: false - } - - const symptomData = - cycleDay && cycleDay[symptom] ? cycleDay[symptom] : defaultSymptomData - - this.state = { ...symptomData } - - this.bleedingRadioProps = getLabelsList(bleeding.labels) - - this.symptom = symptom - } - - autoSave = () => { - const { date } = this.props - const valuesToSave = { ...this.state } - const hasValueToSave = typeof this.state.value === 'number' - saveSymptom(this.symptom, date, hasValueToSave ? valuesToSave : null) - } - - componentDidUpdate() { - this.autoSave() - } - - render() { - return ( - <SymptomView - symptom={this.symptom} - values={this.state} - date={this.props.date} - > - <SymptomSection - header={bleeding.heaviness.header} - explainer={bleeding.heaviness.explainer} - > - <SelectTabGroup - buttons={this.bleedingRadioProps} - active={this.state.value} - onSelect={val => this.setState({ value: val })} - /> - </SymptomSection> - <SymptomSection - header={bleeding.exclude.header} - explainer={bleeding.exclude.explainer} - inline={true} - > - <Switch - onValueChange={(val) => { - this.setState({ exclude: val }) - }} - value={this.state.exclude} - /> - </SymptomSection> - </SymptomView> - ) - } -} - -export default Bleeding diff --git a/components/cycle-day/symptoms/cervix.js b/components/cycle-day/symptoms/cervix.js deleted file mode 100644 index 9966d71f25bf1bba868389728efe57fb1750503a..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/cervix.js +++ /dev/null @@ -1,113 +0,0 @@ -import React, { Component } from 'react' -import { Switch } from 'react-native' -import PropTypes from 'prop-types' - -import { cervix as labels } from '../../../i18n/en/cycle-day' -import SelectTabGroup from '../select-tab-group' -import SymptomSection from './symptom-section' -import SymptomView from './symptom-view' - -import { getLabelsList } from '../../helpers/labels' -import { saveSymptom } from '../../../db' - -class Cervix extends Component { - - static propTypes = { - cycleDay: PropTypes.object, - date: PropTypes.string.isRequired, - } - - constructor(props) { - super(props) - const symptom = 'cervix' - const { cycleDay } = props - - const defaultSymptomData = {} - - const symptomData = - cycleDay && cycleDay[symptom] ? cycleDay[symptom] : defaultSymptomData - - this.state = { ...symptomData } - - this.cervixOpeningRadioProps = getLabelsList(labels.opening.categories) - this.cervixFirmnessRadioProps = getLabelsList(labels.firmness.categories) - this.cervixPositionRadioProps = getLabelsList(labels.position.categories) - - this.symptom = symptom - } - - autoSave = () => { - const { date } = this.props - const { opening, firmness, position, exclude } = this.state - const valuesToSave = { - opening, - firmness, - position, - exclude: Boolean(exclude) - } - const nothingEntered = ['opening', 'firmness', 'position'].every( - val => typeof this.state[val] !== 'number') - saveSymptom(this.symptom, date, nothingEntered ? null : valuesToSave) - } - - componentDidUpdate() { - this.autoSave() - } - - render() { - // TODO saving this info for notice when leaving incomplete data - // const mandatoryNotCompleted = typeof this.state.opening != 'number' || typeof this.state.firmness != 'number' - return ( - <SymptomView - symptom={this.symptom} - values={this.state} - date={this.props.date} - > - <SymptomSection - header="Opening" - explainer={labels.opening.explainer} - > - <SelectTabGroup - buttons={this.cervixOpeningRadioProps} - active={this.state.opening} - onSelect={val => this.setState({ opening: val })} - /> - </SymptomSection> - <SymptomSection - header="Firmness" - explainer={labels.firmness.explainer} - > - <SelectTabGroup - buttons={this.cervixFirmnessRadioProps} - active={this.state.firmness} - onSelect={val => this.setState({ firmness: val })} - /> - </SymptomSection> - <SymptomSection - header="Position" - explainer={labels.position.explainer} - > - <SelectTabGroup - buttons={this.cervixPositionRadioProps} - active={this.state.position} - onSelect={val => this.setState({ position: val })} - /> - </SymptomSection> - <SymptomSection - header="Exclude" - explainer="You can exclude this value if you don't want to use it for fertility detection" - inline={true} - > - <Switch - onValueChange={(val) => { - this.setState({ exclude: val }) - }} - value={this.state.exclude} - /> - </SymptomSection> - </SymptomView> - ) - } -} - -export default Cervix diff --git a/components/cycle-day/symptoms/desire.js b/components/cycle-day/symptoms/desire.js deleted file mode 100644 index de05f5296a20a1e2f4849f764e7acc2d0e77f7d4..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/desire.js +++ /dev/null @@ -1,69 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' - -import { intensity, desire } from '../../../i18n/en/cycle-day' -import SelectTabGroup from '../select-tab-group' -import SymptomSection from './symptom-section' -import SymptomView from './symptom-view' - -import { getLabelsList } from '../../helpers/labels' -import { saveSymptom } from '../../../db' - -class Desire extends Component { - - static propTypes = { - cycleDay: PropTypes.object, - date: PropTypes.string.isRequired, - } - - constructor(props) { - super(props) - const symptom = 'desire' - const { cycleDay } = props - - const defaultSymptomData = { value: null } - - const symptomData = - cycleDay && cycleDay[symptom] ? cycleDay[symptom] : defaultSymptomData - - this.state = { ...symptomData } - - this.symptom = symptom - - this.desireRadioProps = getLabelsList(intensity) - } - - autoSave = () => { - const { date } = this.props - const valuesToSave = { ...this.state } - const hasValueToSave = typeof this.state.value === 'number' - saveSymptom(this.symptom, date, hasValueToSave ? valuesToSave : null) - } - - componentDidUpdate() { - this.autoSave() - } - - render() { - return ( - <SymptomView - symptom={this.symptom} - values={this.state} - date={this.props.date} - > - <SymptomSection - header={desire.header} - explainer={desire.explainer} - > - <SelectTabGroup - buttons={this.desireRadioProps} - active={this.state.value} - onSelect={val => this.setState({ value: val })} - /> - </SymptomSection> - </SymptomView> - ) - } -} - -export default Desire diff --git a/components/cycle-day/symptoms/index.js b/components/cycle-day/symptoms/index.js deleted file mode 100644 index aa84321ce6166bf658764242069961cbfc48092a..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/index.js +++ /dev/null @@ -1,21 +0,0 @@ -import BleedingEditView from './bleeding' -import TemperatureEditView from './temperature' -import MucusEditView from './mucus' -import CervixEditView from './cervix' -import NoteEditView from './note' -import DesireEditView from './desire' -import SexEditView from './sex' -import PainEditView from './pain' -import MoodEditView from './mood' - -export default { - BleedingEditView, - TemperatureEditView, - MucusEditView, - CervixEditView, - NoteEditView, - DesireEditView, - SexEditView, - PainEditView, - MoodEditView -} diff --git a/components/cycle-day/symptoms/info-symptom.js b/components/cycle-day/symptoms/info-symptom.js deleted file mode 100644 index 93820e2e328b41a06c909b3b6e7831fa579f0c1a..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/info-symptom.js +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { ScrollView, View, TouchableOpacity } from 'react-native' -import Icon from 'react-native-vector-icons/SimpleLineIcons' -import AppText from '../../app-text' -import labels from '../../../i18n/en/symptom-info.js' -import styles, {iconStyles} from '../../../styles/index' - -export default function InfoSymptom({ close, symptom }) { - return ( - <View style={styles.infoPopUpWrapper}> - <View style={styles.dimmed}></View> - <View style={styles.infoPopUp} testID="symptomInfoPopup"> - <TouchableOpacity onPress={close} style={styles.infoSymptomClose}> - <Icon name='close' {...iconStyles.infoPopUpClose}/> - </TouchableOpacity> - <ScrollView style={styles.infoSymptomText}> - <AppText>{labels[symptom].text}</AppText> - </ScrollView> - </View> - </View> - ) -} - -InfoSymptom.propTypes = { - close: PropTypes.func.isRequired, - symptom: PropTypes.string.isRequired -} diff --git a/components/cycle-day/symptoms/mood.js b/components/cycle-day/symptoms/mood.js deleted file mode 100644 index 228d2ce00f5831a2778d506ba4590a76ddabcb05..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/mood.js +++ /dev/null @@ -1,93 +0,0 @@ -import React, { Component } from 'react' -import { TextInput } from 'react-native' -import PropTypes from 'prop-types' - -import { mood as labels } from '../../../i18n/en/cycle-day' -import SelectBoxGroup from '../select-box-group' -import SymptomSection from './symptom-section' -import SymptomView from './symptom-view' - -import { saveSymptom } from '../../../db' - -class Mood extends Component { - - static propTypes = { - cycleDay: PropTypes.object, - date: PropTypes.string.isRequired, - } - - constructor(props) { - super(props) - const symptom = 'mood' - const { cycleDay } = props - - const defaultSymptomData = {} - - const symptomData = - cycleDay && cycleDay[symptom] ? cycleDay[symptom] : defaultSymptomData - - this.state = { ...symptomData } - - // We make sure other is always true when there is a note, - // e.g. when import is messed up. - if (this.state.note) this.state.other = true - - this.symptom = symptom - } - - autoSave = () => { - const { date } = this.props - const valuesToSave = Object.assign({}, this.state) - if (!valuesToSave.other) { - valuesToSave.note = null - } - const nothingEntered = Object.values(this.state).every(val => !val) - - saveSymptom(this.symptom, date, nothingEntered ? null : valuesToSave) - } - - componentDidUpdate() { - this.autoSave() - } - - toggleState = (key) => { - const curr = this.state[key] - this.setState({[key]: !curr}) - if (key === 'other' && !curr) { - this.setState({focusTextArea: true}) - } - } - - render() { - return ( - <SymptomView - symptom={this.symptom} - values={this.state} - date={this.props.date} - > - <SymptomSection - explainer={labels.explainer} - > - <SelectBoxGroup - labels={labels.categories} - onSelect={this.toggleState} - optionsState={this.state} - /> - { this.state.other && - <TextInput - autoFocus={this.state.focusTextArea} - multiline={true} - placeholder="Enter" - value={this.state.note} - onChangeText={(val) => { - this.setState({note: val}) - }} - /> - } - </SymptomSection> - </SymptomView> - ) - } -} - -export default Mood diff --git a/components/cycle-day/symptoms/mucus.js b/components/cycle-day/symptoms/mucus.js deleted file mode 100644 index 2a57362b097a70e5c732305a1b0cd9a2d188554b..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/mucus.js +++ /dev/null @@ -1,104 +0,0 @@ -import React, { Component } from 'react' -import { Switch } from 'react-native' -import PropTypes from 'prop-types' - -import { mucus as labels } from '../../../i18n/en/cycle-day' -import computeNfpValue from '../../../lib/nfp-mucus' -import SelectTabGroup from '../select-tab-group' -import SymptomSection from './symptom-section' -import SymptomView from './symptom-view' - -import { getLabelsList } from '../../helpers/labels' -import { saveSymptom } from '../../../db' - -class Mucus extends Component { - - static propTypes = { - cycleDay: PropTypes.object, - date: PropTypes.string.isRequired, - } - - constructor(props) { - super(props) - const symptom = 'mucus' - const { cycleDay } = props - - const defaultSymptomData = {} - - const symptomData = - cycleDay && cycleDay[symptom] ? cycleDay[symptom] : defaultSymptomData - - this.state = { ...symptomData } - - this.mucusFeeling = getLabelsList(labels.feeling.categories) - this.mucusTexture = getLabelsList(labels.texture.categories) - - this.symptom = symptom - } - - shouldAutoSave = () => { - const { date } = this.props - const nothingEntered = ['feeling', 'texture'].every( - val => typeof this.state[val] !== 'number' - ) - const { feeling, texture, exclude} = this.state - const valuesToSave = { - feeling, - texture, - value: computeNfpValue(feeling, texture), - exclude: Boolean(exclude) - } - saveSymptom(this.symptom, date, nothingEntered ? null : valuesToSave) - } - - componentDidUpdate() { - this.shouldAutoSave() - } - - render() { - // TODO leaving this info for notice when leaving incomplete data - // const mandatoryNotCompletedYet = typeof this.state.feeling != 'number' || typeof this.state.texture != 'number' - return ( - <SymptomView - symptom={this.symptom} - values={this.state} - date={this.props.date} - > - <SymptomSection - header='Feeling' - explainer={labels.feeling.explainer} - > - <SelectTabGroup - buttons={this.mucusFeeling} - onSelect={val => this.setState({ feeling: val })} - active={this.state.feeling} - /> - </SymptomSection> - <SymptomSection - header='Texture' - explainer={labels.texture.explainer} - > - <SelectTabGroup - buttons={this.mucusTexture} - onSelect={val => this.setState({ texture: val })} - active={this.state.texture} - /> - </SymptomSection> - <SymptomSection - header="Exclude" - explainer={labels.excludeExplainer} - inline={true} - > - <Switch - onValueChange={(val) => { - this.setState({ exclude: val }) - }} - value={this.state.exclude} - /> - </SymptomSection> - </SymptomView> - ) - } -} - -export default Mucus diff --git a/components/cycle-day/symptoms/note.js b/components/cycle-day/symptoms/note.js deleted file mode 100644 index dc702547515cf2fafcdd3c0dfca833907c23de87..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/note.js +++ /dev/null @@ -1,65 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { TextInput } from 'react-native' - -import SymptomSection from './symptom-section' -import { noteExplainer } from '../../../i18n/en/cycle-day' -import { shared as sharedLabels } from '../../../i18n/en/labels' -import SymptomView from './symptom-view' - -import { saveSymptom } from '../../../db' - -class Note extends Component { - static propTypes = { - cycleDay: PropTypes.object, - date: PropTypes.string.isRequired - } - - constructor(props) { - super(props) - const symptom = 'note' - const { cycleDay } = props - - const defaultSymptomData = { value: '' } - - const symptomData = - cycleDay && cycleDay[symptom] ? cycleDay[symptom] : defaultSymptomData - - this.state = { ...symptomData } - - this.symptom = symptom - } - - autoSave = () => { - const { date } = this.props - const valuesToSave = { ...this.state } - saveSymptom(this.symptom, date, this.state.value ? valuesToSave : null) - } - - componentDidUpdate() { - this.autoSave() - } - - render() { - return ( - <SymptomView - symptom={this.symptom} - values={this.state} - date={this.props.date} - > - <SymptomSection explainer={noteExplainer} > - <TextInput - autoFocus={true} - multiline={true} - placeholder={sharedLabels.enter} - onChangeText={(val) => { this.setState({ value: val })}} - value={this.state.value} - testID='noteInput' - /> - </SymptomSection> - </SymptomView> - ) - } -} - -export default Note diff --git a/components/cycle-day/symptoms/pain.js b/components/cycle-day/symptoms/pain.js deleted file mode 100644 index 218eb38f31fd85d35d15a65c82adcccac8fedb13..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/pain.js +++ /dev/null @@ -1,94 +0,0 @@ -import React, { Component } from 'react' -import { TextInput } from 'react-native' -import PropTypes from 'prop-types' - -import { pain as labels } from '../../../i18n/en/cycle-day' -import { shared as sharedLabels } from '../../../i18n/en/labels' -import SelectBoxGroup from '../select-box-group' -import SymptomSection from './symptom-section' -import SymptomView from './symptom-view' - -import { saveSymptom } from '../../../db' - -class Pain extends Component { - - static propTypes = { - cycleDay: PropTypes.object, - date: PropTypes.string.isRequired, - } - - constructor(props) { - super(props) - const symptom = 'pain' - const { cycleDay } = props - - const defaultSymptomData = {} - - const symptomData = - cycleDay && cycleDay[symptom] ? cycleDay[symptom] : defaultSymptomData - - this.state = { ...symptomData } - - // We make sure other is always true when there is a note, - // e.g. when import is messed up. - if (this.state.note) this.state.other = true - - this.symptom = symptom - } - - autoSave = () => { - const { date } = this.props - const valuesToSave = Object.assign({}, this.state) - if (!valuesToSave.other) { - valuesToSave.note = null - } - const nothingEntered = Object.values(this.state).every(val => !val) - - saveSymptom(this.symptom, date, nothingEntered ? null : valuesToSave) - } - - componentDidUpdate() { - this.autoSave() - } - - toggleState = (key) => { - const curr = this.state[key] - this.setState({[key]: !curr}) - if (key === 'other' && !curr) { - this.setState({focusTextArea: true}) - } - } - - render() { - return ( - <SymptomView - symptom={this.symptom} - values={this.state} - date={this.props.date} - > - <SymptomSection - explainer={labels.explainer} - > - <SelectBoxGroup - labels={labels.categories} - onSelect={this.toggleState} - optionsState={this.state} - /> - { this.state.other && - <TextInput - autoFocus={this.state.focusTextArea} - multiline={true} - placeholder={sharedLabels.enter} - value={this.state.note} - onChangeText={(val) => { - this.setState({note: val}) - }} - /> - } - </SymptomSection> - </SymptomView> - ) - } -} - -export default Pain diff --git a/components/cycle-day/symptoms/sex.js b/components/cycle-day/symptoms/sex.js deleted file mode 100644 index 6b4bd96fed1def04a494451a38f5e4baa4f29b9c..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/sex.js +++ /dev/null @@ -1,110 +0,0 @@ -import React, { Component } from 'react' -import { TextInput } from 'react-native' -import PropTypes from 'prop-types' - -import { sex as sexLabels, contraceptives as contraceptivesLabels } from '../../../i18n/en/cycle-day' -import { shared as sharedLabels } from '../../../i18n/en/labels' -import SelectBoxGroup from '../select-box-group' -import SymptomSection from './symptom-section' -import SymptomView from './symptom-view' - -import { saveSymptom } from '../../../db' - -class Sex extends Component { - - static propTypes = { - cycleDay: PropTypes.object, - date: PropTypes.string.isRequired, - } - - constructor(props) { - super(props) - const symptom = 'sex' - const { cycleDay } = props - - const defaultSymptomData = {} - - const symptomData = - cycleDay && cycleDay[symptom] ? cycleDay[symptom] : defaultSymptomData - - this.state = { ...symptomData } - - // We make sure other is always true when there is a note, - // e.g. when import is messed up. - if (this.state.note) this.state.other = true - - this.symptom = symptom - } - - autoSave = () => { - const { date } = this.props - const valuesToSave = Object.assign({}, this.state) - if (!valuesToSave.other) { - valuesToSave.note = null - } - const nothingEntered = Object.values(this.state).every(val => !val) - - saveSymptom(this.symptom, date, nothingEntered ? null : valuesToSave) - } - - componentDidUpdate() { - this.autoSave() - } - - toggleState = (key) => { - const curr = this.state[key] - this.setState({[key]: !curr}) - if (key === 'other'){ - if (curr){ - this.setState({note: ""}) - } else { - this.setState({focusTextArea: true}) - } - } - } - - render() { - return ( - <SymptomView - symptom={this.symptom} - values={this.state} - date={this.props.date} - > - <SymptomSection - header={sexLabels.header} - explainer={sexLabels.explainer} - > - <SelectBoxGroup - labels={sexLabels.categories} - onSelect={this.toggleState} - optionsState={this.state} - /> - </SymptomSection> - <SymptomSection - header={contraceptivesLabels.header} - explainer={contraceptivesLabels.explainer} - > - <SelectBoxGroup - labels={contraceptivesLabels.categories} - onSelect={this.toggleState} - optionsState={this.state} - /> - </SymptomSection> - - {this.state.other && - <TextInput - autoFocus={this.state.focusTextArea} - multiline={true} - placeholder={sharedLabels.enter} - value={this.state.note} - onChangeText={(val) => { - this.setState({ note: val }) - }} - /> - } - </SymptomView> - ) - } -} - -export default Sex diff --git a/components/cycle-day/symptoms/symptom-info.js b/components/cycle-day/symptoms/symptom-info.js deleted file mode 100644 index 6ccfab33905c18fc9474e83eefb3a637740f555f..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/symptom-info.js +++ /dev/null @@ -1,41 +0,0 @@ -import React, { Component } from 'react' -import { TouchableOpacity } from 'react-native' -import PropTypes from 'prop-types' -import Icon from 'react-native-vector-icons/Entypo' - -import InfoPopUp from './info-symptom' - -import styles, { iconStyles } from '../../../styles' - -export default class SymptomInfo extends Component { - - static propTypes = { - symptom: PropTypes.string - } - - constructor() { - super() - this.state = { showInfo: false } - } - - showInfo = () => this.setState({ showInfo: true }) - - hideInfo = () => this.setState({ showInfo: false }) - - render() { - return ( - <React.Fragment> - <TouchableOpacity - onPress={this.showInfo} - style={styles.infoButtonSymptomView} - testID="symptomInfoButton" - > - <Icon name="info-with-circle" style={iconStyles.info} /> - </TouchableOpacity> - { this.state.showInfo && - <InfoPopUp symptom={this.props.symptom} close={this.hideInfo} /> - } - </React.Fragment> - ) - } -} \ No newline at end of file diff --git a/components/cycle-day/symptoms/symptom-section.js b/components/cycle-day/symptoms/symptom-section.js deleted file mode 100644 index 92192dfaf2a5d253aaa8585475a4bf561e7d472b..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/symptom-section.js +++ /dev/null @@ -1,36 +0,0 @@ -import React, { Component } from 'react' -import { View } from 'react-native' -import AppText from '../../app-text' -import styles from '../../../styles' - -export default class SymptomSection extends Component { - render() { - const p = this.props - let placeHeadingInline - if (!p.explainer && p.inline) { - placeHeadingInline = { - flexDirection: 'row', - alignItems: "center" - } - } - return ( - <View style={[placeHeadingInline, styles.symptomSection]}> - { p.header && - <AppText style={styles.symptomViewHeading}>{p.header}</AppText> - } - <View - flexDirection={p.inline ? 'row' : null} - flex={1} - alignItems={p.inline ? 'center' : null} - > - { p.explainer && ( - <View flex={1}> - <AppText>{p.explainer}</AppText> - </View> - )} - {p.children} - </View> - </View> - ) - } -} \ No newline at end of file diff --git a/components/cycle-day/symptoms/symptom-view.js b/components/cycle-day/symptoms/symptom-view.js deleted file mode 100644 index a02ca83f5120bed3b9ede542f802b74d67f3d562..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/symptom-view.js +++ /dev/null @@ -1,117 +0,0 @@ -import React, { Component } from 'react' -import { ScrollView, View, Alert } from 'react-native' -import PropTypes from 'prop-types' - -import { connect } from 'react-redux' -import { getDate } from '../../../slices/date' -import { goBack } from '../../../slices/navigation' - -import { saveSymptom } from '../../../db' -import formatDate from '../../helpers/format-date' - -import Header from '../../header' -import SymptomInfo from './symptom-info' - -import { headerTitles } from '../../../i18n/en/labels' -import { sharedDialogs } from '../../../i18n/en/cycle-day' - -import styles from '../../../styles' - -const checkIfHasValues = data => { - const isMeaningfulValue = value => value || value === 0 - return Object.values(data).some(isMeaningfulValue) -} - -class SymptomView extends Component { - - static propTypes = { - symptom: PropTypes.string.isRequired, - values: PropTypes.object, - date: PropTypes.string, - children: PropTypes.node, - goBack: PropTypes.func, - } - - constructor(props) { - super() - this.state = { - shouldShowDelete: checkIfHasValues(props.values) - } - } - - componentDidUpdate() { - const shouldShowDelete = checkIfHasValues(this.props.values) - if (shouldShowDelete !== this.state.shouldShowDelete) { - this.setState({ shouldShowDelete }) - } - } - - deleteSymptomEntry() { - const { symptom, date } = this.props - saveSymptom(symptom, date, null) - } - - onDeleteConfirmation = () => { - this.deleteSymptomEntry() - this.props.goBack() - } - - showConfirmationAlert = () => { - - const cancelButton = { - text: sharedDialogs.cancel, - style: 'cancel' - } - - const confirmationButton = { - text: sharedDialogs.reallyDeleteData, - onPress: this.onDeleteConfirmation - } - - return Alert.alert( - sharedDialogs.areYouSureTitle, - sharedDialogs.areYouSureToDelete, - [cancelButton, confirmationButton] - ) - } - - render() { - const { symptom, date, goBack } = this.props - const { shouldShowDelete } = this.state - const handleDelete = shouldShowDelete ? this.showConfirmationAlert : null - - return ( - <View style={{flex: 1}}> - <Header - title={headerTitles[symptom]} - subtitle={formatDate(date)} - handleBack={goBack} - handleDelete={handleDelete} - /> - <View flex={1}> - <ScrollView style={styles.page}> - {this.props.children} - </ScrollView> - <SymptomInfo symptom={symptom} /> - </View> - </View> - ) - } -} - -const mapStateToProps = (state) => { - return({ - date: getDate(state), - }) -} - -const mapDispatchToProps = (dispatch) => { - return({ - goBack: () => dispatch(goBack()), - }) -} - -export default connect( - mapStateToProps, - mapDispatchToProps, -)(SymptomView) diff --git a/components/cycle-day/symptoms/temperature-input.js b/components/cycle-day/symptoms/temperature-input.js deleted file mode 100644 index cc0dbd90be1844b37ad128275169d934e7c3323e..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/temperature-input.js +++ /dev/null @@ -1,108 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' - -import { View } from 'react-native' -import AppText from '../../app-text' -import AppTextInput from '../../app-text-input' - -import { temperature as labels } from '../../../i18n/en/cycle-day' - -import styles from '../../../styles' - -import { getPreviousTemperature } from '../../../db' -import { scaleObservable } from '../../../local-storage' -import config from '../../../config' - -export default class TemperatureInput extends Component { - - static propTypes = { - temperature: PropTypes.string, - handleTemperatureChange: PropTypes.func, - date: PropTypes.string, - } - - constructor(props) { - super(props) - - let shouldShowSuggestion = false - let suggestedTemperature = null - - if (!props.temperature) { - const prevTemp = getPreviousTemperature(props.date) - if (prevTemp) { - shouldShowSuggestion = true - suggestedTemperature = prevTemp.toString() - } - } - - this.state = { - temperature: props.temperature, - shouldShowSuggestion, - suggestedTemperature - } - } - - setTemperature = (temperature) => { - this.setState({ - shouldShowSuggestion: false, - temperature - }) - this.props.handleTemperatureChange(Number(temperature)) - } - - render () { - const { - shouldShowSuggestion, - suggestedTemperature, - temperature - } = this.state - const inputStyle = [ - styles.temperatureTextInput, - shouldShowSuggestion ? styles.temperatureTextInputSuggestion : null - ] - return ( - <React.Fragment> - <View style={styles.framedSegmentInlineChildren}> - <AppTextInput - style={inputStyle} - autoFocus={true} - value={shouldShowSuggestion ? suggestedTemperature : temperature} - onChangeText={this.setTemperature} - keyboardType='numeric' - maxLength={5} - testID='temperatureInput' - /> - <AppText style={{ marginLeft: 5 }}>°C</AppText> - </View> - <OutOfRangeWarning temperature={this.props.temperature} /> - </React.Fragment> - ) - } -} - -const OutOfRangeWarning = ({ temperature }) => { - if (temperature === '') { - return false - } - - const value = Number(temperature) - const { min, max } = config.temperatureScale - const range = { min, max } - const scale = scaleObservable.value - - let warningMsg - - if (value < range.min || value > range.max) { - warningMsg = labels.outOfAbsoluteRangeWarning - } else if (value < scale.min || value > scale.max) { - warningMsg = labels.outOfRangeWarning - } else { - warningMsg = null - } - - return <AppText style={styles.hint}>{warningMsg}</AppText> -} - -OutOfRangeWarning.propTypes = { - temperature: PropTypes.string.isRequired -} diff --git a/components/cycle-day/symptoms/temperature.js b/components/cycle-day/symptoms/temperature.js deleted file mode 100644 index 5c033c926c5bc5326cb4ed1c7c22c4805c4ff1b9..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/temperature.js +++ /dev/null @@ -1,139 +0,0 @@ -import React, { Component } from 'react' -import { Switch } from 'react-native' -import PropTypes from 'prop-types' - -import { LocalTime, ChronoUnit } from 'js-joda' -import { temperature as labels } from '../../../i18n/en/cycle-day' -import { shared as sharedLabels } from '../../../i18n/en/labels' - -import AppTextInput from '../../app-text-input' -import SymptomSection from './symptom-section' -import SymptomView from './symptom-view' -import TimeInput from './time-input' -import TemperatureInput from './temperature-input' - -import { saveSymptom } from '../../../db' - -const minutes = ChronoUnit.MINUTES - -class Temperature extends Component { - - static propTypes = { - cycleDay: PropTypes.object, - date: PropTypes.string.isRequired, - } - - constructor(props) { - super(props) - const symptom = 'temperature' - const { cycleDay } = props - - const defaultSymptomData = { - time: LocalTime.now().truncatedTo(minutes).toString(), - temperature: null, - note: '', - exclude: false - } - - const symptomData = - cycleDay && cycleDay[symptom] ? cycleDay[symptom] : defaultSymptomData - - const { value, ...restSymptomData } = symptomData - this.state = { temperature: value, ...restSymptomData } - - this.symptom = symptom - } - - isDeleteIconActive() { - return ['temperature', 'note', 'exclude'].some(key => { - // the time is always and the suggested temp sometimes prefilled, so they're not relevant for setting - // the delete button active. - return this.state[key] || this.state[key] === 0 - }) - } - - autoSave = () => { - const { date } = this.props - const { temperature, exclude, time, note } = this.state - - const valuesToSave = { - value: temperature, - exclude, - time, - note - } - - saveSymptom(this.symptom, date, temperature ? valuesToSave : null) - } - - setTime = (time) => { - this.setState({ time }) - } - - setTemperature = (temperature) => { - this.setState({ temperature }) - } - - setNote = (note) => { - this.setState({ note }) - } - - componentDidUpdate() { - this.autoSave() - } - - render() { - const { temperature } = this.state - - return ( - <SymptomView - symptom={'temperature'} - values={this.state} - date={this.props.date} - > - <SymptomSection - header={labels.temperature.header} - explainer={labels.temperature.explainer} - > - <TemperatureInput - temperature={temperature ? temperature.toFixed(2) : ''} - date={this.props.date} - handleTemperatureChange={this.setTemperature} - /> - </SymptomSection> - <SymptomSection header={labels.time}> - <TimeInput - time={this.state.time} - handleTimeChange={this.setTime} - /> - </SymptomSection> - <SymptomSection - header={labels.note.header} - explainer={labels.note.explainer} - > - <AppTextInput - multiline={true} - placeholder={sharedLabels.enter} - value={this.state.note} - onChangeText={this.setNote} - testID='noteInput' - /> - </SymptomSection> - <SymptomSection - header={labels.exclude.header} - explainer={labels.exclude.explainer} - inline={true} - > - <Switch - onValueChange={(val) => { - this.setState({ exclude: val }) - }} - value={this.state.exclude} - /> - </SymptomSection> - </SymptomView> - ) - } -} - -export default Temperature diff --git a/components/cycle-day/symptoms/time-input.js b/components/cycle-day/symptoms/time-input.js deleted file mode 100644 index 1d0bc0f051ff04bd21951f8ade72a03d77a58021..0000000000000000000000000000000000000000 --- a/components/cycle-day/symptoms/time-input.js +++ /dev/null @@ -1,62 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { Keyboard } from 'react-native' - -import AppTextInput from '../../app-text-input' -import styles from '../../../styles' - -import DateTimePicker from 'react-native-modal-datetime-picker-nevo' -import moment from 'moment' - -export default class TimeInput extends Component { - - static propTypes = { - time: PropTypes.string, - handleTimeChange: PropTypes.func, - } - - constructor(props) { - super(props) - - this.state = { - isTimePickerVisible: false, - } - } - - showTimePicker = () => { - Keyboard.dismiss() - this.setState({ isTimePickerVisible: true }) - } - - hideTimePicker = () => { - this.setState({ isTimePickerVisible: false }) - } - - handleConfirm = (jsDate) => { - // DateTimePicker also when in mode="time" returns full date (with time) - const time = moment(jsDate).format('HH:mm') - this.props.handleTimeChange(time) - this.setState({ - isTimePickerVisible: false - }) - } - - render () { - return ( - <React.Fragment> - <AppTextInput - style={styles.temperatureTextInput} - onFocus={this.showTimePicker} - value={this.props.time} - testID='timeInput' - /> - <DateTimePicker - mode="time" - isVisible={this.state.isTimePickerVisible} - onConfirm={this.handleConfirm} - onCancel={this.hideTimePicker} - /> - </React.Fragment> - ) - } -} diff --git a/components/cycle-day/temperature.js b/components/cycle-day/temperature.js new file mode 100644 index 0000000000000000000000000000000000000000..653133a65fe011a1730ad5ea0526a55052acfe8b --- /dev/null +++ b/components/cycle-day/temperature.js @@ -0,0 +1,158 @@ +import React, { Component } from 'react' +import { StyleSheet, View } from 'react-native' +import PropTypes from 'prop-types' +import { Keyboard } from 'react-native' +import DateTimePicker from 'react-native-modal-datetime-picker-nevo' +import moment from 'moment' + +import AppText from '../common/app-text' +import AppTextInput from '../common/app-text-input' +import Segment from '../common/segment' + +import { connect } from 'react-redux' +import { getDate } from '../../slices/date' +import { isTemperatureOutOfRange, isPreviousTemperature } from '../helpers/cycle-day' + +import { temperature as labels } from '../../i18n/en/cycle-day' + +import { Colors, Containers, Sizes, Spacing } from '../../styles' + +const formatTemperature = value => value === null + ? value + : Number.parseFloat(value).toFixed(2) + +class Temperature extends Component { + + static propTypes = { + data: PropTypes.object, + date: PropTypes.string.isRequired, + save: PropTypes.func + } + + constructor(props) { + super(props) + + const { data, date } = this.props + const { value } = data + const { shouldShowSuggestion, suggestedTemperature } = + isPreviousTemperature(date) + + this.state = { + isTimePickerVisible: false, + shouldShowSuggestion, + suggestedTemperature: formatTemperature(suggestedTemperature), + value: formatTemperature(value) + } + } + + onCancelTimePicker = () => { + this.setState({ isTimePickerVisible: false }) + } + + onChangeTemperature = (value) => { + this.setState({ value, shouldShowSuggestion: false }) + } + + onShowTimePicker = () => { + Keyboard.dismiss() + this.setState({ isTimePickerVisible: true }) + } + + setTemperature = () => { + const { value } = this.state + this.props.save(value, 'value') + } + + setTime = (jsDate) => { + const time = moment(jsDate).format('HH:mm') + const isTimePickerVisible = false + + this.props.save(time, 'time') + this.setState({ isTimePickerVisible }) + } + + render() { + const { shouldShowSuggestion, suggestedTemperature, value } = this.state + const { time } = this.props.data + + const inputStyle = (shouldShowSuggestion && value === null) + ? { color: Colors.grey } + : {color: Colors.greyDark} + const outOfRangeWarning = isTemperatureOutOfRange(value) + let temperatureToShow = null + + if (value) { + temperatureToShow = value + } else if (shouldShowSuggestion) { + temperatureToShow = suggestedTemperature + } + + return ( + <React.Fragment> + <Segment> + <AppText style={styles.title}>{labels.temperature.explainer}</AppText> + <View style={styles.container}> + <AppTextInput + value={temperatureToShow === null ? '' : temperatureToShow} + onChangeText={this.onChangeTemperature} + onEndEditing={this.setTemperature} + keyboardType="numeric" + maxLength={5} + style={inputStyle} + testID="temperatureInput" + underlineColorAndroid="transparent" + /> + <AppText>°C</AppText> + </View> + { outOfRangeWarning !== null && + <View style={styles.hintContainer}> + <AppText style={styles.hint}>{outOfRangeWarning}</AppText> + </View> + } + </Segment> + <Segment> + <AppText style={styles.title}>{labels.time}</AppText> + <AppTextInput + onFocus={this.onShowTimePicker} + testID='timeInput' + value={time} + /> + <DateTimePicker + isVisible={this.state.isTimePickerVisible} + mode="time" + onConfirm={this.setTime} + onCancel={this.onCancelTimePicker} + /> + </Segment> + </React.Fragment> + ) + } +} + +const styles = StyleSheet.create({ + container: { + ...Containers.rowContainer + }, + hint: { + fontStyle: 'italic', + fontSize: Sizes.small + }, + hintContainer: { + marginVertical: Spacing.tiny + }, + title: { + fontSize: Sizes.subtitle + } +}) + + +const mapStateToProps = (state) => { + return({ + date: getDate(state), + }) +} + +export default connect( + mapStateToProps, + null, +)(Temperature) diff --git a/components/framed-segment.js b/components/framed-segment.js deleted file mode 100644 index 49bce23203045b476de0e3351721723bc574f6c9..0000000000000000000000000000000000000000 --- a/components/framed-segment.js +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' - -import { View } from 'react-native' -import AppText from './app-text' -import styles from '../styles' - -const FramedSegment = ({ children, last, style, title }) => { - const viewStyle = [styles.framedSegment, style] - if (last) viewStyle.push(styles.framedSegmentLast) - return ( - <View style={[viewStyle]}> - {title && <AppText style={styles.framedSegmentTitle}>{title}</AppText>} - {children} - </View> - ) -} - -FramedSegment.propTypes = { - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node - ]), - last: PropTypes.bool, - style: PropTypes.object, - title: PropTypes.string -} - -export default FramedSegment diff --git a/components/header/delete-icon.js b/components/header/delete-icon.js deleted file mode 100644 index 1b67001ceaf8080b64f68c71d37daed80a9f7c9b..0000000000000000000000000000000000000000 --- a/components/header/delete-icon.js +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react' -import { TouchableOpacity } from 'react-native' -import PropTypes from 'prop-types' - -import Icon from 'react-native-vector-icons/AntDesign' - -import styles, { iconStyles } from '../../styles' - -export default function DeleteIcon({ handleDelete }) { - - return ( - <TouchableOpacity - onPress={handleDelete} - style={styles.headerDeleteButton} - testID="deleteIcon" - > - <Icon - name="delete" - {...iconStyles.symptomHeaderIcons} - /> - </TouchableOpacity> - ) -} - -DeleteIcon.propTypes = { - handleDelete: PropTypes.func, -} diff --git a/components/header/hamburger-menu.js b/components/header/hamburger-menu.js new file mode 100644 index 0000000000000000000000000000000000000000..16ace0bc526969c8c2d0218e78a2491d0c56f477 --- /dev/null +++ b/components/header/hamburger-menu.js @@ -0,0 +1,91 @@ +import React, { Component } from 'react' +import { Modal, StyleSheet, TouchableOpacity, View } from 'react-native' + +import AppIcon from '../common/app-icon' +import MenuItem from './menu-item' + +import { Colors, Sizes } from '../../styles' +import settingsLabels from '../../i18n/en/settings' +import { HIT_SLOP } from '../../config' + +const { menuItems } = settingsLabels + +const settingsMenuItems = [ + { name: menuItems.settings, component: 'SettingsMenu' }, + { name: menuItems.about, component: 'About' }, + { name: menuItems.license, component: 'License' }, +] + +export default class HamburgerMenu extends Component { + constructor(props) { + super(props) + + this.state = { shouldShowMenu: false } + } + + toggleMenu = () => { + this.setState({ shouldShowMenu: !this.state.shouldShowMenu }) + } + + render() { + const { shouldShowMenu } = this.state + + return ( + <React.Fragment> + {!shouldShowMenu && ( + <TouchableOpacity onPress={this.toggleMenu} hitSlop={HIT_SLOP}> + <AppIcon name='dots-three-vertical' color={Colors.orange} /> + </TouchableOpacity> + )} + {shouldShowMenu && ( + <Modal + animationType='fade' + onRequestClose={this.toggleMenu} + transparent={true} + visible={shouldShowMenu} + > + <TouchableOpacity + onPress={this.toggleMenu} + style={styles.blackBackground} + ></TouchableOpacity> + <View style={styles.menu}> + <TouchableOpacity + onPress={this.toggleMenu} + style={styles.iconContainer} + > + <AppIcon name='cross' color='black' /> + </TouchableOpacity> + {settingsMenuItems.map((item) => ( + <MenuItem + item={item} + key={item.name} + closeMenu={this.toggleMenu} + /> + ))} + </View> + </Modal> + )} + </React.Fragment> + ) + } +} + +const styles = StyleSheet.create({ + blackBackground: { + backgroundColor: 'black', + flex: 1, + opacity: 0.65, + }, + iconContainer: { + alignSelf: 'flex-end', + marginBottom: Sizes.base, + }, + menu: { + alignSelf: 'flex-end', + backgroundColor: 'white', + height: '100%', + padding: Sizes.base, + position: 'absolute', + width: '60%', + }, +}) diff --git a/components/header/index.js b/components/header/index.js index 885eec3631d21bd2dea1591f0ddb6f6681bf3a57..11845069d14372a67080f2d775ade56ce7153e8c 100644 --- a/components/header/index.js +++ b/components/header/index.js @@ -1,36 +1,36 @@ import React from 'react' -import { View } from 'react-native' +import { StyleSheet, View } from 'react-native' import PropTypes from 'prop-types' -import Title from './title' -import NavigationArrow from './navigation-arrow' -import DeleteIcon from './delete-icon' +import Logo from './logo' +import HamburgerMenu from './hamburger-menu' -import styles from '../../styles' +import { Colors, Containers, Sizes } from '../../styles' -export default function Header({ - handleBack, - handleNext, - handleDelete, - title, - subtitle, -}) { +const Header = ({ isSideMenuEnabled }) => { return ( <View style={styles.header}> - <View style={styles.accentCircle} /> - { handleBack && <NavigationArrow handleBack={handleBack} /> } - <Title title={title} subtitle={subtitle} /> - { handleNext && <NavigationArrow handleNext={handleNext} /> } - { handleDelete && <DeleteIcon handleDelete={handleDelete} /> } + <Logo /> + {isSideMenuEnabled && <HamburgerMenu />} </View > ) } Header.propTypes = { - handleBack: PropTypes.func, - handleDelete: PropTypes.func, - handleNext: PropTypes.func, - subtitle: PropTypes.string, - title: PropTypes.string.isRequired + isSideMenuEnabled: PropTypes.bool } + +Header.defaultProps = { + isSideMenuEnabled: true +} + +const styles = StyleSheet.create({ + header: { + backgroundColor: Colors.purple, + padding: Sizes.base, + ...Containers.rowContainer + } +}) + +export default Header \ No newline at end of file diff --git a/components/header/logo.js b/components/header/logo.js new file mode 100644 index 0000000000000000000000000000000000000000..da2759be704580250e9ef1e51cbc824c04334f1c --- /dev/null +++ b/components/header/logo.js @@ -0,0 +1,41 @@ +import React from 'react' +import { StyleSheet, TouchableOpacity } from 'react-native' +import PropTypes from 'prop-types' + +import AppText from '../common/app-text' + +import { connect } from 'react-redux' +import { navigate } from '../../slices/navigation' + +import { Colors, Fonts, Sizes } from '../../styles' + +const Logo = ({ navigate }) => { + return( + <TouchableOpacity onPress={() => navigate('Home')}> + <AppText style={styles.logo}>drip.</AppText> + </TouchableOpacity> + ) +} + +Logo.propTypes = { + navigate: PropTypes.func.isRequired +} + +const styles = StyleSheet.create({ + logo: { + color: Colors.turquoiseDark, + fontFamily: Fonts.bold, + fontSize: Sizes.title + } +}) + +const mapDispatchToProps = (dispatch) => { + return({ + navigate: (page) => dispatch(navigate(page)), + }) +} + +export default connect( + null, + mapDispatchToProps, +)(Logo) \ No newline at end of file diff --git a/components/header/menu-item.js b/components/header/menu-item.js new file mode 100644 index 0000000000000000000000000000000000000000..d7b1a46725ec1f4aefca1675bd1b97a4a2576fed --- /dev/null +++ b/components/header/menu-item.js @@ -0,0 +1,47 @@ +import React from 'react' +import { StyleSheet, TouchableOpacity } from 'react-native' +import PropTypes from 'prop-types' + +import AppText from '../common/app-text' + +import { connect } from 'react-redux' +import { navigate } from '../../slices/navigation' + +import { Typography } from '../../styles' + +const MenuItem = ({ item, navigate, closeMenu }) => { + const { component, name } = item + const onPress = () => { + closeMenu() + navigate(component) + } + + return( + <TouchableOpacity onPress={onPress}> + <AppText style={styles.text}>{name}</AppText> + </TouchableOpacity> + ) +} + +MenuItem.propTypes = { + item: PropTypes.object.isRequired, + navigate: PropTypes.func.isRequired, + closeMenu: PropTypes.func.isRequired +} + +const styles = StyleSheet.create({ + text: { + ...Typography.subtitle + } +}) + +const mapDispatchToProps = (dispatch) => { + return({ + navigate: (page) => dispatch(navigate(page)), + }) +} + +export default connect( + null, + mapDispatchToProps, +)(MenuItem) diff --git a/components/header/navigation-arrow.js b/components/header/navigation-arrow.js deleted file mode 100644 index 7675893b5ca0a6170fa4663d809dda4cdd3cd902..0000000000000000000000000000000000000000 --- a/components/header/navigation-arrow.js +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react' -import { TouchableOpacity } from 'react-native' -import PropTypes from 'prop-types' -import Icon from 'react-native-vector-icons/Entypo' - -import styles, { iconStyles } from '../../styles' - -export default function NavigationArrow({ handleBack, handleNext }) { - const navigationDirection = handleBack ? 'Left' : 'Right' - return ( - <TouchableOpacity - style={[ - styles.navigationArrow, - styles[`navigationArrow${navigationDirection}`] - ]} - onPress={ handleBack || handleNext } - testID={ handleBack ? 'backButton' : 'nextButton'} - > - <Icon - name={`chevron-thin-${navigationDirection.toLowerCase()}`} - {...iconStyles.navigationArrow} - /> - </TouchableOpacity> - ) -} - -NavigationArrow.propTypes = { - handleBack: PropTypes.func, - handleNext: PropTypes.func, -} \ No newline at end of file diff --git a/components/header/title.js b/components/header/title.js deleted file mode 100644 index f667ded24cdeb84d3c10a2f39880e90dd7b2fd08..0000000000000000000000000000000000000000 --- a/components/header/title.js +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' -import { View, Text} from 'react-native' -import PropTypes from 'prop-types' - -import styles from '../../styles' - -export default function Title({ title, subtitle }) { - - if (subtitle !== undefined) { - return ( - <View> - <Text style={styles.dateHeader} testID='headerTitle'> - { // design wants everyhting lowercased, but we don't - // have CSS pseudo properties - title.toLowerCase()} - </Text> - { subtitle && - <Text style={styles.cycleDayNumber} testID='headerSubtitle'> - {subtitle.toLowerCase()} - </Text> - } - </View> - ) - } - - return ( - <Text testID='headerTitle' style={styles.headerText}> - {title.toLowerCase()} - </Text> - ) -} - -Title.propTypes = { - title: PropTypes.string, - subtitle: PropTypes.string, -} diff --git a/components/helpers/calendar.js b/components/helpers/calendar.js new file mode 100644 index 0000000000000000000000000000000000000000..fdedfa8fce86f0246f77fe4fe5df7f1f2456cc7c --- /dev/null +++ b/components/helpers/calendar.js @@ -0,0 +1,81 @@ +import { LocalDate } from 'js-joda' + +import { Colors, Fonts, Sizes } from '../../styles' + +const { shades } = Colors.iconColors.bleeding + +export const toCalFormat = (bleedingDaysSortedByDate) => { + const todayDateString = LocalDate.now().toString() + + return bleedingDaysSortedByDate.reduce((acc, day) => { + acc[day.date] = { + customStyles: { + container: { + backgroundColor: shades[day.bleeding.value], + paddingTop: 2, + }, + text: { + color: Colors.turquoiseLight, + ...(day.date === todayDateString && styles.calendarToday), + }, + }, + } + return acc + }, {}) +} + +export const predictionToCalFormat = (predictedDays) => { + if (!predictedDays.length) return {} + const todayDateString = LocalDate.now().toString() + const middleIndex = (predictedDays[0].length - 1) / 2 + return predictedDays.reduce((acc, setOfDays) => { + setOfDays.reduce((accSet, day, i) => { + accSet[day] = { + customStyles: { + container: { + borderColor: i === middleIndex ? shades[3] : shades[0], + borderStyle: i === middleIndex ? 'solid' : 'dashed', + borderWidth: 1, + }, + }, + } + if (day === todayDateString) { + accSet[day].customStyles.text = styles.calendarToday + } + + return accSet + }, acc) + return acc + }, {}) +} + +export const todayToCalFormat = () => { + const todayDateString = LocalDate.now().toString() + return { + [todayDateString]: { + customStyles: { + text: styles.calendarToday, + }, + }, + } +} + +const styles = { + calendarToday: { + fontFamily: Fonts.bold, + color: Colors.purple, + }, +} + +export const calendarTheme = { + calendarBackground: Colors.turquoiseLight, + dayTextColor: Colors.greyDark, + monthTextColor: Colors.purple, + textDayFontFamily: Fonts.main, + textMonthFontFamily: Fonts.bold, + textDayHeaderFontFamily: Fonts.bold, + textDayFontSize: Sizes.small, + textMonthFontSize: Sizes.subtitle, + textDayHeaderFontSize: Sizes.small, + textSectionTitleColor: Colors.orange, +} diff --git a/components/helpers/chart.js b/components/helpers/chart.js index dac2fafd0c5faa2943cc37a35a7a09881d3b5bd0..0a68a1bfaa461cf56359220925bd655b1294d416 100644 --- a/components/helpers/chart.js +++ b/components/helpers/chart.js @@ -1,30 +1,36 @@ import { LocalDate } from 'js-joda' import { scaleObservable, unitObservable } from '../../local-storage' +import { getCycleStatusForDay } from '../../lib/sympto-adapter' import { getCycleDay, getAmountOfCycleDays } from '../../db' -import config from '../../config' - //YAxis helpers export function normalizeToScale(temp, columnHeight) { - const scale = scaleObservable.value - const valueRelativeToScale = (scale.max - temp) / (scale.max - scale.min) + const unit = unitObservable.value + //Add 1 tick above the max value to display on chart + const scaleMax = scaleObservable.value.max + unit + const scaleMin = scaleObservable.value.min - unit + const valueRelativeToScale = (scaleMax - temp) / (scaleMax - scaleMin) return getAbsoluteValue(valueRelativeToScale, columnHeight) } function getAbsoluteValue(relative, columnHeight) { - // we add some height to have some breathing room - const verticalPadding = columnHeight * config.temperatureScale.verticalPadding - const scaleHeight = columnHeight - 2 * verticalPadding - return scaleHeight * relative + verticalPadding + return columnHeight * relative +} + +function getTickConfig() { + const unit = unitObservable.value + //Add 1 tick above the max value to display on chart + const scaleMax = scaleObservable.value.max + unit + const scaleMin = scaleObservable.value.min - unit + const numberOfTicks = Math.round((scaleMax - scaleMin) / unit + 1) + + return { numberOfTicks, scaleMax, scaleMin, unit } } export function getTickPositions(columnHeight) { - const units = unitObservable.value - const scaleMin = scaleObservable.value.min - const scaleMax = scaleObservable.value.max - const numberOfTicks = (scaleMax - scaleMin) * (1 / units) + 1 + const { numberOfTicks } = getTickConfig() const tickDistance = 1 / (numberOfTicks - 1) const tickPositions = [] for (let i = 0; i < numberOfTicks; i++) { @@ -35,32 +41,30 @@ export function getTickPositions(columnHeight) { } export function getTickList(columnHeight) { - - const units = unitObservable.value - const scaleMax = scaleObservable.value.max + const { numberOfTicks, scaleMax, unit } = getTickConfig() + const tickHeight = columnHeight / numberOfTicks return getTickPositions(columnHeight).map((tickPosition, i) => { - const tick = scaleMax - i * units - let isBold, label, shouldShowLabel + const tick = scaleMax - i * unit + const isBold = Number.isInteger(tick) ? true : false + const label = tick.toFixed(1) + let shouldShowLabel - if (Number.isInteger(tick)) { - isBold = true - label = tick.toString() + '.0' - } else { - isBold = false - label = tick.toString() - } + // when temp range <= 2, units === 0.1 we show temp values with step 0.2 + // when temp range > 2, units === 0.5 we show temp values with step 0.5 - // when temp range <= 3, units === 0.1 we show temp values with step 0.2 - // when temp range > 3, units === 0.5 we show temp values with step 0.5 - - if (units === 0.1) { + if (unit === 0.1) { // show label with step 0.2 - shouldShowLabel = !(tick * 10 % 2) + shouldShowLabel = !(label * 10 % 2) } else { // show label with step 0.5 - shouldShowLabel = !(tick * 10 % 5) + shouldShowLabel = !(label * 10 % 5) + } + + // don't show label, if first or last tick + if ( i === 0 || i === (numberOfTicks - 1) ) { + shouldShowLabel = false } return { @@ -68,6 +72,7 @@ export function getTickList(columnHeight) { label, isBold, shouldShowLabel, + tickHeight } }) } @@ -201,4 +206,87 @@ function getTodayAndPreviousDays(n) { } return getDaysInRange(today, []) -} \ No newline at end of file +} + +export function nfpLines() { + const cycle = { + status: null + } + + function updateCurrentCycle(dateString) { + // for the NFP lines, we don't care about potentially extending the + // preOvu phase, so we don't include all earlier cycles, as that is + // an expensive db operation at the moment + cycle.status = getCycleStatusForDay( + dateString, { excludeEarlierCycles: true } + ) + if(!cycle.status) { + cycle.noMoreCycles = true + return + } + if (cycle.status.phases.preOvulatory) { + cycle.startDate = cycle.status.phases.preOvulatory.start.date + } else { + cycle.startDate = cycle.status.phases.periOvulatory.start.date + } + } + + function dateIsInPeriOrPostPhase(dateString) { + return ( + dateString >= cycle.status.phases.periOvulatory.start.date + ) + } + + function precededByAnotherTempValue(dateString) { + return ( + // we are only interested in days that have a preceding + // temp + Object.keys(cycle.status.phases).some(phaseName => { + return cycle.status.phases[phaseName].cycleDays.some(day => { + return day.temperature && day.date < dateString + }) + }) + // and also a following temp, so we don't draw the line + // longer than necessary + && + cycle.status.phases.postOvulatory.cycleDays.some(day => { + return day.temperature && day.date > dateString + }) + ) + } + + function isInTempMeasuringPhase(temperature, dateString) { + return ( + temperature || precededByAnotherTempValue(dateString) + ) + } + + return function(dateString, temperature, columnHeight) { + const ret = { + drawLtlAt: null, + drawFhmLine: false + } + if (!cycle.status && !cycle.noMoreCycles) updateCurrentCycle(dateString) + if (cycle.noMoreCycles) return ret + + if (dateString < cycle.startDate) updateCurrentCycle(dateString) + if (cycle.noMoreCycles) return ret + + const tempShift = cycle.status.temperatureShift + + if (tempShift) { + if (tempShift.firstHighMeasurementDay.date === dateString) { + ret.drawFhmLine = true + } + + if ( + dateIsInPeriOrPostPhase(dateString) && + isInTempMeasuringPhase(temperature, dateString) + ) { + ret.drawLtlAt = normalizeToScale(tempShift.ltl, columnHeight) + } + } + + return ret + } +} diff --git a/components/helpers/cycle-day.js b/components/helpers/cycle-day.js new file mode 100644 index 0000000000000000000000000000000000000000..56e1b06b7730ca44b761488219f410e830f1bc87 --- /dev/null +++ b/components/helpers/cycle-day.js @@ -0,0 +1,429 @@ +import { ChronoUnit, LocalDate, LocalTime } from 'js-joda' + +import { getPreviousTemperature, saveSymptom } from '../../db' +import { scaleObservable } from '../../local-storage' + +import * as labels from '../../i18n/en/cycle-day' +import { getLabelsList } from './labels' +import { TEMP_MAX, TEMP_MIN } from '../../config' + +import computeNfpValue from '../../lib/nfp-mucus' + +const bleedingLabels = labels.bleeding.labels +const cervixLabels = labels.cervix +const contraceptiveLabels = labels.contraceptives.categories +const intensityLabels = labels.intensity +const moodLabels = labels.mood.categories +const mucusLabels = labels.mucus +const noteDescription = labels.noteExplainer +const painLabels = labels.pain.categories +const sexLabels = labels.sex.categories +const temperatureLabels = labels.temperature + +const minutes = ChronoUnit.MINUTES + +const isNumber = (value) => typeof value === 'number' +export const shouldShow = (value) => value !== null ? true : false + +export const isPreviousTemperature = (temperature) => { + const previousTemperature = getPreviousTemperature(temperature) + const shouldShowSuggestion = previousTemperature ? true : false + const suggestedTemperature = previousTemperature ? + previousTemperature.toString() : null + + return { shouldShowSuggestion, suggestedTemperature } +} + +export const isTemperatureOutOfRange = (temperature) => { + if (!temperature) return null + + const value = Number(temperature) + const range = { min: TEMP_MIN, max: TEMP_MAX } + const scale = scaleObservable.value + + let warningMsg = null + + if (value < range.min || value > range.max) { + warningMsg = labels.temperature.outOfAbsoluteRangeWarning + } else if (value < scale.min || value > scale.max) { + warningMsg = labels.temperature.outOfRangeWarning + } + + return warningMsg +} + +export const blank = { + bleeding: { + exclude: false, + value: null + }, + cervix: { + exclude: false, + firmness: null, + opening: null, + position: null, + }, + desire: { + value: null + }, + mood:{ + happy: null, + sad: null, + stressed: null, + balanced: null, + fine: null, + anxious: null, + energetic: null, + fatigue: null, + angry: null, + other: null, + note: null + }, + mucus: { + exclude: false, + feeling: null, + texture: null, + value: null + }, + note: { + value: null + }, + pain: { + cramps: null, + ovulationPain: null, + headache: null, + backache: null, + nausea: null, + tenderBreasts: null, + migraine: null, + other: null, + note: null + }, + sex: { + solo: null, + partner: null, + condom: null, + pill: null, + iud: null, + patch: null, + ring: null, + implant: null, + diaphragm: null, + none: null, + other: null, + note: null + }, + temperature: { + exclude: false, + note: null, + time: LocalTime.now().truncatedTo(minutes).toString(), + value: null + } +} + +export const symtomPage = { + bleeding: { + excludeText: labels.bleeding.exclude.explainer, + note: null, + selectBoxGroups: null, + selectTabGroups: [{ + key: 'value', + options: getLabelsList(bleedingLabels), + title: labels.bleeding.heaviness.explainer, + }] + }, + cervix: { + excludeText: cervixLabels.excludeExplainer, + note: null, + selectBoxGroups: null, + selectTabGroups: [ + { + key: 'opening', + options: getLabelsList(cervixLabels.opening.categories), + title: cervixLabels.opening.explainer, + }, + { + key: 'firmness', + options: getLabelsList(cervixLabels.firmness.categories), + title: cervixLabels.firmness.explainer, + }, + { + key: 'position', + options: getLabelsList(cervixLabels.position.categories), + title: cervixLabels.position.explainer, + } + ] + }, + desire: { + excludeText: null, + note: null, + selectBoxGroups: null, + selectTabGroups: [{ + key: 'value', + options: getLabelsList(intensityLabels), + title: labels.desire.explainer + }] + }, + mucus: { + excludeText: mucusLabels.excludeExplainer, + note: null, + selectBoxGroups: null, + selectTabGroups: [ + { + key: 'feeling', + options: getLabelsList(mucusLabels.feeling.categories), + title: mucusLabels.feeling.explainer, + }, + { + key: 'texture', + options: getLabelsList(mucusLabels.texture.categories), + title: mucusLabels.texture.explainer, + } + ] + }, + mood: { + excludeText: null, + note: null, + selectBoxGroups: [{ + key: 'mood', + options: moodLabels, + title: labels.mood.explainer + }], + selectTabGroups: null + }, + note: { + excludeText: null, + note: noteDescription, + selectBoxGroups: null, + selectTabGroups: null + }, + pain: { + excludeText: null, + note: null, + selectBoxGroups: [{ + key: 'pain', + options: painLabels, + title: labels.pain.explainer + }], + selectTabGroups: null + }, + sex: { + excludeText: null, + note: null, + selectBoxGroups: [ + { + key: 'sex', + options: sexLabels, + title: labels.sex.explainer, + }, + { + key: 'contraceptives', + options: contraceptiveLabels, + title: labels.contraceptives.explainer, + } + ], + selectTabGroups: null + }, + temperature: { + excludeText: temperatureLabels.exclude.explainer, + note: temperatureLabels.note.explainer, + selectBoxGroups: null, + selectTabGroups: null + } +} + +export const save = { + bleeding: (data, date, shouldDeleteData) => { + const { exclude, value } = data + const isDataEntered = isNumber(value) + const valuesToSave = shouldDeleteData || !isDataEntered + ? null : { value, exclude } + + saveSymptom('bleeding', date, valuesToSave) + }, + cervix: (data, date, shouldDeleteData) => { + const { opening, firmness, position, exclude } = data + const isDataEntered = ['opening', 'firmness', 'position'].some( + value => isNumber(data[value])) + const valuesToSave = shouldDeleteData || !isDataEntered + ? null : { opening, firmness, position, exclude } + + saveSymptom('cervix', date, valuesToSave) + }, + desire: (data, date, shouldDeleteData) => { + const { value } = data + const valuesToSave = shouldDeleteData || !isNumber(value) + ? null : { value } + + saveSymptom('desire', date, valuesToSave) + }, + mood: (data, date, shouldDeleteData) => { + saveBoxSymptom(data, date, shouldDeleteData, 'mood') + }, + mucus: (data, date, shouldDeleteData) => { + const { feeling, texture, exclude } = data + const isDataEntered = ['feeling', 'texture'].some( + value => isNumber(data[value])) + const valuesToSave = shouldDeleteData || !isDataEntered + ? null : { feeling, texture, value: computeNfpValue(feeling, texture), exclude } + + saveSymptom('mucus', date, valuesToSave) + }, + note: (data, date, shouldDeleteData) => { + const { value } = data + const isValidData = value !== null && value !== '' + const valuesToSave = shouldDeleteData || !isValidData ? null : { value } + + saveSymptom('note', date, valuesToSave) + }, + pain: (data, date, shouldDeleteData) => { + saveBoxSymptom(data, date, shouldDeleteData, 'pain') + }, + sex: (data, date, shouldDeleteData) => { + saveBoxSymptom(data, date, shouldDeleteData, 'sex') + }, + temperature: (data, date, shouldDeleteData) => { + const { exclude, note, time, value } = data + const valuesToSave = { + exclude, + note, + time, + value: Number(value) + } + + saveSymptom( + 'temperature', + date, + (shouldDeleteData || value === null) ? null : valuesToSave + ) + } +} + +const saveBoxSymptom = (data, date, shouldDeleteData, symptom) => { + const isDataEntered = Object.keys(data).some(key => data[key] !== null) + const valuesToSave = shouldDeleteData || !isDataEntered + ? null : data + + saveSymptom(symptom, date, valuesToSave) +} + +const label = { + bleeding: ({ value, exclude }) => { + if (isNumber(value)) { + const bleedingLabel = bleedingLabels[value] + return exclude ? `(${bleedingLabel})` : bleedingLabel + } + }, + temperature: ({ value, time, exclude }) => { + if (isNumber(value)) { + let temperatureLabel = `${value} °C` + if (time) { + temperatureLabel += ` - ${time}` + } + if (exclude) { + temperatureLabel = `(${temperatureLabel})` + } + return temperatureLabel + } + }, + mucus: mucus => { + const filledCategories = ['feeling', 'texture'].filter(c => isNumber(mucus[c])) + let label = filledCategories.map(category => { + return labels.mucus.subcategories[category] + ': ' + labels.mucus[category].categories[mucus[category]] + }).join(', ') + + if (isNumber(mucus.value)) label += `\n => ${labels.mucusNFP[mucus.value]}` + if (mucus.exclude) label = `(${label})` + + return label + }, + cervix: cervix => { + const filledCategories = ['opening', 'firmness', 'position'].filter(c => isNumber(cervix[c])) + let label = filledCategories.map(category => { + return labels.cervix.subcategories[category] + ': ' + labels.cervix[category].categories[cervix[category]] + }).join(', ') + + if (cervix.exclude) label = `(${label})` + + return label + }, + note: note => note.value, + desire: ({ value }) => { + if (isNumber(value)) { + return intensityLabels[value] + } + }, + sex: sex => { + const sexLabel = [] + if (sex && Object.values({...sex}).some(val => val)){ + Object.keys(sex).forEach(key => { + if(sex[key] && key !== 'other' && key !== 'note') { + sexLabel.push( + sexLabels[key] || + contraceptiveLabels[key] + ) + } + if(key === 'other' && sex.other) { + let label = contraceptiveLabels[key] + if(sex.note) { + label = `${label} (${sex.note})` + } + sexLabel.push(label) + } + }) + return sexLabel.join(', ') + } + }, + pain: pain => { + const painLabel = [] + if (pain && Object.values({...pain}).some(val => val)){ + Object.keys(pain).forEach(key => { + if(pain[key] && key !== 'other' && key !== 'note') { + painLabel.push(painLabels[key]) + } + if(key === 'other' && pain.other) { + let label = painLabels[key] + if(pain.note) { + label = `${label} (${pain.note})` + } + painLabel.push(label) + } + }) + return painLabel.join(', ') + } + }, + mood: mood => { + const moodLabel = [] + if (mood && Object.values({...mood}).some(val => val)){ + Object.keys(mood).forEach(key => { + if(mood[key] && key !== 'other' && key !== 'note') { + moodLabel.push(moodLabels[key]) + } + if(key === 'other' && mood.other) { + let label = moodLabels[key] + if(mood.note) { + label = `${label} (${mood.note})` + } + moodLabel.push(label) + } + }) + return moodLabel.join(', ') + } + } +} + +export const getData = (symptom, symptomData) => { + return symptomData && label[symptom](symptomData) +} + +export const prevDate = (dateString) => { + return LocalDate.parse(dateString).minusDays(1).toString() +} + +export const nextDate = (dateString) => { + return LocalDate.parse(dateString).plusDays(1).toString() +} + +export const isDateInFuture = (dateString) => { + return LocalDate.now().isBefore(LocalDate.parse(dateString)) +} diff --git a/components/helpers/format-date.js b/components/helpers/format-date.js index d353dc645542dc73df2303bc84fd28069c2863cd..f9e2cc367de89eb4770c9dacf881d89f2ad7d0e3 100644 --- a/components/helpers/format-date.js +++ b/components/helpers/format-date.js @@ -1,14 +1,24 @@ import { LocalDate } from 'js-joda' import moment from 'moment' +import { general as labels } from '../../i18n/en/cycle-day' + export default function (date) { const today = LocalDate.now() const dateToDisplay = LocalDate.parse(date) return today.equals(dateToDisplay) ? - 'today' : + labels.today : moment(date).format('MMMM Do YYYY') } export function formatDateForShortText (date) { return moment(date.toString()).format('dddd, MMMM Do') +} + +export function dateToTitle(dateString) { + const today = LocalDate.now() + const dateToDisplay = LocalDate.parse(dateString) + return today.equals(dateToDisplay) ? + labels.today : + moment(dateString).format('dddd, Do MMM YYYY') } \ No newline at end of file diff --git a/components/helpers/home.js b/components/helpers/home.js index 98e9f20054a7c2f20011e96de55d2b7fd55bae08..e5b75c30a2eecd4274179bfe38086050cb9097e8 100644 --- a/components/helpers/home.js +++ b/components/helpers/home.js @@ -12,7 +12,7 @@ function getTimes(prediction) { const predictedBleedingStart = LocalDate.parse(prediction[0][0]) /* the range of predicted bleeding days can be either 3 or 5 */ const predictedBleedingEnd = - LocalDate.parse(prediction[0][ prediction[0].length - 1 ]) + LocalDate.parse(prediction[0][prediction[0].length - 1]) const daysToEnd = todayDate.until(predictedBleedingEnd, ChronoUnit.DAYS) return { todayDate, predictedBleedingStart, predictedBleedingEnd, daysToEnd } } @@ -62,3 +62,26 @@ export function getBleedingPredictionRange(prediction) { } return (daysToEnd === 0 ? '0' : `0 - ${daysToEnd}`) } + +export function getOrdinalSuffix(num) { + const j = num % 10 + const k = num % 100 + + if (j === 1 && k !== 11) { + return 'st' + } + + if (j === 2 && k !== 12) { + return 'nd' + } + + if (j === 3 && k !== 13) { + return 'rd' + } + + return 'th' +} + +export function formatWithOrdinalSuffix(num) { + return num + getOrdinalSuffix(num) +} diff --git a/components/home-element.js b/components/home-element.js deleted file mode 100644 index 5c2423b04380ac47fd37199f48e22d7a4bb77fcc..0000000000000000000000000000000000000000 --- a/components/home-element.js +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react' -import { View } from 'react-native' -import PropTypes from 'prop-types' - -import Button from './button' - -import styles from '../styles' - -const HomeElement = ({ children, onPress, buttonColor, buttonLabel }) => { - return ( - <View - onPress={ onPress } - style={ styles.homeElement } - > - <View style={styles.homeIconAndText}> - {children[0]} - {children[1]} - </View> - - <View style={{paddingLeft: 15}}> - {children.slice(2)} - <Button - style={styles.homeButton} - onPress={ onPress } - backgroundColor={ buttonColor }> - { buttonLabel } - </Button> - </View> - </View> - ) -} - -HomeElement.propTypes = { - buttonColor: PropTypes.string, - buttonLabel: PropTypes.string, - children: PropTypes.node, - onPress: PropTypes.func, -} - -export default HomeElement diff --git a/components/home.js b/components/home.js index 2b900d58a00e2b50efbc2110ea9ef07a0a329431..a6c8cc189cfaca6318c52a4295abe1132d81f86b 100644 --- a/components/home.js +++ b/components/home.js @@ -1,54 +1,53 @@ -import { LocalDate } from 'js-joda' import React, { Component } from 'react' -import { ScrollView, View } from 'react-native' -import { connect } from 'react-redux' +import { ScrollView, StyleSheet, View } from 'react-native' import PropTypes from 'prop-types' +import { LocalDate } from 'js-joda' + +import { connect } from 'react-redux' import { navigate } from '../slices/navigation' import { getDate, setDate } from '../slices/date' -import DripHomeIcon from '../assets/drip-home-icons' - -import AppText from './app-text' -import IconText from './icon-text' -import HomeElement from './home-element' - -import { home as labels } from '../i18n/en/labels' -import links from '../i18n/en/links' +import AppText from './common/app-text' +import Button from './common/button' import cycleModule from '../lib/cycle' import { getFertilityStatusForDay } from '../lib/sympto-adapter' -import { - determinePredictionText, - getBleedingPredictionRange -} from './helpers/home' +import { determinePredictionText, formatWithOrdinalSuffix } from './helpers/home' -import styles, { cycleDayColor, periodColor, secondaryColor } from '../styles' +import { Colors, Fonts, Sizes, Spacing } from '../styles' +import { home as labels } from '../i18n/en/labels' class Home extends Component { static propTypes = { navigate: PropTypes.func, - setDate: PropTypes.func, - // The following are not being used, - // we could see if it's possible to not pass them from the <App /> - cycleDay: PropTypes.object, - date: PropTypes.string, + setDate: PropTypes.func } constructor(props) { super(props) + const today = LocalDate.now() + this.todayDateString = today.toString() const { getCycleDayNumber, getPredictedMenses } = cycleModule() - - this.todayDateString = LocalDate.now().toString() this.cycleDayNumber = getCycleDayNumber(this.todayDateString) - + const { status, phase, statusText } = + getFertilityStatusForDay(this.todayDateString) const prediction = getPredictedMenses() - this.predictionText = determinePredictionText(prediction) - this.bleedingPredictionRange = getBleedingPredictionRange(prediction) - - this.fertilityStatus = getFertilityStatusForDay(this.todayDateString) + this.prediction = determinePredictionText(prediction) + this.title = `${today.dayOfMonth()} ${today.month()} ${today.year()}` + + if (this.cycleDayNumber) { + this.cycleDayText = formatWithOrdinalSuffix(this.cycleDayNumber) + } + + if (phase) { + this.phase = phase + this.phaseText = formatWithOrdinalSuffix(phase) + this.status = status + this.statusText = statusText + } } navigateToCycleDayView = () => { @@ -56,96 +55,112 @@ class Home extends Component { this.props.navigate('CycleDay') } - navigateToBleedingEditView = () => { - this.props.setDate(this.todayDateString) - this.props.navigate('BleedingEditView') - } - - navigateToChart = () => { - this.props.navigate('Chart') - } - render() { const { cycleDayNumber, - predictionText, - bleedingPredictionRange, + cycleDayText, + phase, + phaseText, + prediction, + status, + statusText, + title } = this - const { phase, status, statusText } = this.fertilityStatus - - const cycleDayMoreText = cycleDayNumber ? - labels.cycleDayKnown(cycleDayNumber) : - labels.cycleDayNotEnoughInfo - return ( - <View flex={1}> - <ScrollView> - <View style={styles.homeView}> - <HomeElement - onPress={this.navigateToCycleDayView} - buttonColor={ cycleDayColor } - buttonLabel={ labels.editToday } - > - <View> - <DripHomeIcon name="circle" size={80} color={cycleDayColor}/> - </View> - <IconText>{cycleDayNumber || labels.unknown}</IconText> - - <AppText style={styles.homeDescriptionText}> - {cycleDayMoreText} - </AppText> - </HomeElement> - - <HomeElement - onPress={this.navigateToBleedingEditView} - buttonColor={ periodColor } - buttonLabel={ labels.trackPeriod } - > - <DripHomeIcon name="drop" size={100} color={periodColor} /> - - <IconText wrapperStyles={{ top: '45%' }}> - {bleedingPredictionRange} - </IconText> - - <AppText style={styles.homeDescriptionText}> - {predictionText} - </AppText> - </HomeElement> - - <HomeElement - onPress={this.navigateToChart} - buttonColor={ secondaryColor } - buttonLabel={ labels.checkFertility } - > - <View style={styles.homeCircle}/> - - <IconText>{ phase ? phase.toString() : labels.unknown }</IconText> - - { phase && - <AppText style={styles.homeDescriptionText}> - {`${labels.phase(phase)} (${status})`} - </AppText> - } - <AppText style={styles.homeDescriptionText}> - { `${statusText} Visit ${links.wiki.url}.` } - </AppText> - </HomeElement> + <ScrollView + style={styles.container} + contentContainerStyle={styles.contentContainer} + > + <AppText style={styles.title}>{title}</AppText> + + {cycleDayNumber && + <View style={styles.line}> + <AppText style={styles.whiteSubtitle}>{cycleDayText}</AppText> + <AppText style={styles.turquoiseText}>{labels.cycleDay}</AppText> </View> - </ScrollView> - </View> + } + {phase && + <View style={styles.line}> + <AppText style={styles.whiteSubtitle}>{phaseText}</AppText> + <AppText style={styles.turquoiseText}> + {labels.cyclePhase} + </AppText> + <AppText style={styles.turquoiseText}>{status}</AppText> + <Asterisk /> + </View> + } + <View style={styles.line}> + <AppText style={styles.turquoiseText}>{prediction}</AppText> + </View> + <Button isCTA isSmall={false} onPress={this.navigateToCycleDayView}> + {labels.addData} + </Button> + {phase && ( + <View style={styles.line}> + <Asterisk /> + <AppText linkStyle={styles.whiteText} style={styles.greyText}> + {statusText} + </AppText> + </View> + )} + </ScrollView> ) } } +const Asterisk = () => { + return <AppText style={styles.asterisk}>*</AppText> +} + +const styles = StyleSheet.create({ + asterisk: { + color: Colors.orange, + }, + container: { + backgroundColor: Colors.purple, + flex: 1, + }, + contentContainer: { + padding: Spacing.base, + }, + line: { + flexDirection: 'row', + justifyContent: 'flex-start', + marginBottom: Spacing.tiny, + marginTop: Spacing.small, + }, + title: { + color: Colors.purpleLight, + fontFamily: Fonts.bold, + fontSize: Sizes.huge, + marginVertical: Spacing.base, + }, + turquoiseText: { + color: Colors.turquoise, + fontSize: Sizes.subtitle, + }, + whiteSubtitle: { + color: 'white', + fontSize: Sizes.subtitle, + }, + whiteText: { + color: 'white', + }, + greyText: { + color: Colors.greyLight, + paddingLeft: Spacing.base, + } +}) + const mapStateToProps = (state) => { - return({ + return ({ date: getDate(state), }) } const mapDispatchToProps = (dispatch) => { - return({ + return ({ navigate: (page) => dispatch(navigate(page)), setDate: (date) => dispatch(setDate(date)), }) diff --git a/components/icon-text.js b/components/icon-text.js deleted file mode 100644 index be30d4832832001a0555722d00a7f809e30a54c6..0000000000000000000000000000000000000000 --- a/components/icon-text.js +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react' -import { View } from 'react-native' -import PropTypes from 'prop-types' - -import AppText from './app-text' - -import styles from '../styles' - -const IconText = ({ children, wrapperStyles }) => { - return ( - <View style={[ styles.homeIconTextWrapper, wrapperStyles ]}> - <AppText style={styles.iconText}> - { children } - </AppText> - </View> - ) -} - -IconText.propTypes = { - children: PropTypes.node, - wrapperStyles: PropTypes.object, -} - -export default IconText diff --git a/components/license.js b/components/license.js index b433063f079072b43dea99929309de2bd5dcd122..8c1bab754d241c41ae8b0a23c238464fd81d8e0c 100644 --- a/components/license.js +++ b/components/license.js @@ -1,44 +1,49 @@ import React from 'react' import PropTypes from 'prop-types' -import { ScrollView, View, BackHandler } from 'react-native' -import AppText from './app-text' +import { BackHandler, StyleSheet, View } from 'react-native' + +import AppPage from './common/app-page' +import AppText from './common/app-text' +import Button from './common/button' +import Segment from './common/segment' + +import { saveLicenseFlag } from '../local-storage' + import { shared } from '../i18n/en/labels' import settingsLabels from '../i18n/en/settings' -import styles,{secondaryColor} from '../styles' -import Button from './button' -import { saveLicenseFlag } from '../local-storage' +import { Containers } from '../styles' const labels = settingsLabels.license -export default function License({setLicense}) { + +export default function License({ setLicense }) { + const onAcceptLicense = async () => { + await saveLicenseFlag() + setLicense() + } + return ( - <ScrollView testID='licensePage' style={styles.licensePage}> - <AppText style={styles.framedSegmentTitle}>{labels.title}</AppText> - <AppText testID='test'>{labels.text}</AppText> - <View style={styles.licenseButtons}> - <Button - style={styles.licenseButton} - backgroundColor={'grey'} - onPress={() => BackHandler.exitApp()} - testID='licenseCancelButton' - > - {shared.cancel} - </Button> - <Button - style={styles.licenseButton} - backgroundColor={secondaryColor} - onPress={async () => { - await saveLicenseFlag() - setLicense() - }} - testID='licenseOkButton' - > - {shared.ok} - </Button> - </View> - </ScrollView> + <AppPage testID="licensePage"> + <Segment last testID="test" title={labels.title}> + <AppText testID="test">{labels.text}</AppText> + <View style={styles.container}> + <Button onPress={BackHandler.exitApp} testID="licenseCancelButton"> + {shared.cancel} + </Button> + <Button isCTA onPress={onAcceptLicense} testID="licenseOkButton"> + {shared.ok} + </Button> + </View> + </Segment> + </AppPage> ) } License.propTypes = { setLicense: PropTypes.func.isRequired } + +const styles = StyleSheet.create({ + container: { + ...Containers.rowContainer + } +}) diff --git a/components/link.js b/components/link.js deleted file mode 100644 index caea7925a99af1491a5233b905bf33584e1eb3be..0000000000000000000000000000000000000000 --- a/components/link.js +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import Hyperlink from 'react-native-hyperlink' -import styles from '../styles' -import links from '../i18n/en/links' - -export default function Link(props) { - return ( - <Hyperlink - linkStyle={styles.link} - linkText={replaceUrlWithText} - linkDefault - > - {props.children} - </Hyperlink> - ) -} - -Link.propTypes = { - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node - ]) -} - -function replaceUrlWithText(url) { - const link = Object.values(links).find(l => l.url === url) - return (link && link.text) || url -} \ No newline at end of file diff --git a/components/menu/index.js b/components/menu/index.js index 969082ebbe16e6500675b874a2e58702362fa9a1..2d329d00cf00a4b08897552234d7d505b90e44cc 100644 --- a/components/menu/index.js +++ b/components/menu/index.js @@ -1,30 +1,23 @@ import React from 'react' -import { View } from 'react-native' -import PropTypes from 'prop-types' +import { StyleSheet, View } from 'react-native' import MenuItem from './menu-item' -import { connect } from 'react-redux' -import { getNavigation, navigate } from '../../slices/navigation' - +import { Containers } from '../../styles' import { pages } from '../pages' -import styles from '../../styles' - -const Menu = ({ navigate, navigation }) => { +const Menu = () => { const menuItems = pages.filter(page => page.isInMenu) + return ( - <View style={styles.menu}> - { menuItems.map(({ icon, label, component, children }) => { - const isActive = (component === navigation.currentPage) || - (children && children.indexOf(navigation.currentPage) !== -1) + <View style={styles.container}> + { menuItems.map(({ icon, label, component }) => { return ( <MenuItem + component={component} + icon={icon} key={label} label={label} - icon={icon} - active={isActive} - onPress={() => navigate(component)} /> )} )} @@ -32,24 +25,11 @@ const Menu = ({ navigate, navigation }) => { ) } -Menu.propTypes = { - navigation: PropTypes.object, - navigate: PropTypes.func, -} - -const mapStateToProps = (state) => { - return({ - navigation: getNavigation(state), - }) -} - -const mapDispatchToProps = (dispatch) => { - return({ - navigate: (page) => dispatch(navigate(page)), - }) -} +const styles = StyleSheet.create({ + container: { + backgroundColor: 'white', + ...Containers.rowContainer + } +}) -export default connect( - mapStateToProps, - mapDispatchToProps, -)(Menu) \ No newline at end of file +export default Menu \ No newline at end of file diff --git a/components/menu/menu-item.js b/components/menu/menu-item.js index 8dc1bcdc689821e6567dca1cb7529e3c2b50158f..fc1c1f854ff515f6c4b1d93a689b8594325f1f21 100644 --- a/components/menu/menu-item.js +++ b/components/menu/menu-item.js @@ -1,36 +1,72 @@ import React from 'react' import PropTypes from 'prop-types' -import { Text, TouchableOpacity } from 'react-native' +import { StyleSheet, Text, TouchableOpacity } from 'react-native' -import styles, { iconStyles, secondaryColor } from '../../styles' -import Icon from 'react-native-vector-icons/MaterialCommunityIcons' +import Icon from '../common/menu-icon' -import { menuTitles } from '../../i18n/en/labels' +import { connect } from 'react-redux' +import { getNavigation, navigate } from '../../slices/navigation' -const menuTitlesLowerCase = Object.keys(menuTitles).reduce((acc, curr) => { - acc[curr] = menuTitles[curr].toLowerCase() - return acc -}, {}) +import { Colors, Containers, Fonts, Sizes, Spacing } from '../../styles' -export default function MenuItem({ active, icon, label, onPress }) { - const styleActive = active ? { color: secondaryColor } : null +const MenuItem = ({ component, icon, label, navigate, navigation }) => { + const isActive = (component === navigation.currentPage) + const textStyle = isActive ? styles.menuTextActive : styles.menuText + const testID = isActive ? 'activeMenuItem' : `menuItem${label}` return ( - <TouchableOpacity style={styles.menuItem} onPress={onPress} > - <Icon name={icon} {...iconStyles.menuIcon} {...styleActive} /> - <Text - testID={active ? 'activeMenuItem' : `menuItem${label}`} - style={[styles.menuText, styleActive]} - > - {menuTitlesLowerCase[label]} - </Text> + <TouchableOpacity + style={styles.button} + onPress={() => navigate(component)} + > + <Icon name={icon} isActive={isActive}/> + <Text testID={testID} style={textStyle} >{label}</Text> </TouchableOpacity> ) } MenuItem.propTypes = { - active: PropTypes.bool, + component: PropTypes.string.isRequired, icon: PropTypes.string.isRequired, label: PropTypes.string.isRequired, - onPress: PropTypes.func.isRequired -} \ No newline at end of file + navigation: PropTypes.object, + navigate: PropTypes.func, +} + +const text = { + fontFamily: Fonts.bold, + fontSize: Sizes.small, + textTransform: 'uppercase' +} + +const styles = StyleSheet.create({ + button: { + padding: Spacing.base, + ...Containers.centerItems + }, + menuText: { + color: Colors.grey, + ...text + }, + menuTextActive: { + color: Colors.orange, + ...text + } +}) + +const mapStateToProps = (state) => { + return({ + navigation: getNavigation(state), + }) +} + +const mapDispatchToProps = (dispatch) => { + return({ + navigate: (page) => dispatch(navigate(page)), + }) +} + +export default connect( + mapStateToProps, + mapDispatchToProps, +)(MenuItem) diff --git a/components/pages.js b/components/pages.js index 943a6a98366751bce36665314ae87f0e8f0e91cf..e7e6d986e7881a5259dd27bdc6238bab4d642c2a 100644 --- a/components/pages.js +++ b/components/pages.js @@ -1,16 +1,7 @@ -import symptomViews from './cycle-day/symptoms' import settingsViews from './settings' import settingsLabels from '../i18n/en/settings' -const labels = settingsLabels.menuTitles - -const symptomsPages = Object.keys(symptomViews).map(symptomView => ({ - component: symptomView, - parent: 'CycleDay', -})) - -export const isSymptomView = - (page) => Object.keys(symptomViews).includes(page) +const labels = settingsLabels.menuItems export const isSettingsView = (page) => Object.keys(settingsViews).includes(page) @@ -19,26 +10,25 @@ export const pages = [ { component: 'Home', icon: 'home', - isInMenu: true, label: 'Home', }, { component: 'Calendar', - icon: 'calendar-range', + icon: 'calendar', isInMenu: true, label: 'Calendar', parent: 'Home', }, { component: 'Chart', - icon: 'chart-line', + icon: 'chart', isInMenu: true, label: 'Chart', parent: 'Home', }, { component: 'Stats', - icon: 'chart-pie', + icon: 'statistics', isInMenu: true, label: 'Stats', parent: 'Home', @@ -47,43 +37,41 @@ export const pages = [ children: Object.keys(settingsViews), component: 'SettingsMenu', icon: 'settings', - isInMenu: true, label: 'Settings', parent: 'Home', }, { component: 'Reminders', - label: labels.reminders, + label: labels.reminders.name, parent: 'SettingsMenu', }, { component: 'NfpSettings', - label: labels.nfpSettings, + label: labels.nfpSettings.name, parent: 'SettingsMenu', }, { component: 'DataManagement', - label: labels.dataManagement, + label: labels.dataManagement.name, parent: 'SettingsMenu', }, { component: 'Password', - label: labels.password, + label: labels.password.name, parent: 'SettingsMenu', }, { component: 'About', - label: labels.about, + label: 'About', parent: 'SettingsMenu', }, { component: 'License', - label: labels.license, + label: 'License', parent: 'SettingsMenu', }, { component: 'CycleDay', parent: 'Home', - }, - ...symptomsPages + } ] \ No newline at end of file diff --git a/components/password-prompt.js b/components/password-prompt.js index b2b7af4d0a7e4f75c9eed0a4062caa4f8b18cc27..2924b469974a1a93e19f6971dfe8ac3ff9f5be1c 100644 --- a/components/password-prompt.js +++ b/components/password-prompt.js @@ -1,13 +1,19 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { View, TextInput, TouchableOpacity, Alert } from 'react-native' +import { Alert, StyleSheet, View } from 'react-native' import nodejs from 'nodejs-mobile-react-native' -import { saveEncryptionFlag } from '../local-storage' -import AppText from './app-text' + +import AppPage from './common/app-page' +import AppTextInput from './common/app-text-input' +import Button from './common/button' import Header from './header' -import styles from '../styles' -import { passwordPrompt as labels, shared, menuTitles } from '../i18n/en/labels' + +import { saveEncryptionFlag } from '../local-storage' import { requestHash, deleteDbAndOpenNew, openDb } from '../db' +import { passwordPrompt as labels, shared } from '../i18n/en/labels' +import { Containers, Spacing } from '../styles' + +const cancelButton = { text: shared.cancel, style: 'cancel' } export default class PasswordPrompt extends Component { static propTypes = { @@ -16,17 +22,40 @@ export default class PasswordPrompt extends Component { constructor(props) { super(props) - this.state = { - password: null - } + this.state = { password: null } + + nodejs.channel.addListener('check-pw', this.passHashToDb, this) + } - nodejs.channel.addListener( - 'check-pw', - this.passHashToDb, - this + componentWillUnmount() { + nodejs.channel.removeListener('check-pw', this.passHashToDb) + } + + onConfirmDeletion = async () => { + Alert.alert( + labels.deleteDatabaseTitle, + labels.deleteDatabaseExplainer, + [cancelButton, { text: labels.deleteData, onPress: this.onDeleteData}] ) } + onDeleteData = () => { + Alert.alert( + labels.areYouSureTitle, + labels.areYouSure, + [cancelButton, { + text: labels.reallyDeleteData, + onPress: this.onDeleteDataConfirmation + }] + ) + } + + onDeleteDataConfirmation = async () => { + await deleteDbAndOpenNew() + await saveEncryptionFlag(false) + this.props.enableShowApp() + } + passHashToDb = async hash => { const connected = await openDb(hash) if (!connected) { @@ -43,71 +72,53 @@ export default class PasswordPrompt extends Component { this.props.enableShowApp() } - confirmDeletion = async () => { - Alert.alert( - labels.deleteDatabaseTitle, - labels.deleteDatabaseExplainer, - [{ - text: shared.cancel, - style: 'cancel' - }, { - text: labels.deleteData, - onPress: () => { - Alert.alert( - labels.areYouSureTitle, - labels.areYouSure, - [{ - text: shared.cancel, - style: 'cancel' - }, { - text: labels.reallyDeleteData, - onPress: async () => { - await deleteDbAndOpenNew() - await saveEncryptionFlag(false) - this.props.enableShowApp() - } - }] - ) - } - }] - ) + unlockApp = () => { + requestHash('check-pw', this.state.password) } - componentWillUnmount() { - nodejs.channel.removeListener('check-pw', this.passHashToDb) + setPassword = (password) => { + this.setState({ password }) } render() { + const { password } = this.state + const isPasswordEntered = password && password.length > 0 + return ( - <View flex={1}> - <Header title={menuTitles.PasswordPrompt.toLowerCase()} /> - <View style={styles.passwordPromptPage}> - <TextInput - onChangeText={val => this.setState({ password: val })} - style={styles.passwordPromptField} + <React.Fragment> + <Header isSideMenuEnabled={false} /> + <AppPage contentContainerStyle={styles.contentContainer}> + <AppTextInput + onChangeText={this.setPassword} secureTextEntry={true} placeholder={labels.enterPassword} /> - <TouchableOpacity - style={styles.passwordPromptButton} - onPress={() => { - requestHash('check-pw', this.state.password) - }} - disabled={!this.state.password} - > - <AppText style={styles.passwordPromptButtonText}> + <View style={styles.containerButtons}> + <Button + disabled={!isPasswordEntered} + isCTA={isPasswordEntered} + onPress={this.unlockApp} + > {labels.title} - </AppText> - </TouchableOpacity> - <TouchableOpacity - onPress={this.confirmDeletion} - > - <AppText style={styles.passwordPromptForgotPasswordText}> + </Button> + <Button onPress={this.onConfirmDeletion}> {labels.forgotPassword} - </AppText> - </TouchableOpacity> - </View> - </View> + </Button> + </View> + </AppPage> + </React.Fragment> ) } -} \ No newline at end of file +} + +const styles = StyleSheet.create({ + contentContainer: { + flex: 1, + justifyContent: 'center', + marginHorizontal: Spacing.base + }, + containerButtons: { + ...Containers.rowContainer, + justifyContent: 'space-around' + } +}) \ No newline at end of file diff --git a/components/settings/about.js b/components/settings/about.js index f5be4c482a4ad3ea080d7a766bea513e3b46d6d5..ea2fc96706a9122a9f51d0f379d5a8a9873289b0 100644 --- a/components/settings/about.js +++ b/components/settings/about.js @@ -1,33 +1,35 @@ -import React, { Component } from 'react' -import { ScrollView } from 'react-native' -import AppText from '../app-text' +import React from 'react' + +import AppPage from '../common/app-page' +import AppText from '../common/app-text' +import Segment from '../common/segment' + import labels from '../../i18n/en/settings' import links from '../../i18n/en/links' -import FramedSegment from '../framed-segment' -export default class AboutSection extends Component { - render() { - return ( - <ScrollView> - <FramedSegment title={labels.aboutSection.title}> - <AppText>{labels.aboutSection.text}</AppText> - </FramedSegment> - <FramedSegment title={labels.philosophy.title}> - <AppText>{labels.philosophy.text}</AppText> - </FramedSegment> - <FramedSegment title={labels.credits.title}> - <AppText>{labels.credits.note}</AppText> - </FramedSegment> - <FramedSegment title={labels.donate.title}> - <AppText>{labels.donate.note}</AppText> - </FramedSegment> - <FramedSegment title={labels.website.title}> - <AppText>{links.website.url}</AppText> - </FramedSegment> - <FramedSegment title={labels.version.title} last> - <AppText>{require('../../package.json').version}</AppText> - </FramedSegment> - </ScrollView> - ) - } +const AboutSection = () => { + return ( + <AppPage title={labels.aboutSection.title} > + <Segment> + <AppText>{labels.aboutSection.text}</AppText> + </Segment> + <Segment title={labels.philosophy.title}> + <AppText>{labels.philosophy.text}</AppText> + </Segment> + <Segment title={labels.credits.title}> + <AppText>{labels.credits.note}</AppText> + </Segment> + <Segment title={labels.donate.title}> + <AppText>{labels.donate.note}</AppText> + </Segment> + <Segment title={labels.website.title}> + <AppText>{links.website.url}</AppText> + </Segment> + <Segment title={labels.version.title} last> + <AppText>{require('../../package.json').version}</AppText> + </Segment> + </AppPage> + ) } + +export default AboutSection diff --git a/components/settings/shared/alert-error.js b/components/settings/common/alert-error.js similarity index 100% rename from components/settings/shared/alert-error.js rename to components/settings/common/alert-error.js diff --git a/components/settings/shared/confirm-with-password.js b/components/settings/common/confirm-with-password.js similarity index 68% rename from components/settings/shared/confirm-with-password.js rename to components/settings/common/confirm-with-password.js index 02d56002f5db18d17615f9ea1c55f607117fbb8d..2b0b9705b95a379f5f1e6ecf76ed7c4d59905e36 100644 --- a/components/settings/shared/confirm-with-password.js +++ b/components/settings/common/confirm-with-password.js @@ -1,27 +1,22 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { View, Alert } from 'react-native' - +import { Alert, StyleSheet, View } from 'react-native' import nodejs from 'nodejs-mobile-react-native' -import { requestHash, openDb } from '../../../db' -import PasswordField from './password-field' -import SettingsButton from '../shared/settings-button' +import AppTextInput from '../../common/app-text-input' +import Button from '../../common/button' +import { requestHash, openDb } from '../../../db' +import { Containers } from '../../../styles' import settings from '../../../i18n/en/settings' import { shared } from '../../../i18n/en/labels' export default class ConfirmWithPassword extends Component { constructor() { super() - this.state = { - password: null - } - nodejs.channel.addListener( - 'password-check', - this.checkPassword, - this - ) + + this.state = { password: null } + nodejs.channel.addListener('password-check', this.checkPassword, this) } componentWillUnmount() { @@ -67,36 +62,29 @@ export default class ConfirmWithPassword extends Component { render() { const { password } = this.state const labels = settings.passwordSettings + const isPassword = password !== null return ( - <View> - <PasswordField + <React.Fragment> + <AppTextInput + onChangeText={this.handlePasswordInput} placeholder={labels.enterCurrent} value={password} - onChangeText={this.handlePasswordInput} + secureTextEntry={true} /> - <View style={{ - flex: 1, - flexDirection: 'row', - justifyContent: 'space-between' - }}> - <SettingsButton - onPress={this.props.onCancel} - secondary - > + <View style={styles.container}> + <Button onPress={this.props.onCancel}> {shared.cancel} - </SettingsButton> - <SettingsButton + </Button> + <Button + disabled={!isPassword} + isCTA={isPassword} onPress={this.initPasswordCheck} - disabled={!password} - style={{ - flex: 1, - }} > {shared.confirmToProceed} - </SettingsButton> + </Button> </View> - </View> + </React.Fragment> ) } @@ -105,4 +93,10 @@ export default class ConfirmWithPassword extends Component { ConfirmWithPassword.propTypes = { onSuccess: PropTypes.func, onCancel: PropTypes.func -} \ No newline at end of file +} + +const styles = StyleSheet.create({ + container: { + ...Containers.rowContainer + } +}) \ No newline at end of file diff --git a/components/settings/shared/password-field.js b/components/settings/common/password-field.js similarity index 88% rename from components/settings/shared/password-field.js rename to components/settings/common/password-field.js index 7937b6696a23bb2bce05691bd1fba37e145afc54..d22fdd1f3f94f9b327465f6523b6fc98dbe84436 100644 --- a/components/settings/shared/password-field.js +++ b/components/settings/common/password-field.js @@ -1,6 +1,6 @@ import React from 'react' import PropTypes from 'prop-types' -import AppTextInput from '../../app-text-input' +import AppTextInput from '../../common/app-text-input' import styles from '../../../styles' diff --git a/components/settings/shared/settings-button.js b/components/settings/common/settings-button.js similarity index 95% rename from components/settings/shared/settings-button.js rename to components/settings/common/settings-button.js index 94aa2104207914c338bb8044d21bcc9fe943c642..93af5f2dac3799ea326fbd3d9af77def6366f677 100644 --- a/components/settings/shared/settings-button.js +++ b/components/settings/common/settings-button.js @@ -2,7 +2,7 @@ import React from 'react' import PropTypes from 'prop-types' import { TouchableOpacity } from 'react-native' -import AppText from '../../app-text' +import AppText from '../../common/app-text' import styles from '../../../styles' const SettingsButton = ({ children, style, secondary, ...props }) => { diff --git a/components/settings/data-management/delete-data.js b/components/settings/data-management/delete-data.js index 6af5da3899699fef041615f3457cfa4628f2e338..83c70d3a3c9cd67af85c8a3ee5d45438a0a52b8d 100644 --- a/components/settings/data-management/delete-data.js +++ b/components/settings/data-management/delete-data.js @@ -3,12 +3,13 @@ import RNFS from 'react-native-fs' import { Alert, ToastAndroid } from 'react-native' import PropTypes from 'prop-types' +import Button from '../../common/button' + +import ConfirmWithPassword from '../common/confirm-with-password' +import alertError from '../common/alert-error' + import { clearDb, isDbEmpty } from '../../../db' import { hasEncryptionObservable } from '../../../local-storage' -import SettingsButton from '../shared/settings-button' -import ConfirmWithPassword from '../shared/confirm-with-password' -import alertError from '../shared/alert-error' - import settings from '../../../i18n/en/settings' import { shared as sharedLabels } from '../../../i18n/en/labels' import { EXPORT_FILE_NAME } from './constants' @@ -18,6 +19,7 @@ const exportedFilePath = `${RNFS.DocumentDirectoryPath}/${EXPORT_FILE_NAME}` export default class DeleteData extends Component { constructor() { super() + this.state = { isPasswordSet: hasEncryptionObservable.value, isConfirmingWithPassword: false @@ -92,9 +94,9 @@ export default class DeleteData extends Component { } return ( - <SettingsButton onPress={this.alertBeforeDeletion}> + <Button isCTA onPress={this.alertBeforeDeletion}> {settings.deleteSegment.title} - </SettingsButton> + </Button> ) } } diff --git a/components/settings/data-management/export-dialog.js b/components/settings/data-management/export-dialog.js index 4b47c2c52106053ac1eab911678c0d01ca8b0f9d..8200b682fdefe509a6fb5203889d9b8a996bf2a8 100644 --- a/components/settings/data-management/export-dialog.js +++ b/components/settings/data-management/export-dialog.js @@ -2,7 +2,7 @@ import Share from 'react-native-share' import { getCycleDaysSortedByDate } from '../../../db' import getDataAsCsvDataUri from '../../../lib/import-export/export-to-csv' -import alertError from '../shared/alert-error' +import alertError from '../common/alert-error' import settings from '../../../i18n/en/settings' import { EXPORT_FILE_NAME } from './constants' import RNFS from 'react-native-fs' diff --git a/components/settings/data-management/import-dialog.js b/components/settings/data-management/import-dialog.js index 23899a1fe3df0199cbf66e0454dfcec187c078ba..919752430ff86665a084766d78f8286852fdbb9c 100644 --- a/components/settings/data-management/import-dialog.js +++ b/components/settings/data-management/import-dialog.js @@ -4,7 +4,7 @@ import rnfs from 'react-native-fs' import importCsv from '../../../lib/import-export/import-from-csv' import { shared as sharedLabels } from '../../../i18n/en/labels' import labels from '../../../i18n/en/settings' -import alertError from '../shared/alert-error' +import alertError from '../common/alert-error' export function openImportDialog(onImportData) { Alert.alert( diff --git a/components/settings/data-management/index.js b/components/settings/data-management/index.js index bf32d6d1eb036ae049573821b3e3f0560d241b8e..40b81d0316ca6cac22f8a7095e6a5cc531edf9a9 100644 --- a/components/settings/data-management/index.js +++ b/components/settings/data-management/index.js @@ -1,18 +1,23 @@ import React, { Component } from 'react' -import { ScrollView, View } from 'react-native' -import AppText from '../../app-text' -import FramedSegment from '../../framed-segment' -import AppLoadingView from '../../app-loading' -import SettingsButton from '../shared/settings-button' + +import AppLoadingView from '../../common/app-loading' +import AppPage from '../../common/app-page' +import AppText from '../../common/app-text' +import Button from '../../common/button' +import Segment from '../../common/segment' + import { openImportDialog, getFileContent, importData } from './import-dialog' import openShareDialogAndExport from './export-dialog' import DeleteData from './delete-data' + import labels from '../../../i18n/en/settings' +import { ACTION_DELETE, ACTION_EXPORT, ACTION_IMPORT } from '../../../config' export default class DataManagement extends Component { constructor(props) { super(props) + this.state = { isLoading: false, currentAction: null @@ -37,12 +42,12 @@ export default class DataManagement extends Component { } startExport = () => { - this.setCurrentAction('export') + this.setCurrentAction(ACTION_EXPORT) openShareDialogAndExport() } startImport = () => { - this.setCurrentAction('import') + this.setCurrentAction(ACTION_IMPORT) openImportDialog(this.startImportFlow) } @@ -51,41 +56,36 @@ export default class DataManagement extends Component { } render() { - const { currentAction } = this.state + const { currentAction, isLoading } = this.state + const isDeletingData = currentAction === ACTION_DELETE + return ( - <View flex={1}> - {this.state.isLoading && <AppLoadingView />} - {!this.state.isLoading && - <ScrollView> - <View> - <FramedSegment title={labels.export.button}> - <AppText>{labels.export.segmentExplainer}</AppText> - <SettingsButton onPress={this.startExport}> - {labels.export.button} - </SettingsButton> - </FramedSegment> - <FramedSegment title={labels.import.button}> - <AppText>{labels.import.segmentExplainer}</AppText> - <SettingsButton - onPress= {this.startImport} - > - {labels.import.button} - </SettingsButton> - </FramedSegment> - <FramedSegment - title={labels.deleteSegment.title} - last - > - <AppText>{labels.deleteSegment.explainer}</AppText> - <DeleteData - isDeletingData = { currentAction === 'delete' } - onStartDeletion = {() => this.setCurrentAction('delete')} - /> - </FramedSegment> - </View> - </ScrollView> + <React.Fragment> + {isLoading && <AppLoadingView />} + {!isLoading && + <AppPage> + <Segment title={labels.export.button}> + <AppText>{labels.export.segmentExplainer}</AppText> + <Button isCTA onPress={this.startExport}> + {labels.export.button} + </Button> + </Segment> + <Segment title={labels.import.button}> + <AppText>{labels.import.segmentExplainer}</AppText> + <Button isCTA onPress={this.startImport}> + {labels.import.button} + </Button> + </Segment> + <Segment title={labels.deleteSegment.title} last> + <AppText>{labels.deleteSegment.explainer}</AppText> + <DeleteData + isDeletingData = {isDeletingData} + onStartDeletion = {() => this.setCurrentAction(ACTION_DELETE)} + /> + </Segment> + </AppPage> } - </View> + </React.Fragment> ) } } \ No newline at end of file diff --git a/components/settings/index.js b/components/settings/index.js index 4a8fc254bb5234c242facc810a8244a6de52cee1..f4e586143ef14ea5b63640bb5e1042f446960131 100644 --- a/components/settings/index.js +++ b/components/settings/index.js @@ -1,4 +1,4 @@ -import Reminders from './reminders' +import Reminders from './reminders/reminders' import NfpSettings from './nfp-settings' import DataManagement from './data-management' import Password from './password' diff --git a/components/settings/license.js b/components/settings/license.js index 709188272c01c3470ee442d4efdf65027f31ee6f..d3b53c9728df1a5b22c0ee4cc69cb5486e5a5c09 100644 --- a/components/settings/license.js +++ b/components/settings/license.js @@ -1,18 +1,19 @@ -import React, { Component } from 'react' -import { View, ScrollView } from 'react-native' -import AppText from '../app-text' -import styles from '../../styles/index' +import React from 'react' + +import AppPage from '../common/app-page' +import AppText from '../common/app-text' +import Segment from '../common/segment' + import labels from '../../i18n/en/settings' -export default class License extends Component { - render() { - return ( - <ScrollView> - <View style={styles.framedSegment}> - <AppText style={styles.framedSegmentTitle}>{`${labels.license.title} `}</AppText> - <AppText>{`${labels.license.text} `}</AppText> - </View> - </ScrollView> - ) - } +const License = () => { + return ( + <AppPage title={labels.license.title}> + <Segment last> + <AppText>{labels.license.text}</AppText> + </Segment> + </AppPage> + ) } + +export default License diff --git a/components/settings/menu-item.js b/components/settings/menu-item.js new file mode 100644 index 0000000000000000000000000000000000000000..8348962c38e5278cf2cc7da7ab2e3e60369bffd9 --- /dev/null +++ b/components/settings/menu-item.js @@ -0,0 +1,57 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { StyleSheet, TouchableOpacity, View } from 'react-native' + +import AppIcon from '../common/app-icon' +import AppText from '../common/app-text' +import Segment from '../common/segment' + +import { connect } from 'react-redux' +import { navigate } from '../../slices/navigation' + +import { Colors, Containers, Sizes } from '../../styles' + +const MenuItem = ({ item, last, navigate }) => { + return ( + <Segment last={last}> + <TouchableOpacity + style={styles.container} + key={item.name} + onPress={() => navigate(item.component)} + > + <View> + <AppText style={styles.title}>{item.name}</AppText> + {item.text.length > 0 && <AppText>{item.text}</AppText>} + </View> + <AppIcon name='chevron-right' color={Colors.orange}/> + </TouchableOpacity> + </Segment> + ) +} + +MenuItem.propTypes = { + item: PropTypes.object.isRequired, + last: PropTypes.bool.isRequired, + navigate: PropTypes.func.isRequired +} + +const styles = StyleSheet.create({ + container: { + ...Containers.rowContainer + }, + title: { + color: Colors.purple, + fontSize: Sizes.subtitle + } +}) + +const mapDispatchToProps = (dispatch) => { + return({ + navigate: (page) => dispatch(navigate(page)), + }) +} + +export default connect( + null, + mapDispatchToProps +)(MenuItem) \ No newline at end of file diff --git a/components/settings/nfp-settings/index.js b/components/settings/nfp-settings/index.js index 423f8e7c06046c7e8700fcd6d74089757ee834d5..378e6f4e560a45055da520e5a6a8fa368c511327 100644 --- a/components/settings/nfp-settings/index.js +++ b/components/settings/nfp-settings/index.js @@ -1,39 +1,74 @@ import React, { Component } from 'react' -import { - ScrollView, View -} from 'react-native' -import styles from '../../../styles' +import { StyleSheet, View } from 'react-native' + +import AppIcon from '../../common/app-icon' +import AppPage from '../../common/app-page' +import AppSwitch from '../../common/app-switch' +import AppText from '../../common/app-text' +import TemperatureSlider from './temperature-slider' +import Segment from '../../common/segment' + +import { useCervixObservable, saveUseCervix } from '../../../local-storage' +import { Colors, Spacing, Typography } from '../../../styles' import labels from '../../../i18n/en/settings' -import AppText from '../../app-text' -import FramedSegment from '../../framed-segment' -import TempSlider from './temp-slider' -import UseCervixSetting from './use-cervix' -import Icon from 'react-native-vector-icons/Entypo' export default class Settings extends Component { constructor(props) { super(props) - this.state = {} + + this.state = { + shouldUseCervix: useCervixObservable.value + } + } + + onCervixToggle = (value) => { + this.setState({ shouldUseCervix: value }) + saveUseCervix(value) } render() { + const { shouldUseCervix } = this.state + const cervixText = shouldUseCervix ? + labels.useCervix.cervixModeOn : labels.useCervix.cervixModeOff + return ( - <ScrollView> - <FramedSegment title={labels.useCervix.title}> - <UseCervixSetting/> - </FramedSegment> - <FramedSegment title={labels.tempScale.segmentTitle}> + <AppPage> + <Segment title={labels.useCervix.title}> + <AppSwitch + onToggle={this.onCervixToggle} + text={cervixText} + value={shouldUseCervix} + /> + </Segment> + <Segment title={labels.tempScale.segmentTitle}> <AppText>{labels.tempScale.segmentExplainer}</AppText> - <TempSlider/> - </FramedSegment> - <FramedSegment style={styles.framedSegmentLast} > - <View style={{flexDirection: 'row', alignItems: 'center'}}> - <Icon name="info-with-circle"/> - <AppText style={styles.framedSegmentTitle}>{` ${labels.preOvu.title} `}</AppText> + <TemperatureSlider /> + </Segment> + <Segment last> + <View style={styles.line}> + <AppIcon + color={Colors.purple} + name="info-with-circle" + style={styles.icon} + /> + <AppText style={styles.title}>{labels.preOvu.title}</AppText> </View> <AppText>{labels.preOvu.note}</AppText> - </FramedSegment> - </ScrollView> + </Segment> + </AppPage> ) } } + +const styles = StyleSheet.create({ + icon: { + marginRight: Spacing.base + }, + line: { + flexDirection: 'row', + alignItems: 'center' + }, + title: { + ...Typography.subtitle + } +}) diff --git a/components/settings/nfp-settings/slider-label.js b/components/settings/nfp-settings/slider-label.js new file mode 100644 index 0000000000000000000000000000000000000000..4fbda0898a00d3ba469e9ac6186876008f5cd000 --- /dev/null +++ b/components/settings/nfp-settings/slider-label.js @@ -0,0 +1,54 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { StyleSheet } from 'react-native' + +import AppText from '../../common/app-text' + +import { Fonts, Sizes } from '../../../styles' + +const sliderRadius = 5 +const width = 50 + +const getMarkerCoordinate = (position) => { + return position - width / 2 + sliderRadius +} + +const SliderLabel = ({ + oneMarkerValue, + twoMarkerValue, + oneMarkerLeftPosition, + twoMarkerLeftPosition +}) => { + const minCoordinate = getMarkerCoordinate(oneMarkerLeftPosition) + const maxCoordinate = getMarkerCoordinate(twoMarkerLeftPosition) + const isMinNumber = Number.isFinite(oneMarkerLeftPosition) && + Number.isFinite(oneMarkerValue) + const isMaxNumber = Number.isFinite(twoMarkerLeftPosition) && + Number.isFinite(twoMarkerValue) + const minStyle = [styles.label, { left: minCoordinate }] + const maxStyle = [styles.label, { left: maxCoordinate }] + + return ( + <React.Fragment> + {isMinNumber && <AppText style={minStyle}>{oneMarkerValue}</AppText>} + {isMaxNumber && <AppText style={maxStyle}>{twoMarkerValue}</AppText>} + </React.Fragment> + ) +} + +SliderLabel.propTypes = { + oneMarkerValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + twoMarkerValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + oneMarkerLeftPosition: PropTypes.number, + twoMarkerLeftPosition: PropTypes.number +} + +const styles = StyleSheet.create({ + label: { + fontFamily: Fonts.bold, + position: 'absolute', + marginTop: (-1) * Sizes.base + } +}) + +export default SliderLabel \ No newline at end of file diff --git a/components/settings/nfp-settings/temp-slider.js b/components/settings/nfp-settings/temp-slider.js deleted file mode 100644 index ecccaf472fe21a5b5b34e1440289b8af46672841..0000000000000000000000000000000000000000 --- a/components/settings/nfp-settings/temp-slider.js +++ /dev/null @@ -1,71 +0,0 @@ -import React, { Component } from 'react' -import { View } from 'react-native' -import Slider from '@ptomasroos/react-native-multi-slider' -import AppText from '../../app-text' -import { - scaleObservable, - saveTempScale, -} from '../../../local-storage' -import { secondaryColor } from '../../../styles/index' -import labels from '../../../i18n/en/settings' -import config from '../../../config' -import alertError from '../shared/alert-error' - -export default class TempSlider extends Component { - constructor(props) { - super(props) - this.state = Object.assign({}, scaleObservable.value) - } - - onValuesChange = (values) => { - this.setState({ - min: values[0], - max: values[1] - }) - } - - onValuesChangeFinish = (values) => { - this.setState({ - min: values[0], - max: values[1] - }) - try { - saveTempScale(this.state) - } catch(err) { - alertError(labels.tempScale.saveError) - } - } - - render() { - return ( - <View style={{ alignItems: 'center' }}> - <AppText>{`${labels.tempScale.min} ${this.state.min.toFixed(1)}`}</AppText> - <AppText>{`${labels.tempScale.max} ${this.state.max.toFixed(1)}`}</AppText> - <Slider - values={[this.state.min, this.state.max]} - min={config.temperatureScale.min} - max={config.temperatureScale.max} - step={0.5} - onValuesChange={this.onValuesChange} - onValuesChangeFinish={this.onValuesChangeFinish} - selectedStyle={{ - backgroundColor: 'darkgrey', - }} - unselectedStyle={{ - backgroundColor: 'silver', - }} - trackStyle={{ - height: 10, - }} - markerStyle={{ - backgroundColor: secondaryColor, - height: 20, - width: 20, - borderRadius: 100, - marginTop: 10 - }} - /> - </View> - ) - } -} \ No newline at end of file diff --git a/components/settings/nfp-settings/temperature-slider.js b/components/settings/nfp-settings/temperature-slider.js new file mode 100644 index 0000000000000000000000000000000000000000..86b9c53d66792d254e1ee2f90f1cc4e20b474e5d --- /dev/null +++ b/components/settings/nfp-settings/temperature-slider.js @@ -0,0 +1,80 @@ +import React, { Component } from 'react' +import { StyleSheet, View } from 'react-native' +import Slider from '@ptomasroos/react-native-multi-slider' + +import alertError from '../common/alert-error' +import SliderLabel from './slider-label' + +import { scaleObservable, saveTempScale } from '../../../local-storage' +import { Colors, Sizes } from '../../../styles' +import labels from '../../../i18n/en/settings' +import { TEMP_MIN, TEMP_MAX, TEMP_SLIDER_STEP } from '../../../config' + +export default class TemperatureSlider extends Component { + constructor(props) { + super(props) + + const { min, max } = scaleObservable.value + this.state = { minTemperature: min, maxTemperature: max } + } + + onTemperatureSliderChange = (values) => { + this.setState({ + minTemperature: values[0], + maxTemperature: values[1] + }) + + try { + saveTempScale({ min: values[0], max: values[1] }) + } catch(err) { + alertError(labels.tempScale.saveError) + } + } + + render() { + const { minTemperature, maxTemperature } = this.state + + return ( + <View style={styles.container}> + <Slider + customLabel={SliderLabel} + enableLabel={true} + markerStyle={styles.marker} + markerOffsetY={Sizes.tiny} + max={TEMP_MAX} + min={TEMP_MIN} + onValuesChange={this.onTemperatureSliderChange} + selectedStyle={styles.sliderAccentBackground} + step={TEMP_SLIDER_STEP} + trackStyle={styles.slider} + unselectedStyle={styles.sliderBackground} + values={[minTemperature, maxTemperature]} + /> + </View> + ) + } +} + +const styles = StyleSheet.create({ + container: { + alignItems: 'center', + paddingTop: Sizes.base + }, + marker: { + backgroundColor: Colors.turquoiseDark, + borderRadius: 50, + elevation: 4, + height: Sizes.subtitle, + width: Sizes.subtitle + }, + slider: { + borderRadius: 25, + height: Sizes.small + }, + sliderAccentBackground: { + backgroundColor: Colors.turquoiseDark + }, + sliderBackground: { + backgroundColor: Colors.turquoise + }, +}) diff --git a/components/settings/nfp-settings/use-cervix.js b/components/settings/nfp-settings/use-cervix.js deleted file mode 100644 index 2bb9ff985168d382b72b7b35e2a861e2a92672bb..0000000000000000000000000000000000000000 --- a/components/settings/nfp-settings/use-cervix.js +++ /dev/null @@ -1,39 +0,0 @@ -import React, { Component } from 'react' -import { - View, - Switch -} from 'react-native' -import AppText from '../../app-text' -import { - useCervixObservable, - saveUseCervix -} from '../../../local-storage' -import labels from '../../../i18n/en/settings' - -export default class UseCervixSetting extends Component { - constructor() { - super() - this.state = {useCervix: useCervixObservable.value} - } - - render() { - return ( - <View style={{ flexDirection: 'row', alignItems: 'center' }}> - <View style={{ flex: 1 }}> - {this.state.useCervix ? - <AppText>{labels.useCervix.cervixModeOn}</AppText> - : - <AppText>{labels.useCervix.cervixModeOff}</AppText> - } - </View> - <Switch - value={this.state.useCervix} - onValueChange={bool => { - this.setState({ useCervix: bool }) - saveUseCervix(bool) - }} - /> - </View> - ) - } -} diff --git a/components/settings/password/create.js b/components/settings/password/create.js index 9178312c81a0f32ea81a44952be8b57a18f46051..8838b30e50330cb8a180c0dde81ae6814a591647 100644 --- a/components/settings/password/create.js +++ b/components/settings/password/create.js @@ -1,16 +1,17 @@ import React, { Component } from 'react' -import { View } from 'react-native' -import settings from '../../../i18n/en/settings' + +import Button from '../../common/button' + import EnterNewPassword from './enter-new-password' -import SettingsButton from '../shared/settings-button' import showBackUpReminder from './show-backup-reminder' +import settings from '../../../i18n/en/settings' + export default class CreatePassword extends Component { constructor() { super() - this.state = { - isSettingPassword: false - } + + this.state = { isSettingPassword: false } } toggleSettingPassword = () => { @@ -23,18 +24,14 @@ export default class CreatePassword extends Component { } render () { - const { - isSettingPassword - } = this.state + const { isSettingPassword } = this.state const labels = settings.passwordSettings if (!isSettingPassword) { return ( - <View> - <SettingsButton onPress={this.startSettingPassword}> - {labels.setPassword} - </SettingsButton> - </View> + <Button isCTA onPress={this.startSettingPassword}> + {labels.setPassword} + </Button> ) } else { return <EnterNewPassword /> diff --git a/components/settings/password/delete.js b/components/settings/password/delete.js index d034a73d878e49a213c6efebf4d8dfdaa0cdf210..8f078d7f921ce72084b576be4288910122d5b3ef 100644 --- a/components/settings/password/delete.js +++ b/components/settings/password/delete.js @@ -1,17 +1,22 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import labels from '../../../i18n/en/settings' +import Button from '../../common/button' +import ConfirmWithPassword from '../common/confirm-with-password' + import { changeEncryptionAndRestartApp } from '../../../db' -import ConfirmWithPassword from '../shared/confirm-with-password' -import SettingsButton from '../shared/settings-button' +import labels from '../../../i18n/en/settings' export default class DeletePassword extends Component { + static propTypes = { + onStartDelete: PropTypes.func, + onCancelDelete: PropTypes.func + } + constructor() { super() - this.state = { - enteringCurrentPassword: false - } + + this.state = { enteringCurrentPassword: false } } startConfirmWithPassword = () => { @@ -29,7 +34,6 @@ export default class DeletePassword extends Component { } render() { - const { enteringCurrentPassword } = this.state if (enteringCurrentPassword) { @@ -42,14 +46,9 @@ export default class DeletePassword extends Component { } return ( - <SettingsButton onPress={this.startConfirmWithPassword} > + <Button isCTA onPress={this.startConfirmWithPassword}> {labels.passwordSettings.deletePassword} - </SettingsButton> + </Button> ) } -} - -DeletePassword.propTypes = { - onStartDelete: PropTypes.func, - onCancelDelete: PropTypes.func } \ No newline at end of file diff --git a/components/settings/password/enter-new-password.js b/components/settings/password/enter-new-password.js index cba3a11c731c232a756fa02c4d8f6b8b9442ed12..a351099453d814eecb3f195254deddb429bde3c7 100644 --- a/components/settings/password/enter-new-password.js +++ b/components/settings/password/enter-new-password.js @@ -1,13 +1,13 @@ import React, { Component } from 'react' -import { View } from 'react-native' +import { StyleSheet } from 'react-native' import nodejs from 'nodejs-mobile-react-native' -import { requestHash, changeEncryptionAndRestartApp } from '../../../db' -import AppText from '../../app-text' -import PasswordField from '../shared/password-field' -import SettingsButton from '../shared/settings-button' +import AppText from '../../common/app-text' +import AppTextInput from '../../common/app-text-input' +import Button from '../../common/button' -import styles from '../../../styles' +import { requestHash, changeEncryptionAndRestartApp } from '../../../db' +import { Colors, Spacing } from '../../../styles' import settings from '../../../i18n/en/settings' const LISTENER_TYPE = 'create-or-change-pw' @@ -36,9 +36,7 @@ export default class EnterNewPassword extends Component { if (this.comparePasswords()) { requestHash(LISTENER_TYPE, this.state.password) } else { - this.setState({ - shouldShowErrorMessage: true - }) + this.setState({ shouldShowErrorMessage: true }) } } @@ -58,40 +56,42 @@ export default class EnterNewPassword extends Component { const { password, passwordConfirmation, - shouldShowErrorMessage, + shouldShowErrorMessage } = this.state const labels = settings.passwordSettings - - const isSaveButtonDisabled = - !password.length || - !passwordConfirmation.length + const isButtonActive = + (password.length > 0) && (passwordConfirmation.length > 0) return ( - <View> - <PasswordField + <React.Fragment> + <AppTextInput + onChangeText={this.handlePasswordInput} placeholder={labels.enterNew} + textContentType="password" value={password} - onChangeText={this.handlePasswordInput} + secureTextEntry={true} /> - <PasswordField - autoFocus={false} + <AppTextInput + onChangeText={this.handleConfirmationInput} placeholder={labels.confirmPassword} + textContentType="password" value={passwordConfirmation} - onChangeText={this.handleConfirmationInput} + secureTextEntry={true} /> - { - shouldShowErrorMessage && - <AppText style={styles.errorMessage}> - {labels.passwordsDontMatch} - </AppText> + {shouldShowErrorMessage && + <AppText style={styles.error}>{labels.passwordsDontMatch}</AppText> } - <SettingsButton - onPress={this.savePassword} - disabled={isSaveButtonDisabled} - > + <Button isCTA={isButtonActive} onPress={this.savePassword}> {labels.savePassword} - </SettingsButton> - </View> + </Button> + </React.Fragment> ) } -} \ No newline at end of file +} + +const styles = StyleSheet.create({ + error: { + color: Colors.orange, + marginTop: Spacing.base + } +}) \ No newline at end of file diff --git a/components/settings/password/index.js b/components/settings/password/index.js index 08406a440cf38ea7dadd88ddbf32e0f6087bb1eb..5e67e5d59270e0b5acd90aaa0c0baef21fcff704 100644 --- a/components/settings/password/index.js +++ b/components/settings/password/index.js @@ -1,18 +1,20 @@ import React, { Component } from 'react' -import { ScrollView } from 'react-native' + +import AppPage from '../../common/app-page' +import AppText from '../../common/app-text' +import Segment from '../../common/segment' + import CreatePassword from './create' import ChangePassword from './update' import DeletePassword from './delete' -import FramedSegment from '../../framed-segment' -import AppText from '../../app-text' -import { - hasEncryptionObservable -} from '../../../local-storage' + +import { hasEncryptionObservable } from '../../../local-storage' import labels from '../../../i18n/en/settings' export default class PasswordSetting extends Component { constructor(props) { super(props) + this.state = { isPasswordSet: hasEncryptionObservable.value, isChangingPassword: false, @@ -51,29 +53,29 @@ export default class PasswordSetting extends Component { } = labels.passwordSettings return ( - <ScrollView> - <FramedSegment title={title}> + <AppPage> + <Segment title={title} last> <AppText> - { isPasswordSet ? explainerEnabled : explainerDisabled } + {isPasswordSet ? explainerEnabled : explainerDisabled} </AppText> - { !isPasswordSet && <CreatePassword/> } + {!isPasswordSet && <CreatePassword/>} - { (isPasswordSet && !isDeletingPassword) && ( + {(isPasswordSet && !isDeletingPassword) && ( <ChangePassword onStartChange = {this.onChangingPassword} onCancelChange = {this.onCancelChangingPassword} /> )} - { (isPasswordSet && !isChangingPassword) && ( + {(isPasswordSet && !isChangingPassword) && ( <DeletePassword onStartDelete = {this.onDeletingPassword} onCancelDelete = {this.onCancelDeletingPassword} /> )} - </FramedSegment> - </ScrollView> + </Segment> + </AppPage> ) } } diff --git a/components/settings/password/update.js b/components/settings/password/update.js index 447b9de0a208b12b1fc757c49e60a6a723ff03ad..a7112620d5362b97b619f4228588ea26936bdc94 100644 --- a/components/settings/password/update.js +++ b/components/settings/password/update.js @@ -1,16 +1,23 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import settings from '../../../i18n/en/settings' +import Button from '../../common/button' + import EnterNewPassword from './enter-new-password' -import SettingsButton from '../shared/settings-button' import showBackUpReminder from './show-backup-reminder' -import ConfirmWithPassword from '../shared/confirm-with-password' +import ConfirmWithPassword from '../common/confirm-with-password' +import settings from '../../../i18n/en/settings' export default class ChangePassword extends Component { + static propTypes = { + onStartChange: PropTypes.func, + onCancelChange: PropTypes.func + } + constructor() { super() + this.state = { currentPassword: null, enteringCurrentPassword: false, @@ -48,14 +55,13 @@ export default class ChangePassword extends Component { } render() { - const { enteringCurrentPassword, enteringNewPassword, currentPassword } = this.state - const labels = settings.passwordSettings + const isPasswordSet = currentPassword !== null if (enteringCurrentPassword) { return ( @@ -71,17 +77,13 @@ export default class ChangePassword extends Component { } return ( - <SettingsButton + <Button + disabled={isPasswordSet} + isCTA onPress={this.startChangingPassword} - disabled={currentPassword} > {labels.changePassword} - </SettingsButton> + </Button> ) } -} - -ChangePassword.propTypes = { - onStartChange: PropTypes.func, - onCancelChange: PropTypes.func } \ No newline at end of file diff --git a/components/settings/reminders/index.js b/components/settings/reminders/index.js deleted file mode 100644 index 93425af25fc90b805e2a9a540744a0a4f804a4e9..0000000000000000000000000000000000000000 --- a/components/settings/reminders/index.js +++ /dev/null @@ -1,29 +0,0 @@ -import React, { Component } from 'react' -import { - ScrollView, -} from 'react-native' -import FramedSegment from '../../framed-segment' -import TempReminderPicker from './temp-reminder-picker' -import PeriodReminderPicker from './period-reminder' - -import labels from '../../../i18n/en/settings' - -export default class Settings extends Component { - constructor(props) { - super(props) - this.state = {} - } - - render() { - return ( - <ScrollView> - <FramedSegment title={labels.tempReminder.title}> - <TempReminderPicker/> - </FramedSegment> - <FramedSegment title={labels.periodReminder.title}> - <PeriodReminderPicker/> - </FramedSegment> - </ScrollView> - ) - } -} diff --git a/components/settings/reminders/period-reminder.js b/components/settings/reminders/period-reminder.js deleted file mode 100644 index f7e177c654864ad0247706c59fe029976b9673fe..0000000000000000000000000000000000000000 --- a/components/settings/reminders/period-reminder.js +++ /dev/null @@ -1,35 +0,0 @@ -import React, { Component } from 'react' -import { - View, - Switch -} from 'react-native' -import AppText from '../../app-text' -import { - periodReminderObservable, - savePeriodReminder -} from '../../../local-storage' -import labels from '../../../i18n/en/settings' - -export default class PeriodReminderPicker extends Component { - constructor(props) { - super(props) - this.state = periodReminderObservable.value - } - - render() { - return ( - <View style={{ flexDirection: 'row', alignItems: 'center' }}> - <View style={{ flex: 1 }}> - <AppText>{labels.periodReminder.reminderText}</AppText> - </View> - <Switch - value={this.state.enabled} - onValueChange={switchOn => { - this.setState({ enabled: switchOn }) - savePeriodReminder({enabled: switchOn}) - }} - /> - </View> - ) - } -} \ No newline at end of file diff --git a/components/settings/reminders/reminders.js b/components/settings/reminders/reminders.js new file mode 100644 index 0000000000000000000000000000000000000000..ddc59302e283c3c5064b47415d94b7591c94a33c --- /dev/null +++ b/components/settings/reminders/reminders.js @@ -0,0 +1,42 @@ +import React, { Component } from 'react' + +import AppPage from '../../common/app-page' +import AppSwitch from '../../common/app-switch' +import Segment from '../../common/segment' +import TemperatureReminder from './temperature-reminder' + +import { periodReminderObservable, savePeriodReminder } from '../../../local-storage' + +import labels from '../../../i18n/en/settings' + +export default class Reminders extends Component { + constructor(props) { + super(props) + + this.state = { + isPeriodReminderEnabled: periodReminderObservable.value.enabled + } + } + + periodReminderToggle = (isEnabled) => { + this.setState({ isPeriodReminderEnabled: isEnabled }) + savePeriodReminder({ enabled: isEnabled }) + } + + render() { + return ( + <AppPage> + <Segment title={labels.tempReminder.title}> + <TemperatureReminder /> + </Segment> + <Segment title={labels.periodReminder.title} last> + <AppSwitch + onToggle={this.periodReminderToggle} + text={labels.periodReminder.reminderText} + value={this.state.isPeriodReminderEnabled} + /> + </Segment> + </AppPage> + ) + } +} diff --git a/components/settings/reminders/temp-reminder-picker.js b/components/settings/reminders/temp-reminder-picker.js deleted file mode 100644 index a481d61f392093b333bae0e4b3bb70a69ad0c9b2..0000000000000000000000000000000000000000 --- a/components/settings/reminders/temp-reminder-picker.js +++ /dev/null @@ -1,73 +0,0 @@ -import React, { Component } from 'react' -import { - View, - TouchableOpacity, - Switch -} from 'react-native' -import DateTimePicker from 'react-native-modal-datetime-picker-nevo' -import AppText from '../../app-text' -import { - tempReminderObservable, - saveTempReminder -} from '../../../local-storage' -import labels from '../../../i18n/en/settings' -import padWithZeros from '../../helpers/pad-time-with-zeros' - -export default class TempReminderPicker extends Component { - constructor(props) { - super(props) - const { time, enabled } = tempReminderObservable.value - this.state = { - time, - enabled, - isTimePickerVisible: false - } - } - - render() { - return ( - <TouchableOpacity - style={{ flexDirection: 'row', alignItems: 'center' }} - onPress={() => this.setState({ isTimePickerVisible: true })} - > - <View style={{ flex: 1 }}> - {this.state.time && this.state.enabled ? - <AppText>{labels.tempReminder.timeSet(this.state.time)}</AppText> - : - <AppText>{labels.tempReminder.noTimeSet}</AppText> - } - </View> - <Switch - value={this.state.enabled} - onValueChange={switchOn => { - this.setState({ enabled: switchOn }) - if (switchOn && !this.state.time) { - this.setState({ isTimePickerVisible: true }) - } - if (!switchOn) saveTempReminder({ enabled: false }) - }} - /> - <DateTimePicker - mode="time" - isVisible={this.state.isTimePickerVisible} - onConfirm={jsDate => { - const time = padWithZeros(jsDate) - this.setState({ - time, - isTimePickerVisible: false, - enabled: true - }) - saveTempReminder({ - time, - enabled: true - }) - }} - onCancel={() => { - this.setState({ isTimePickerVisible: false }) - if (!this.state.time) this.setState({enabled: false}) - }} - /> - </TouchableOpacity> - ) - } -} diff --git a/components/settings/reminders/temperature-reminder.js b/components/settings/reminders/temperature-reminder.js new file mode 100644 index 0000000000000000000000000000000000000000..7a7d6116a97326d615c0b6e571bd57cb0eee7825 --- /dev/null +++ b/components/settings/reminders/temperature-reminder.js @@ -0,0 +1,65 @@ +import React, { Component } from 'react' +import DateTimePicker from 'react-native-modal-datetime-picker-nevo' + +import AppSwitch from '../../common/app-switch' + +import { saveTempReminder, tempReminderObservable } from '../../../local-storage' +import padWithZeros from '../../helpers/pad-time-with-zeros' + +import labels from '../../../i18n/en/settings' + +export default class TemperatureReminder extends Component { + constructor(props) { + super(props) + + const { time, enabled } = tempReminderObservable.value + this.state = { + isEnabled: enabled, + isTimePickerVisible: false, + time, + } + } + + temperatureReminderToggle = (value) => { + if (value) { + this.setState({ isTimePickerVisible: true }) + } else { + saveTempReminder({ enabled: false }) + this.setState({ isEnabled: false }) + } + } + + onPickDate = (date) => { + const time = padWithZeros(date) + + this.setState({ isEnabled: true, isTimePickerVisible: false, time }) + saveTempReminder({ time, enabled: true }) + } + + onPickDateCancel = () => { + this.setState({ isTimePickerVisible: false }) + } + + render() { + const { isEnabled, isTimePickerVisible, time } = this.state + + const tempReminderText = time && isEnabled ? + labels.tempReminder.timeSet(time) : labels.tempReminder.noTimeSet + + return ( + <React.Fragment> + <AppSwitch + onToggle={this.temperatureReminderToggle} + text={tempReminderText} + value={isEnabled} + /> + <DateTimePicker + isVisible={isTimePickerVisible} + mode="time" + onConfirm={this.onPickDate} + onCancel={this.onPickDateCancel} + /> + </React.Fragment> + ) + } +} diff --git a/components/settings/settings-menu.js b/components/settings/settings-menu.js index f6b6bc2f115e711e2e5e901c189c773a8a51246d..4436c155ba88a1ad6ed69964e8ef36adde2f2e3b 100644 --- a/components/settings/settings-menu.js +++ b/components/settings/settings-menu.js @@ -1,58 +1,29 @@ import React from 'react' -import PropTypes from 'prop-types' -import { TouchableOpacity, ScrollView } from 'react-native' -import { connect } from 'react-redux' -import { navigate } from '../../slices/navigation' - -import styles from '../../styles/index' +import AppPage from '../common/app-page' +import MenuItem from './menu-item' import settingsLabels from '../../i18n/en/settings' -import AppText from '../app-text' - -const labels = settingsLabels.menuTitles - +const { menuItems } = settingsLabels const menu = [ - {title: labels.reminders, component: 'Reminders'}, - {title: labels.nfpSettings, component: 'NfpSettings'}, - {title: labels.dataManagement, component: 'DataManagement'}, - {title: labels.password, component: 'Password'}, - {title: labels.about, component: 'About'}, - {title: labels.license, component: 'License'} + { ...menuItems.reminders, component: 'Reminders'}, + { ...menuItems.nfpSettings, component: 'NfpSettings'}, + { ...menuItems.dataManagement, component: 'DataManagement'}, + { ...menuItems.password, component: 'Password'} ] -const SettingsMenu = ({ navigate }) => { +const SettingsMenu = () => { return ( - <ScrollView> - { menu.map(menuItem)} - </ScrollView> + <AppPage title={settingsLabels.title}> + {menu.map((menuItem, i) => { + const last = (menu.length === i + 1) + + return <MenuItem item={menuItem} key={i} last={last}/> + } + )} + </AppPage> ) - - function menuItem(item) { - return ( - <TouchableOpacity - style={styles.framedSegment} - key={item.title} - onPress={() => navigate(item.component)} - > - <AppText>{item.title.toLowerCase()}</AppText> - </TouchableOpacity> - ) - } -} - -SettingsMenu.propTypes = { - navigate: PropTypes.func.isRequired -} - -const mapDispatchToProps = (dispatch) => { - return({ - navigate: (page) => dispatch(navigate(page)), - }) } -export default connect( - null, - mapDispatchToProps -)(SettingsMenu) \ No newline at end of file +export default SettingsMenu \ No newline at end of file diff --git a/components/stats.js b/components/stats.js index 248851035ab0fa31fcead61bbf45c2bab6a7581e..1cdcf1bf6ce03ba670f1615be9f01a68bdc8c4d9 100644 --- a/components/stats.js +++ b/components/stats.js @@ -1,77 +1,117 @@ -import React, { Component } from 'react' -import { - View, - ScrollView -} from 'react-native' +import React from 'react' +import { Dimensions, ImageBackground, StyleSheet, View } from 'react-native' + +import AppPage from './common/app-page' +import AppText from './common/app-text' +import Segment from './common/segment' +import Table from './common/table' -import styles from '../styles/index' import cycleModule from '../lib/cycle' import {getCycleLengthStats as getCycleInfo} from '../lib/cycle-length' import {stats as labels} from '../i18n/en/labels' -import AppText from './app-text' -import FramedSegment from './framed-segment' -export default class Stats extends Component { - render() { - const cycleLengths = cycleModule().getAllCycleLengths() - const atLeastOneCycle = cycleLengths.length >= 1 - let numberOfCycles - let cycleInfo - if (atLeastOneCycle) { - numberOfCycles = cycleLengths.length - if (numberOfCycles > 1) { - cycleInfo = getCycleInfo(cycleLengths) - } - } - return ( - <ScrollView> - <FramedSegment - style={styles.framedSegmentLast} - title={labels.cycleLengthTitle} - > - <AppText style={styles.paragraph}> - {labels.cycleLengthExplainer} - </AppText> +import { Sizes, Spacing, Typography } from '../styles' +import { fontRatio } from '../config' - {!atLeastOneCycle && - <AppText>{labels.emptyStats}</AppText> - } - {atLeastOneCycle && numberOfCycles === 1 && - <View style={[styles.statsRow, styles.paragraph]}> - <AppText>{labels.oneCycleStats}</AppText> - <AppText style={styles.emphasis}> {cycleLengths[0]} </AppText> - <AppText>{labels.daysLabel}.</AppText> - </View> - } - {atLeastOneCycle && numberOfCycles > 1 && <View> - <View style={styles.paragraph}> - <AppText style={styles.emphasis}> - {labels.averageLabel}: {cycleInfo.mean} {labels.daysLabel} - </AppText> - </View> - <View> - <AppText> - {labels.minLabel}: {cycleInfo.minimum} {labels.daysLabel} - </AppText> - </View> - <View> - <AppText> - {labels.maxLabel}: {cycleInfo.maximum} {labels.daysLabel} - </AppText> - </View> - <View style={styles.paragraph}> - <AppText> - {labels.stdLabel}: {cycleInfo.stdDeviation} {labels.daysLabel} +const image = require('../assets/cycle-icon.png') +const screen = Dimensions.get('screen') + +const Stats = () => { + const cycleLengths = cycleModule().getAllCycleLengths() + const numberOfCycles = cycleLengths.length + const hasAtLeastOneCycle = numberOfCycles >= 1 + const cycleData = hasAtLeastOneCycle ? getCycleInfo(cycleLengths) + : { minimum: '—', maximum: '—', stdDeviation: '—' } + const statsData = [ + [cycleData.minimum, labels.minLabel], + [cycleData.maximum, labels.maxLabel], + [cycleData.stdDeviation ? cycleData.stdDeviation : '—', labels.stdLabel], + [numberOfCycles, labels.basisOfStatsEnd] + ] + const height = screen.height * 0.2 + const marginTop = (height / 8 - Sizes.icon / fontRatio) / 4 + + return ( + <AppPage contentContainerStyle={styles.pageContainer}> + <Segment last style={styles.pageContainer}> + <AppText>{labels.cycleLengthExplainer}</AppText> + {!hasAtLeastOneCycle && <AppText>{labels.emptyStats}</AppText>} + {hasAtLeastOneCycle && + <View style={styles.container}> + <View style={styles.columnLeft}> + <ImageBackground + source={image} + imageStyle={styles.image} + style={[styles.imageContainter, { height }]} + > + <AppText + numberOfLines={1} + ellipsizeMode="clip" + style={[styles.accentPurpleGiant, { marginTop }]} + > + {cycleData.mean} + </AppText> + <AppText style={styles.accentPurpleHuge}> + {labels.daysLabel} + </AppText> + </ImageBackground> + <AppText style={styles.accentOrange}> + {labels.averageLabel} </AppText> </View> - <View style={styles.statsRow}> - <AppText>{labels.basisOfStatsBeginning}</AppText> - <AppText style={styles.emphasis}> {numberOfCycles} </AppText> - <AppText>{labels.basisOfStatsEnd}</AppText> + <View style={styles.columnRight}> + <Table tableContent={statsData} /> </View> - </View>} - </FramedSegment> - </ScrollView> - ) - } + </View> + } + </Segment> + </AppPage> + ) +} + +const column = { + flexDirection: 'column', } + +const styles = StyleSheet.create({ + accentOrange: { + ...Typography.accentOrange, + fontSize: Sizes.small, + }, + accentPurpleGiant: { + ...Typography.accentPurpleGiant, + }, + accentPurpleHuge: { + ...Typography.accentPurpleHuge, + marginTop: Spacing.base * (-1), + }, + container: { + alignItems: 'center', + flexDirection: 'row', + justifyContent: 'space-between', + }, + columnLeft: { + ...column, + flex: 4, + }, + columnRight: { + ...column, + flex: 5, + paddingTop: Spacing.small, + }, + image: { + marginLeft: Spacing.large, + marginTop: Spacing.large, + resizeMode: 'contain', + + }, + imageContainter: { + paddingTop: Spacing.large * 2, + marginBottom: Spacing.large, + }, + pageContainer: { + marginVertical: Spacing.base, + } +}) + +export default Stats \ No newline at end of file diff --git a/components/views.js b/components/views.js index 1cb85454973fab0785e4c32a4d05580154bf75d6..7e325b85c7087a6287f18ccddc2c282d29c39526 100644 --- a/components/views.js +++ b/components/views.js @@ -1,7 +1,6 @@ import Home from './home' import Calendar from './calendar' import CycleDay from './cycle-day/cycle-day-overview' -import symptomViews from './cycle-day/symptoms' import Chart from './chart/chart' import SettingsMenu from './settings/settings-menu' import settingsViews from './settings' @@ -11,9 +10,9 @@ export const viewsList = { Home, Calendar, CycleDay, + TemperatureEditView: CycleDay, Chart, SettingsMenu, ...settingsViews, Stats, - ...symptomViews } diff --git a/config.js b/config.js index 0fd19c583fd0bdcee6529e02428fc5cfcb0b906e..4053b7473647bef00c8fa4dea521ec5ecf9587fb 100644 --- a/config.js +++ b/config.js @@ -1,29 +1,37 @@ -const config = { - columnWidth: 25, - xAxisHeightPercentage: 0.08, - xAxisHeightPercentageLarge: 0.12, - symptomHeightPercentage: 0.05, - symptomHeightPercentageLarge: 0.1, - temperatureScale: { - defaultLow: 35, - defaultHigh: 38, - min: 34, - max: 40, - units: 0.1, - verticalPadding: 0.03 - }, - symptoms: [ - 'bleeding', - 'mucus', - 'cervix', - 'sex', - 'desire', - 'pain', - 'mood', - 'note' - ], -} +import { PixelRatio } from 'react-native' -config.columnMiddle = config.columnWidth / 2 +export const ACTION_DELETE = 'delete' +export const ACTION_EXPORT = 'export' +export const ACTION_IMPORT = 'import' -export default config \ No newline at end of file +export const SYMPTOMS = [ + 'bleeding', + 'temperature', + 'mucus', + 'cervix', + 'sex', + 'desire', + 'pain', + 'mood', + 'note', +] + +export const fontRatio = PixelRatio.getFontScale() +export const CHART_COLUMN_WIDTH = 32 +export const CHART_COLUMN_MIDDLE = CHART_COLUMN_WIDTH / 2 +export const CHART_DOT_RADIUS = 6 +export const CHART_GRID_LINE_HORIZONTAL_WIDTH = 0.3 +export const CHART_ICON_SIZE = 20 +export const CHART_STROKE_WIDTH = 3 +export const CHART_SYMPTOM_HEIGHT_RATIO = 0.08 +export const CHART_XAXIS_HEIGHT_RATIO = 0.1 +export const CHART_YAXIS_WIDTH = 32 + +export const TEMP_SCALE_MAX = 38 +export const TEMP_SCALE_MIN = 35 +export const TEMP_SCALE_UNITS = 0.1 +export const TEMP_MAX = 40 +export const TEMP_MIN = 34 +export const TEMP_SLIDER_STEP = 0.5 + +export const HIT_SLOP = { top: 20, bottom: 20, left: 20, right: 20 } diff --git a/i18n/en/cycle-day.js b/i18n/en/cycle-day.js index 4399ca5604852e99ca5e729a727a3267071b663f..981b648d4402ffe5e3a7753976378f22e000ecb3 100644 --- a/i18n/en/cycle-day.js +++ b/i18n/en/cycle-day.js @@ -31,6 +31,7 @@ export const cervix = { categories: ['low', 'medium', 'high'], explainer: 'How high up in the vagina is the cervix?' }, + excludeExplainer: "You can exclude this value if you don't want to use it for fertility detection.", actionHint: 'Choose values for at least "Opening" and "Firmness" to save.' } @@ -132,6 +133,11 @@ export const temperature = { export const noteExplainer = "Anything you want to add for the day?" +export const general = { + cycleDayNumber: "Cycle day ", + today: "Today" +} + export const sharedDialogs = { cancel: 'Cancel', areYouSureTitle: 'Are you sure?', diff --git a/i18n/en/labels.js b/i18n/en/labels.js index 80478131d632c30096752354cb5ea5e0737245a7..c4544230a88a762f7ee9ce1394995d3843a963ce 100644 --- a/i18n/en/labels.js +++ b/i18n/en/labels.js @@ -1,5 +1,17 @@ import labels from './settings' -const settingsTitles = labels.menuTitles +const settingsTitles = labels.menuItems + +export const home = { + unknown: '?', + phase: n => `${['1st', '2nd', '3rd'][n - 1]} cycle phase`, + cycleDay: ' day of your cycle', + cyclePhase: ' cycle phase - ', + addData: 'add data for today' +} + +export const chart = { + tutorial: 'You can swipe the chart to view more dates.' +} export const shared = { cancel: 'Cancel', @@ -13,12 +25,13 @@ export const shared = { ok: 'OK', confirmToProceed: 'Confirm to proceed', date: 'Date', - cycleDayWithLinebreak: 'Cycle\nday', loading: 'Loading ...', noDataWarning: 'You haven\'t entered any data yet.', noTemperatureWarning: 'You haven\'t entered any temperature data yet.', noDataButtonText: 'Start entering data now', enter: 'Enter', + remove: 'Remove', + learnMore: 'Learn more' } export const headerTitles = { @@ -27,12 +40,12 @@ export const headerTitles = { Chart: 'Chart', Stats: 'Statistics', SettingsMenu: 'Settings', - Reminders: settingsTitles.reminders, - NfpSettings: settingsTitles.nfpSettings, - DataManagement: settingsTitles.dataManagement, - Password: settingsTitles.password, - About: settingsTitles.about, - License: settingsTitles.license, + Reminders: settingsTitles.reminders.name, + NfpSettings: settingsTitles.nfpSettings.name, + DataManagement: settingsTitles.dataManagement.name, + Password: settingsTitles.password.name, + About: 'About', + License: 'License', bleeding: 'Bleeding', temperature: 'Temperature', mucus: 'Cervical Mucus', @@ -41,39 +54,24 @@ export const headerTitles = { desire: 'Desire', sex: 'Sex', pain: 'Pain', - mood: 'Mood', - InfoSymptom: 'Info' -} - -export const menuTitles = { - Home: 'Home', - Calendar: 'Calendar', - Chart: 'Chart', - Stats: 'Stats', - Settings: 'Settings', - PasswordPrompt: 'Drip' + mood: 'Mood' } export const stats = { - cycleLengthTitle: 'Cycle length', cycleLengthExplainer: 'Basic statistics about the length of your cycles.', emptyStats: 'At least one completed cycle is needed to display stats.', - //oneCycleStats: (number) => `You have documented one cycle of ${number} days.`, - oneCycleStats: 'You have documented one cycle of', daysLabel: 'days', - //getBasisOfStats: (numberOfCycles) => `Stats are based on ${numberOfCycles} completed cycles.`, - basisOfStatsBeginning: 'Stats are based on', - basisOfStatsEnd: 'completed cycles.', - averageLabel: 'Average cycle length', - minLabel: 'Shortest cycle', - maxLabel: 'Longest cycle', - stdLabel: 'Standard deviation' + basisOfStatsEnd: 'completed\ncycles', + averageLabel: 'Average cycle', + minLabel: `Shortest`, + maxLabel: `Longest`, + stdLabel: `Standard\ndeviation` } export const bleedingPrediction = { - noPrediction: 'There is not enough period data to predict the next one.', + noPrediction: `As soon as you have tracked 3 menstrual cycles, drip will make predictions for the next ones.`, predictionInFuture: (startDays, endDays) => `Your next period is likely to start in ${startDays} to ${endDays} days.`, - predictionStartedXDaysLeft: (numberOfDays) => `Your period is likely to start today or during the next ${numberOfDays} days.`, + predictionStartedXDaysLeft: (numberOfDays) => `Your period is likely to start today or within the next ${numberOfDays} days.`, predictionStarted1DayLeft: 'Your period is likely to start today or tomorrow.', predictionStartedNoDaysLeft: 'Your period is likely to start today.', predictionInPast: (startDate, endDate) => `Based on your documented data, your period was likely to start between ${startDate} and ${endDate}.` @@ -91,29 +89,13 @@ export const passwordPrompt = { reallyDeleteData: 'Yes, I am sure' } -export const home = { - editToday: 'add data for today', - cycleDayNotEnoughInfo: "We don't have enough information to know what your current cycle day is.", - unknown: '?', - cycleDayKnown: d => `Your last period started ${getDaysDescriptor(d)}.`, - trackPeriod: 'track your period', - checkFertility: 'check your fertility', - phase: n => `${['1st', '2nd', '3rd'][n - 1]} cycle phase`, -} - -const getDaysDescriptor = cycleDayNumber => { - if (cycleDayNumber === 1) return 'today' - if (cycleDayNumber === 2) return 'yesterday' - return `${cycleDayNumber - 1} days ago` -} - export const fertilityStatus = { fertile: 'fertile', infertile: 'infertile', fertileUntilEvening: 'Fertile phase ends in the evening', unknown: 'We cannot show any cycle information because no period data has been added.', preOvuText: "With NFP rules, you may assume 5 days of infertility at the beginning of your cycle, provided you don't observe any fertile cervical mucus or cervix values.", - periOvuText: "We have not been able to detect both a temperature shift and cervical mucus or cervix shift. Please find more information on NFP rules here:", + periOvuText: "We have not been able to detect both a temperature shift and cervical mucus or cervix shift. Please find more information on NFP rules here: https://gitlab.com/bloodyhealth/drip/wikis/home", postOvuText: tempRule => { return ( 'We have detected a temperature shift (' + ['regular', '1st exception', '2nd exception'][tempRule] + diff --git a/i18n/en/links.js b/i18n/en/links.js index c677b28654d1fb80428a962a15851f1134026501..c738749390c11c3f14211e4584ddf46587b5dbfd 100644 --- a/i18n/en/links.js +++ b/i18n/en/links.js @@ -17,5 +17,25 @@ export default { donate: { url: 'https://ko-fi.com/dripapp', text: 'here' - } + }, + smashicons: { + url: 'https://smashicons.com/', + text: 'Smashicons', + }, + pause08: { + url: 'https://www.flaticon.com/authors/pause08', + text: 'Pause08', + }, + kazachek: { + url: 'https://www.flaticon.com/authors/kirill-kazachek', + text: 'Kirill Kazachek', + }, + freepik: { + url: 'https://www.flaticon.com/authors/freepik', + text: 'Freepik', + }, + flaticon: { + url: 'https://www.flaticon.com', + text: 'Flaticon', + }, } diff --git a/i18n/en/settings.js b/i18n/en/settings.js index 36f63dee44df4d4128db7fcbf55f0add7fddd055..cc63775d8da04511c6cb6a00ef2914dfb9d0024d 100644 --- a/i18n/en/settings.js +++ b/i18n/en/settings.js @@ -3,13 +3,27 @@ import links from './links' const currentYear = new Date().getFullYear() export default { - menuTitles: { - reminders: 'Reminders', - dataManagement: 'Manage your data', - nfpSettings: 'NFP settings', - password: 'Password', + title: 'Settings', + menuItems: { + reminders: { + name: 'Reminders', + text: 'turn on/off reminders' + }, + nfpSettings: { + name:'NFP settings', + text: 'define how you want to use NFP', + }, + dataManagement: { + name: 'Data', + text: 'import, export or delete your data' + }, + password: { + name:'Password', + text: '' + }, about: 'About', - license: 'License' + license: 'License', + settings: 'Settings' }, export: { errors: { @@ -124,7 +138,7 @@ You can contact us by bloodyhealth@mailbox.org.` }, credits: { title: 'Credits', - note: 'Thanks and lots of <3 to all of our contributors as well as Susanne Umscheid for the wonderful design, and Paula Härtel for the symptom icons.' + note: `We love the drip team. Thanks and lots of <3 to all of our condriputors. Thanks to Paula Härtel for the symptom tracking icons. All the other icons are made by ${links.smashicons.url}, ${links.pause08.url}, ${links.kazachek.url} & ${links.freepik.url} from ${links.flaticon.url}.` }, donate: { title: 'Buy us a coffee!', diff --git a/ic_launcher-web.png b/ic_launcher-web.png new file mode 100755 index 0000000000000000000000000000000000000000..7889d1452c5a1724055e7784b42ece8e4db06d7c Binary files /dev/null and b/ic_launcher-web.png differ diff --git a/ios/drip/Info.plist b/ios/drip/Info.plist index 8df975a133c77bcaaebd21d0be3dc7b1d3ba0ae1..790ce8a563a238e2c0da35655eb745a9e22342d0 100644 --- a/ios/drip/Info.plist +++ b/ios/drip/Info.plist @@ -24,22 +24,6 @@ <string>1</string> <key>LSRequiresIPhoneOS</key> <true/> - <key>UILaunchStoryboardName</key> - <string>LaunchScreen</string> - <key>UIRequiredDeviceCapabilities</key> - <array> - <string>armv7</string> - </array> - <key>UISupportedInterfaceOrientations</key> - <array> - <string>UIInterfaceOrientationPortrait</string> - <string>UIInterfaceOrientationLandscapeLeft</string> - <string>UIInterfaceOrientationLandscapeRight</string> - </array> - <key>UIViewControllerBasedStatusBarAppearance</key> - <false/> - <key>NSLocationWhenInUseUsageDescription</key> - <string/> <key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> @@ -51,6 +35,8 @@ </dict> </dict> </dict> + <key>NSLocationWhenInUseUsageDescription</key> + <string></string> <key>UIAppFonts</key> <array> <string>Entypo.ttf</string> @@ -89,5 +75,18 @@ <string>AntDesign.ttf</string> <string>OpenSans-LightItalic.ttf</string> </array> + <key>UILaunchStoryboardName</key> + <string>LaunchScreen</string> + <key>UIRequiredDeviceCapabilities</key> + <array> + <string>armv7</string> + </array> + <key>UISupportedInterfaceOrientations</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + <string>UIInterfaceOrientationPortraitUpsideDown</string> + </array> + <key>UIViewControllerBasedStatusBarAppearance</key> + <false/> </dict> </plist> diff --git a/lib/notifications.js b/lib/notifications.js index 1692484ad1f7fd6e0c4167270c147cde58fa159c..f58a7671cca1f99b61e57ddbbd2e09356686afb8 100644 --- a/lib/notifications.js +++ b/lib/notifications.js @@ -1,6 +1,5 @@ import {tempReminderObservable, periodReminderObservable} from '../local-storage' import Notification from 'react-native-push-notification' -import { LocalDate } from 'js-joda' import Moment from 'moment' import labels from '../i18n/en/settings' import { getBleedingDaysSortedByDate } from '../db' @@ -11,7 +10,7 @@ export default function setupNotifications(navigate) { Notification.configure({ onNotification: (notification) => { if (notification.id === '1') { - navigate('TemperatureEditView', { date: LocalDate.now().toString() }) + navigate('TemperatureEditView') } else { navigate('Home') } diff --git a/local-storage.js b/local-storage.js index 4cc9c75d4f2614b3da5da81c4becf120d8fb42a9..b23ac6f53eae33d4739bbb7bd16f1fd1905827a6 100644 --- a/local-storage.js +++ b/local-storage.js @@ -1,18 +1,16 @@ import { AsyncStorage } from 'react-native' import Observable from 'obv' -import config from './config' +import { TEMP_SCALE_MIN, TEMP_SCALE_MAX, TEMP_SCALE_UNITS } from './config' export const scaleObservable = Observable() -setObvWithInitValue('tempScale', scaleObservable, { - min: config.temperatureScale.defaultLow, - max: config.temperatureScale.defaultHigh -}) +setObvWithInitValue('tempScale', + scaleObservable, { min: TEMP_SCALE_MIN, max: TEMP_SCALE_MAX }) export const unitObservable = Observable() -unitObservable.set(config.temperatureScale.units) +unitObservable.set(TEMP_SCALE_UNITS) scaleObservable((scale) => { const scaleRange = scale.max - scale.min - if (scaleRange <= 3) { + if (scaleRange <= 2) { unitObservable.set(0.1) } else { unitObservable.set(0.5) @@ -69,6 +67,15 @@ export async function saveLicenseFlag() { await AsyncStorage.setItem('agreedToLicense', JSON.stringify(true)) } +export async function getChartFlag() { + const isFirstChartView = await AsyncStorage.getItem('isFirstChartView') + return isFirstChartView === null ? 'true' : isFirstChartView +} + +export async function setChartFlag() { + await AsyncStorage.setItem('isFirstChartView', JSON.stringify(false)) +} + async function setObvWithInitValue(key, obv, defaultValue) { const result = await AsyncStorage.getItem(key) let value diff --git a/package-lock.json b/package-lock.json index 401667e2e5c338bf0c5e6ae700c1b1d3f427791e..88bd9994a4953faf5ae1378ee6cb1f11b047eac1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,128 +5,36 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "requires": { - "@babel/highlight": "^7.0.0" + "@babel/highlight": "^7.10.4" } }, "@babel/core": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.2.tgz", - "integrity": "sha512-eeD7VEZKfhK1KUXGiyPFettgF3m513f8FoBSWiQ1xTvl1RAopLs42Wp9+Ze911I6H0N9lNqJMDgoZT7gHsipeQ==", - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.2", - "@babel/helpers": "^7.7.0", - "@babel/parser": "^7.7.2", - "@babel/template": "^7.7.0", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.7.2", + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.4.tgz", + "integrity": "sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.4", + "@babel/helper-module-transforms": "^7.11.0", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.11.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.11.0", + "@babel/types": "^7.11.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.13", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" }, "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/generator": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.2.tgz", - "integrity": "sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ==", - "requires": { - "@babel/types": "^7.7.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", - "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", - "requires": { - "@babel/helper-get-function-arity": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", - "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", - "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==" - }, - "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/traverse": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.2.tgz", - "integrity": "sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw==", - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.2", - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0", - "@babel/parser": "^7.7.2", - "@babel/types": "^7.7.2", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "requires": { - "safe-buffer": "~5.1.1" - } - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -135,11 +43,6 @@ "ms": "^2.1.1" } }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -153,1684 +56,597 @@ } }, "@babel/generator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", - "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.4.tgz", + "integrity": "sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==", "requires": { - "@babel/types": "^7.4.4", + "@babel/types": "^7.11.0", "jsesc": "^2.5.1", - "lodash": "^4.17.11", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" + "source-map": "^0.5.0" } }, "@babel/helper-annotate-as-pure": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.0.tgz", - "integrity": "sha512-k50CQxMlYTYo+GGyUGFwpxKVtxVJi9yh61sXZji3zYHccK9RYliZGSTOgci85T+r+0VFN2nWbGM04PIqwfrpMg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", + "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", "requires": { - "@babel/types": "^7.7.0" - }, - "dependencies": { - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "@babel/types": "^7.10.4" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.0.tgz", - "integrity": "sha512-Cd8r8zs4RKDwMG/92lpZcnn5WPQ3LAMQbCw42oqUh4s7vsSN5ANUZjMel0OOnxDLq57hoDDbai+ryygYfCTOsw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz", + "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==", "requires": { - "@babel/helper-explode-assignable-expression": "^7.7.0", - "@babel/types": "^7.7.0" - }, - "dependencies": { - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "@babel/helper-explode-assignable-expression": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/helper-builder-react-jsx": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.7.0.tgz", - "integrity": "sha512-LSln3cexwInTMYYoFeVLKnYPPMfWNJ8PubTBs3hkh7wCu9iBaqq1OOyW+xGmEdLxT1nhsl+9SJ+h2oUDYz0l2A==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.4.tgz", + "integrity": "sha512-5nPcIZ7+KKDxT1427oBivl9V9YTal7qk0diccnh7RrcgrT/pGFOjgGw1dgryyx1GvHEpXVfoDF6Ak3rTiWh8Rg==", "requires": { - "@babel/types": "^7.7.0", - "esutils": "^2.0.0" - }, - "dependencies": { - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/types": "^7.10.4" } }, - "@babel/helper-call-delegate": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.7.0.tgz", - "integrity": "sha512-Su0Mdq7uSSWGZayGMMQ+z6lnL00mMCnGAbO/R0ZO9odIdB/WNU/VfQKqMQU0fdIsxQYbRjDM4BixIa93SQIpvw==", + "@babel/helper-builder-react-jsx-experimental": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.5.tgz", + "integrity": "sha512-Buewnx6M4ttG+NLkKyt7baQn7ScC/Td+e99G914fRU8fGIUivDDgVIQeDHFa5e4CRSJQt58WpNHhsAZgtzVhsg==", "requires": { - "@babel/helper-hoist-variables": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/generator": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.2.tgz", - "integrity": "sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ==", - "requires": { - "@babel/types": "^7.7.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", - "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", - "requires": { - "@babel/helper-get-function-arity": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", - "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", - "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==" - }, - "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/traverse": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.2.tgz", - "integrity": "sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw==", - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.2", - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0", - "@babel/parser": "^7.7.2", - "@babel/types": "^7.7.2", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-module-imports": "^7.10.4", + "@babel/types": "^7.10.5" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.7.0.tgz", - "integrity": "sha512-MZiB5qvTWoyiFOgootmRSDV1udjIqJW/8lmxgzKq6oDqxdmHUjeP2ZUOmgHdYjmUVNABqRrHjYAYRvj8Eox/UA==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz", + "integrity": "sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A==", "requires": { - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-member-expression-to-functions": "^7.7.0", - "@babel/helper-optimise-call-expression": "^7.7.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0" - }, - "dependencies": { - "@babel/helper-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", - "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", - "requires": { - "@babel/helper-get-function-arity": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", - "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", - "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==" - }, - "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-member-expression-to-functions": "^7.10.5", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.2.tgz", - "integrity": "sha512-pAil/ZixjTlrzNpjx+l/C/wJk002Wo7XbbZ8oujH/AoJ3Juv0iN/UTcPUHXKMFLqsfS0Hy6Aow8M31brUYBlQQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz", + "integrity": "sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g==", "requires": { - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.6.0" + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-regex": "^7.10.4", + "regexpu-core": "^4.7.0" } }, "@babel/helper-define-map": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.7.0.tgz", - "integrity": "sha512-kPKWPb0dMpZi+ov1hJiwse9dWweZsz3V9rP4KdytnX1E7z3cTNmFGglwklzFPuqIcHLIY3bgKSs4vkwXXdflQA==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz", + "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==", "requires": { - "@babel/helper-function-name": "^7.7.0", - "@babel/types": "^7.7.0", - "lodash": "^4.17.13" - }, - "dependencies": { - "@babel/helper-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", - "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", - "requires": { - "@babel/helper-get-function-arity": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", - "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==" - }, - "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "@babel/helper-function-name": "^7.10.4", + "@babel/types": "^7.10.5", + "lodash": "^4.17.19" } }, "@babel/helper-explode-assignable-expression": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.0.tgz", - "integrity": "sha512-CDs26w2shdD1urNUAji2RJXyBFCaR+iBEGnFz3l7maizMkQe3saVw9WtjG1tz8CwbjvlFnaSLVhgnu1SWaherg==", + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz", + "integrity": "sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ==", "requires": { - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/generator": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.2.tgz", - "integrity": "sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ==", - "requires": { - "@babel/types": "^7.7.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", - "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", - "requires": { - "@babel/helper-get-function-arity": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", - "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", - "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==" - }, - "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/traverse": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.2.tgz", - "integrity": "sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw==", - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.2", - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0", - "@babel/parser": "^7.7.2", - "@babel/types": "^7.7.2", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } + "@babel/types": "^7.10.4" } }, "@babel/helper-function-name": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", - "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", "requires": { - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/helper-get-function-arity": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", - "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.0.tgz", - "integrity": "sha512-LUe/92NqsDAkJjjCEWkNe+/PcpnisvnqdlRe19FahVapa4jndeuJ+FBiTX1rcAKWKcJGE+C3Q3tuEuxkSmCEiQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", "requires": { - "@babel/types": "^7.7.0" - }, - "dependencies": { - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "@babel/types": "^7.10.4" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.0.tgz", - "integrity": "sha512-QaCZLO2RtBcmvO/ekOLp8p7R5X2JriKRizeDpm5ChATAFWrrYDcDxPuCIBXKyBjY+i1vYSdcUTMIb8psfxHDPA==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", + "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", "requires": { - "@babel/types": "^7.7.0" - }, - "dependencies": { - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "@babel/types": "^7.11.0" } }, "@babel/helper-module-imports": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.7.0.tgz", - "integrity": "sha512-Dv3hLKIC1jyfTkClvyEkYP2OlkzNvWs5+Q8WgPbxM5LMeorons7iPP91JM+DU7tRbhqA1ZeooPaMFvQrn23RHw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", "requires": { - "@babel/types": "^7.7.0" - }, - "dependencies": { - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "@babel/types": "^7.10.4" } }, "@babel/helper-module-transforms": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.0.tgz", - "integrity": "sha512-rXEefBuheUYQyX4WjV19tuknrJFwyKw0HgzRwbkyTbB+Dshlq7eqkWbyjzToLrMZk/5wKVKdWFluiAsVkHXvuQ==", - "requires": { - "@babel/helper-module-imports": "^7.7.0", - "@babel/helper-simple-access": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0", - "lodash": "^4.17.13" - }, - "dependencies": { - "@babel/helper-split-export-declaration": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", - "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==" - }, - "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", + "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/template": "^7.10.4", + "@babel/types": "^7.11.0", + "lodash": "^4.17.19" } }, "@babel/helper-optimise-call-expression": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.0.tgz", - "integrity": "sha512-48TeqmbazjNU/65niiiJIJRc5JozB8acui1OS7bSd6PgxfuovWsvjfWSzlgx+gPFdVveNzUdpdIg5l56Pl5jqg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", "requires": { - "@babel/types": "^7.7.0" - }, - "dependencies": { - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "@babel/types": "^7.10.4" } }, "@babel/helper-plugin-utils": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==" + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" }, "@babel/helper-regex": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz", - "integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.5.tgz", + "integrity": "sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg==", "requires": { - "lodash": "^4.17.13" - }, - "dependencies": { - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "lodash": "^4.17.19" } }, "@babel/helper-remap-async-to-generator": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.0.tgz", - "integrity": "sha512-pHx7RN8X0UNHPB/fnuDnRXVZ316ZigkO8y8D835JlZ2SSdFKb6yH9MIYRU4fy/KPe5sPHDFOPvf8QLdbAGGiyw==", + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.11.4.tgz", + "integrity": "sha512-tR5vJ/vBa9wFy3m5LLv2faapJLnDFxNWff2SAYkSE4rLUdbp7CdObYFgI7wK4T/Mj4UzpjPwzR8Pzmr5m7MHGA==", "requires": { - "@babel/helper-annotate-as-pure": "^7.7.0", - "@babel/helper-wrap-function": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0" - }, - "dependencies": { - "@babel/generator": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.2.tgz", - "integrity": "sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ==", - "requires": { - "@babel/types": "^7.7.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", - "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", - "requires": { - "@babel/helper-get-function-arity": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", - "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", - "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==" - }, - "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/traverse": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.2.tgz", - "integrity": "sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw==", - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.2", - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0", - "@babel/parser": "^7.7.2", - "@babel/types": "^7.7.2", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "requires": { - "@babel/highlight": "^7.0.0" - } - } - } - }, - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-wrap-function": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/helper-replace-supers": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.7.0.tgz", - "integrity": "sha512-5ALYEul5V8xNdxEeWvRsBzLMxQksT7MaStpxjJf9KsnLxpAKBtfw5NeMKZJSYDa0lKdOcy0g+JT/f5mPSulUgg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", + "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", "requires": { - "@babel/helper-member-expression-to-functions": "^7.7.0", - "@babel/helper-optimise-call-expression": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/generator": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.2.tgz", - "integrity": "sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ==", - "requires": { - "@babel/types": "^7.7.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", - "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", - "requires": { - "@babel/helper-get-function-arity": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", - "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", - "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==" - }, - "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/traverse": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.2.tgz", - "integrity": "sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw==", - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.2", - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0", - "@babel/parser": "^7.7.2", - "@babel/types": "^7.7.2", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/helper-simple-access": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.7.0.tgz", - "integrity": "sha512-AJ7IZD7Eem3zZRuj5JtzFAptBw7pMlS3y8Qv09vaBWoFsle0d1kAn5Wq6Q9MyBXITPOKnxwkZKoAm4bopmv26g==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", + "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", "requires": { - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" - }, - "dependencies": { - "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==" - }, - "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz", + "integrity": "sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q==", + "requires": { + "@babel/types": "^7.11.0" } }, "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", "requires": { - "@babel/types": "^7.4.4" + "@babel/types": "^7.11.0" } }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" + }, "@babel/helper-wrap-function": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.7.0.tgz", - "integrity": "sha512-sd4QjeMgQqzshSjecZjOp8uKfUtnpmCyQhKQrVJBBgeHAB/0FPi33h3AbVlVp07qQtMD4QgYSzaMI7VwncNK/w==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz", + "integrity": "sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug==", "requires": { - "@babel/helper-function-name": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0" - }, - "dependencies": { - "@babel/generator": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.2.tgz", - "integrity": "sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ==", - "requires": { - "@babel/types": "^7.7.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", - "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", - "requires": { - "@babel/helper-get-function-arity": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", - "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", - "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==" - }, - "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/traverse": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.2.tgz", - "integrity": "sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw==", - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.2", - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0", - "@babel/parser": "^7.7.2", - "@babel/types": "^7.7.2", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "requires": { - "@babel/highlight": "^7.0.0" - } - } - } - }, - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } + "@babel/helper-function-name": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/helpers": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.0.tgz", - "integrity": "sha512-VnNwL4YOhbejHb7x/b5F39Zdg5vIQpUUNzJwx0ww1EcVRt41bbGRZWhAURrfY32T5zTT3qwNOQFWpn+P0i0a2g==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", + "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", "requires": { - "@babel/template": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0" - }, - "dependencies": { - "@babel/generator": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.2.tgz", - "integrity": "sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ==", - "requires": { - "@babel/types": "^7.7.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", - "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", - "requires": { - "@babel/helper-get-function-arity": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", - "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", - "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==" - }, - "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/traverse": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.2.tgz", - "integrity": "sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw==", - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.2", - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0", - "@babel/parser": "^7.7.2", - "@babel/types": "^7.7.2", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "requires": { - "@babel/highlight": "^7.0.0" - } - } - } - }, - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "requires": { + "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", - "esutils": "^2.0.2", "js-tokens": "^4.0.0" - }, - "dependencies": { - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } } }, "@babel/parser": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.4.tgz", - "integrity": "sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w==" + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", + "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==" }, "@babel/plugin-external-helpers": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-external-helpers/-/plugin-external-helpers-7.2.0.tgz", - "integrity": "sha512-QFmtcCShFkyAsNtdCM3lJPmRe1iB+vPZymlB4LnDIKEBj2yKQLQKtoxXxJ8ePT5fwMl4QGg303p4mB0UsSI2/g==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-external-helpers/-/plugin-external-helpers-7.10.4.tgz", + "integrity": "sha512-5mASqSthmRNYVXOphYzlqmR3Y8yp5SZMZhtKDh2DGV3R2PWGLEmP7qOahw66//6m4hjhlpV1bVM7xIJHt1F77Q==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.7.0.tgz", - "integrity": "sha512-tufDcFA1Vj+eWvwHN+jvMN6QsV5o+vUlytNKrbMiCeDL0F2j92RURzUsUMWE5EJkLyWxjdUslCsMQa9FWth16A==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz", + "integrity": "sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.7.0", - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-create-class-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-proposal-export-default-from": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.5.2.tgz", - "integrity": "sha512-wr9Itk05L1/wyyZKVEmXWCdcsp/e185WUNl6AfYZeEKYaUPPvHXRDqO5K1VH7/UamYqGJowFRuCv30aDYZawsg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.10.4.tgz", + "integrity": "sha512-G1l00VvDZ7Yk2yRlC5D8Ybvu3gmeHS3rCHoUYdjrqGYUtdeOBoRypnvDZ5KQqxyaiiGHWnVDeSEzA5F9ozItig==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-export-default-from": "^7.2.0" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-export-default-from": "^7.10.4" } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.4.4.tgz", - "integrity": "sha512-Amph7Epui1Dh/xxUxS2+K22/MUi6+6JVTvy3P58tja3B6yKTSjwwx0/d83rF7551D6PVSSoplQb8GCwqec7HRw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz", + "integrity": "sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.2.0" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz", - "integrity": "sha512-LDBXlmADCsMZV1Y9OQwMc0MyGZ8Ta/zlD9N67BfQT8uYwkRswiu2hU6nJKrjrt/58aH/vqfQlR/9yId/7A2gWw==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz", + "integrity": "sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.10.4" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz", + "integrity": "sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.6.0.tgz", - "integrity": "sha512-kj4gkZ6qUggkprRq3Uh5KP8XnE1MdIO0J7MhdDX8+rAbB6dJ2UrensGIS+0NPZAaaJ1Vr0PN6oLUgXMU1uMcSg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz", + "integrity": "sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-optional-chaining": "^7.2.0" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" } }, "@babel/plugin-syntax-class-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.2.0.tgz", - "integrity": "sha512-UxYaGXYQ7rrKJS/PxIKRkv3exi05oH7rokBAsmCSsCxz1sVPZ7Fu6FzKoGgUvmY+0YgSkYHgUoCh5R5bCNBQlw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", + "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-dynamic-import": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", - "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/plugin-syntax-export-default-from": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.2.0.tgz", - "integrity": "sha512-c7nqUnNST97BWPtoe+Ssi+fJukc9P9/JMZ71IOMNQWza2E+Psrd46N6AEvtw6pqK+gt7ChjXyrw4SPDO79f3Lw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.10.4.tgz", + "integrity": "sha512-79V6r6Pgudz0RnuMGp5xidu6Z+bPFugh8/Q9eDHonmLp4wKFAZDwygJwYgCzuDu8lFA/sYyT+mc5y2wkd7bTXA==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-flow": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.7.0.tgz", - "integrity": "sha512-vQMV07p+L+jZeUnvX3pEJ9EiXGCjB5CTTvsirFD9rpEuATnoAvLBLoYbw1v5tyn3d2XxSuvEKi8cV3KqYUa0vQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.10.4.tgz", + "integrity": "sha512-yxQsX1dJixF4qEEdzVbst3SZQ58Nrooz8NV9Z9GL4byTE25BvJgl5lf0RECUf0fh28rZBb/RYTWn/eeKwCMrZQ==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-jsx": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz", - "integrity": "sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz", + "integrity": "sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.2.0.tgz", - "integrity": "sha512-lRCEaKE+LTxDQtgbYajI04ddt6WW0WJq57xqkAZ+s11h4YgfRHhVA/Y2VhfPzzFD4qeLHWg32DMp9HooY4Kqlg==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/plugin-syntax-object-rest-spread": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", - "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/plugin-syntax-optional-chaining": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.2.0.tgz", - "integrity": "sha512-HtGCtvp5Uq/jH/WNUPkK6b7rufnCPLLlDAFN7cmACoIjaOOiXxUt3SswU5loHqrhtqTsa/WoLQ1OQ1AGuZqaWA==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/plugin-syntax-typescript": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.3.3.tgz", - "integrity": "sha512-dGwbSMA1YhVS8+31CnPR7LB4pcbrzcV99wQzby4uAfrkZPYZlQ7ImwdpzLqi6Z6IL02b8IAL379CaMwo0x5Lag==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.10.4.tgz", + "integrity": "sha512-oSAEz1YkBCAKr5Yiq8/BNtvSAPwkp/IyUnwZogd8p+F0RuYQQrLeRUzIQhueQTTBy/F+a40uS7OFKxnkRvmvFQ==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", - "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz", + "integrity": "sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.0.tgz", - "integrity": "sha512-vLI2EFLVvRBL3d8roAMqtVY0Bm9C1QzLkdS57hiKrjUBSqsQYrBsMCeOg/0KK7B0eK9V71J5mWcha9yyoI2tZw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz", + "integrity": "sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ==", "requires": { - "@babel/helper-module-imports": "^7.7.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.7.0" + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-remap-async-to-generator": "^7.10.4" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", - "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz", + "integrity": "sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.3.tgz", - "integrity": "sha512-7hvrg75dubcO3ZI2rjYTzUrEuh1E9IyDEhhB6qfcooxhDA33xx2MasuLVgdxzcP6R/lipAC6n9ub9maNW6RKdw==", + "version": "7.11.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz", + "integrity": "sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "lodash": "^4.17.13" - }, - "dependencies": { - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-classes": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.0.tgz", - "integrity": "sha512-/b3cKIZwGeUesZheU9jNYcwrEA7f/Bo4IdPmvp7oHgvks2majB5BoT5byAql44fiNQYOPzhk2w8DbgfuafkMoA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.7.0", - "@babel/helper-define-map": "^7.7.0", - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-optimise-call-expression": "^7.7.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz", + "integrity": "sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-define-map": "^7.10.4", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", "globals": "^11.1.0" - }, - "dependencies": { - "@babel/helper-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", - "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", - "requires": { - "@babel/helper-get-function-arity": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", - "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", - "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==" - }, - "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } } }, "@babel/plugin-transform-computed-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", - "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz", + "integrity": "sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-destructuring": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz", - "integrity": "sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz", + "integrity": "sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", - "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz", + "integrity": "sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw==", "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-flow-strip-types": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.6.3.tgz", - "integrity": "sha512-l0ETkyEofkqFJ9LS6HChNIKtVJw2ylKbhYMlJ5C6df+ldxxaLIyXY4yOdDQQspfFpV8/vDiaWoJlvflstlYNxg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.10.4.tgz", + "integrity": "sha512-XTadyuqNst88UWBTdLjM+wEY7BFnY2sYtPyAidfC7M/QaZnSuIZpMvLxqGT7phAcnGyWh/XQFLKcGf04CnvxSQ==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-flow": "^7.2.0" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-flow": "^7.10.4" } }, "@babel/plugin-transform-for-of": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", - "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz", + "integrity": "sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.0.tgz", - "integrity": "sha512-P5HKu0d9+CzZxP5jcrWdpe7ZlFDe24bmqP6a6X8BHEBl/eizAsY8K6LX8LASZL0Jxdjm5eEfzp+FIrxCm/p8bA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz", + "integrity": "sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg==", "requires": { - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-plugin-utils": "^7.0.0" - }, - "dependencies": { - "@babel/helper-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", - "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", - "requires": { - "@babel/helper-get-function-arity": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", - "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==" - }, - "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", - "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz", + "integrity": "sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz", - "integrity": "sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz", + "integrity": "sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.0.tgz", - "integrity": "sha512-KEMyWNNWnjOom8vR/1+d+Ocz/mILZG/eyHHO06OuBQ2aNhxT62fr4y6fGOplRx+CxCSp3IFwesL8WdINfY/3kg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz", + "integrity": "sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==", "requires": { - "@babel/helper-module-transforms": "^7.7.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.7.0", - "babel-plugin-dynamic-import-node": "^2.3.0" + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-object-assign": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.2.0.tgz", - "integrity": "sha512-nmE55cZBPFgUktbF2OuoZgPRadfxosLOpSgzEPYotKSls9J4pEPcembi8r78RU37Rph6UApCpNmsQA4QMWK9Ng==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.10.4.tgz", + "integrity": "sha512-6zccDhYEICfMeQqIjuY5G09/yhKzG30DKHJeYBQUHIsJH7c2jXSGvgwRalufLAXAq432OSlsEfAOLlzEsQzxVw==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-object-super": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz", - "integrity": "sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz", + "integrity": "sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.5.5" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4" } }, "@babel/plugin-transform-parameters": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", - "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz", + "integrity": "sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw==", "requires": { - "@babel/helper-call-delegate": "^7.4.4", - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-property-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz", - "integrity": "sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz", + "integrity": "sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-react-display-name": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz", - "integrity": "sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.4.tgz", + "integrity": "sha512-Zd4X54Mu9SBfPGnEcaGcOrVAYOtjT2on8QZkLKEq1S/tHexG39d9XXGZv19VfRrDjPJzFmPfTAqOQS1pfFOujw==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-react-jsx": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.0.tgz", - "integrity": "sha512-mXhBtyVB1Ujfy+0L6934jeJcSXj/VCg6whZzEcgiiZHNS0PGC7vUCsZDQCxxztkpIdF+dY1fUMcjAgEOC3ZOMQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.4.tgz", + "integrity": "sha512-L+MfRhWjX0eI7Js093MM6MacKU4M6dnCRa/QPDwYMxjljzSCzzlzKzj9Pk4P3OtrPcxr2N3znR419nr3Xw+65A==", "requires": { - "@babel/helper-builder-react-jsx": "^7.7.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0" + "@babel/helper-builder-react-jsx": "^7.10.4", + "@babel/helper-builder-react-jsx-experimental": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-jsx": "^7.10.4" } }, "@babel/plugin-transform-react-jsx-source": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.5.0.tgz", - "integrity": "sha512-58Q+Jsy4IDCZx7kqEZuSDdam/1oW8OdDX8f+Loo6xyxdfg1yF0GE2XNJQSTZCaMol93+FBzpWiPEwtbMloAcPg==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.5.tgz", + "integrity": "sha512-wTeqHVkN1lfPLubRiZH3o73f4rfon42HpgxUSs86Nc+8QIcm/B9s8NNVXu/gwGcOyd7yDib9ikxoDLxJP0UiDA==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-jsx": "^7.10.4" } }, "@babel/plugin-transform-regenerator": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.0.tgz", - "integrity": "sha512-AXmvnC+0wuj/cFkkS/HFHIojxH3ffSXE+ttulrqWjZZRaUOonfJc60e1wSNT4rV8tIunvu/R3wCp71/tLAa9xg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz", + "integrity": "sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw==", "requires": { - "regenerator-transform": "^0.14.0" + "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-runtime": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.2.tgz", - "integrity": "sha512-cqULw/QB4yl73cS5Y0TZlQSjDvNkzDbu0FurTZyHlJpWE5T3PCMdnyV+xXoH1opr1ldyHODe3QAX3OMAii5NxA==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.11.0.tgz", + "integrity": "sha512-LFEsP+t3wkYBlis8w6/kmnd6Kb1dxTd+wGJ8MlxTGzQo//ehtqlVL4S9DNUa53+dtPSQobN2CXx4d81FqC58cw==", "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", "resolve": "^1.8.1", "semver": "^5.5.1" }, @@ -1843,117 +659,110 @@ } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", - "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz", + "integrity": "sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-spread": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.6.2.tgz", - "integrity": "sha512-DpSvPFryKdK1x+EDJYCy28nmAaIMdxmhot62jAXF/o99iA33Zj2Lmcp3vDmz+MUh0LNYVPvfj5iC3feb3/+PFg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz", + "integrity": "sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", - "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz", + "integrity": "sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.0.0" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-regex": "^7.10.4" } }, "@babel/plugin-transform-template-literals": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", - "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz", + "integrity": "sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw==", "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-typescript": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.7.2.tgz", - "integrity": "sha512-UWhDaJRqdPUtdK1s0sKYdoRuqK0NepjZto2UZltvuCgMoMZmdjhgz5hcRokie/3aYEaSz3xvusyoayVaq4PjRg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.11.0.tgz", + "integrity": "sha512-edJsNzTtvb3MaXQwj8403B7mZoGu9ElDJQZOKjGUnvilquxBA3IQoEIOvkX/1O8xfAsnHS/oQhe2w/IXrr+w0w==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.7.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-typescript": "^7.2.0" + "@babel/helper-create-class-features-plugin": "^7.10.5", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-typescript": "^7.10.4" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.0.tgz", - "integrity": "sha512-RrThb0gdrNwFAqEAAx9OWgtx6ICK69x7i9tCnMdVrxQwSDp/Abu9DXFU5Hh16VP33Rmxh04+NGW28NsIkFvFKA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz", + "integrity": "sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.0", - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/register": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.4.4.tgz", - "integrity": "sha512-sn51H88GRa00+ZoMqCVgOphmswG4b7mhf9VOB0LUBAieykq2GnRFerlN+JQkO/ntT7wz4jaHNSRPg9IdMPEUkA==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.10.5.tgz", + "integrity": "sha512-eYHdLv43nyvmPn9bfNfrcC4+iYNwdQ8Pxk1MFJuU/U5LpSYl/PH4dFMazCYZDFVi8ueG3shvO+AQfLrxpYulQw==", "requires": { - "core-js": "^3.0.0", "find-cache-dir": "^2.0.0", - "lodash": "^4.17.11", - "mkdirp": "^0.5.1", + "lodash": "^4.17.19", + "make-dir": "^2.1.0", "pirates": "^4.0.0", - "source-map-support": "^0.5.9" - }, - "dependencies": { - "core-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.0.1.tgz", - "integrity": "sha512-sco40rF+2KlE0ROMvydjkrVMMG1vYilP2ALoRXcYR4obqbYIuV3Bg+51GEDW+HF8n7NRA+iaA4qD0nD9lo9mew==" - } + "source-map-support": "^0.5.16" } }, "@babel/runtime": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.2.tgz", - "integrity": "sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw==", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", + "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", "requires": { - "regenerator-runtime": "^0.13.2" + "regenerator-runtime": "^0.13.4" }, "dependencies": { "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" } } }, "@babel/template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", - "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4" + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/traverse": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.4.tgz", - "integrity": "sha512-Gw6qqkw/e6AGzlyj9KnkabJX7VcubqPtkUQVAwkc0wUMldr3A/hezNB3Rc5eIvId95iSGkGIOe5hh1kMKf951A==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.4", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", + "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.0", + "@babel/types": "^7.11.0", "debug": "^4.1.0", "globals": "^11.1.0", - "lodash": "^4.17.11" + "lodash": "^4.17.19" }, "dependencies": { "debug": { @@ -1965,19 +774,19 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "@babel/types": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", - "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.11", + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } }, @@ -2029,9 +838,9 @@ }, "dependencies": { "@cnakazawa/watch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz", - "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", "dev": true, "requires": { "exec-sh": "^0.3.2", @@ -2331,9 +1140,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "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 }, "merge-stream": { @@ -2363,12 +1172,6 @@ "to-regex": "^3.0.2" } }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "rsvp": { "version": "4.8.5", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", @@ -2465,9 +1268,9 @@ }, "dependencies": { "@cnakazawa/watch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz", - "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", "dev": true, "requires": { "exec-sh": "^0.3.2", @@ -2761,9 +1564,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "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 }, "merge-stream": { @@ -2793,12 +1596,6 @@ "to-regex": "^3.0.2" } }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "rsvp": { "version": "4.8.5", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", @@ -2888,9 +1685,9 @@ }, "dependencies": { "@cnakazawa/watch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz", - "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", "dev": true, "requires": { "exec-sh": "^0.3.2", @@ -3184,9 +1981,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "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 }, "merge-stream": { @@ -3216,12 +2013,6 @@ "to-regex": "^3.0.2" } }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "rsvp": { "version": "4.8.5", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", @@ -3281,9 +2072,9 @@ }, "dependencies": { "@cnakazawa/watch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz", - "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", "dev": true, "requires": { "exec-sh": "^0.3.2", @@ -3577,9 +2368,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "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 }, "merge-stream": { @@ -3609,12 +2400,6 @@ "to-regex": "^3.0.2" } }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "rsvp": { "version": "4.8.5", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", @@ -3678,14 +2463,14 @@ } }, "@ptomasroos/react-native-multi-slider": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@ptomasroos/react-native-multi-slider/-/react-native-multi-slider-1.0.0.tgz", - "integrity": "sha512-NpX22rQLArg9widwMzGf7XsInTDf6mfY/D1XaDVjglNkVphj3NSN37+nF6MofArCxC++1P+jHv0SGWbmJQwy4g==" + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@ptomasroos/react-native-multi-slider/-/react-native-multi-slider-2.2.2.tgz", + "integrity": "sha512-HWyCnRD3Z3SbHK2FLWYmBBqd1B4iXipeKv1+AK0FoY/CElEDTEixHE8hN60TsqxalPrznn798LE2Q4tHuCiyaA==" }, "@react-native-community/cli": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-1.11.2.tgz", - "integrity": "sha512-5NuYd30f5PCTrGUbZLnusZKv5nfTWvTDTRa/3Q4vwdMnUQrhm9sZXWGQ5CnFoQ7cE58EAqhj6/ShXeJF3DZ9uQ==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-1.12.0.tgz", + "integrity": "sha512-GAs4JgVP8QkEYeZks/T7cCrBuwFJKxd9ksBLRdQ058uvLGkOEeS4g3y4GsVM/9C1zat5h6Z6QwU0h/hj7G3tzg==", "requires": { "chalk": "^1.1.1", "commander": "^2.19.0", @@ -3728,11 +2513,6 @@ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" }, - "big-integer": { - "version": "1.6.48", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", - "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==" - }, "bplist-creator": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz", @@ -3771,11 +2551,6 @@ "universalify": "^0.1.0" } }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, "plist": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", @@ -3797,9 +2572,9 @@ } }, "xcode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xcode/-/xcode-2.0.0.tgz", - "integrity": "sha512-5xF6RCjAdDEiEsbbZaS/gBRt3jZ/177otZcpoLCjGN/u1LrfgH7/Sgeeavpr/jELpyDqN2im3AKosl2G2W8hfw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/xcode/-/xcode-2.1.0.tgz", + "integrity": "sha512-uCrmPITrqTEzhn0TtT57fJaNaw8YJs1aCzs+P/QqxsDbvPZSv7XMPPwXrKvHtD6pLjBM/NaVwraWJm8q83Y4iQ==", "requires": { "simple-plist": "^1.0.0", "uuid": "^3.3.2" @@ -3813,17 +2588,17 @@ } }, "@react-native-community/push-notification-ios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@react-native-community/push-notification-ios/-/push-notification-ios-1.4.0.tgz", - "integrity": "sha512-YnfxtAuHkiuvprh1d9npGZVwOrso6sys8+w8XY6RQAs8kD2LHZg0C8rA5gfX4jW/GrQV7m14Y6ngciE6Rpd91w==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@react-native-community/push-notification-ios/-/push-notification-ios-1.4.1.tgz", + "integrity": "sha512-Y+4LS10R+yc17wu54tlDcxgW/SugEAz2dNjmil9I7KUtaZIOc0hTvAE8dUvYTEDvYQ9uYrXI+OqdElTE3FJ3FA==", "requires": { "invariant": "^2.2.4" } }, "@types/babel__core": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz", - "integrity": "sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA==", + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", + "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -3834,9 +2609,9 @@ } }, "@types/babel__generator": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.0.tgz", - "integrity": "sha512-c1mZUu4up5cp9KROs/QAw0gTeHrw/x7m52LcnvMxxOZ03DmLwPV0MlGmlgzV3cnSdjhJOZsj7E7FHeioai+egw==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", "dev": true, "requires": { "@babel/types": "^7.0.0" @@ -3853,33 +2628,33 @@ } }, "@types/babel__traverse": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.7.tgz", - "integrity": "sha512-CeBpmX1J8kWLcDEnI3Cl2Eo6RfbGvzUctA+CjZUhOKDFbLfcr7fc4usEqLNWetrlJd7RhAkyYe2czXop4fICpw==", + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.13.tgz", + "integrity": "sha512-i+zS7t6/s9cdQvbqKDARrcbrPvtJGlbYsMkazo03nTAK3RX9FNrLllXys22uiTGJapPOTZTQ35nHh4ISph4SLQ==", "dev": true, "requires": { "@babel/types": "^7.3.0" } }, "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", "dev": true }, "@types/istanbul-lib-report": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz", - "integrity": "sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "*" } }, "@types/istanbul-reports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", - "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "*", @@ -3887,9 +2662,9 @@ } }, "@types/node": { - "version": "14.0.27", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz", - "integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==", + "version": "14.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.0.tgz", + "integrity": "sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA==", "dev": true }, "@types/stack-utils": { @@ -3925,24 +2700,24 @@ } }, "@types/yargs": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.3.tgz", - "integrity": "sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ==", + "version": "13.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.10.tgz", + "integrity": "sha512-MU10TSgzNABgdzKvQVW1nuuT+sgBMWeXNc3XOs5YXV5SDAK+PPja2eUuBNB9iqElu03xyEDqlnGw0jgl4nbqGQ==", "dev": true, "requires": { "@types/yargs-parser": "*" } }, "@types/yargs-parser": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-13.1.0.tgz", - "integrity": "sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", "dev": true }, "abab": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.2.tgz", - "integrity": "sha512-2scffjvioEmNz0OyDSLGWDfKCVwaKc6l9Pm9kOIREU13ClXZvHpg/nRL5xyjSSSLhOnXqft2HpsAzNEEA8cFFg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.4.tgz", + "integrity": "sha512-Eu9ELJWCz/c1e9gTiCY+FceWxcqzjYEbqMgtndnuSqZSUCOL73TWNK2mHfIj4Cw2E/ongOp+JISVNCmovt2KYQ==", "dev": true }, "abbrev": { @@ -3965,9 +2740,9 @@ } }, "acorn": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "dev": true }, "acorn-globals": { @@ -3981,9 +2756,9 @@ } }, "acorn-jsx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", - "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", "dev": true }, "acorn-walk": { @@ -4296,9 +3071,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" }, "micromatch": { "version": "3.1.10", @@ -4382,13 +3157,14 @@ "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=" }, "array-includes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", - "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.7.0" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" } }, "array-map": { @@ -4411,6 +3187,17 @@ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" }, + "array.prototype.flatmap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.3.tgz", + "integrity": "sha512-OOEk+lkePcg+ODXIpvuU9PAryCikCJyo7GlDG1upleEpQRx6mzL9puEBkozQ5iAx20KV0l3DbyQwqciJtqe5Pg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1" + } + }, "art": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/art/-/art-0.10.3.tgz", @@ -4430,10 +3217,11 @@ } }, "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", "requires": { + "object-assign": "^4.1.1", "util": "0.10.3" } }, @@ -4465,19 +3253,12 @@ "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "requires": { "lodash": "^4.17.14" - }, - "dependencies": { - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } } }, "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, "asynckit": { "version": "0.4.0", @@ -4495,22 +3276,22 @@ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz", + "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==" }, "babel-eslint": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.1.tgz", - "integrity": "sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", + "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "eslint-scope": "3.7.1", - "eslint-visitor-keys": "^1.0.0" + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" } }, "babel-jest": { @@ -4529,9 +3310,9 @@ } }, "babel-plugin-dynamic-import-node": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", - "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", "requires": { "object.assign": "^4.1.0" } @@ -4568,9 +3349,9 @@ } }, "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -4711,9 +3492,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" } } }, @@ -4762,6 +3543,15 @@ "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==" }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "bl": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", @@ -4772,9 +3562,9 @@ } }, "bluebird": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz", - "integrity": "sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==" + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "bplist-creator": { "version": "0.0.7", @@ -4812,9 +3602,9 @@ } }, "browser-process-hrtime": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", - "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", "dev": true }, "browser-resolve": { @@ -4887,13 +3677,13 @@ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, "bunyan": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", - "integrity": "sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=", + "version": "1.8.14", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.14.tgz", + "integrity": "sha512-LlahJUxXzZLuw/hetUQJmRgZ1LF6+cr5TPpRj6jf327AsiIq2jhYEH4oqUUkVKTor+9w2BT3oxVwhzE5lw9tcg==", "dev": true, "requires": { "dtrace-provider": "~0.8", - "moment": "^2.10.6", + "moment": "^2.19.3", "mv": "~2", "safe-json-stringify": "~1" } @@ -5075,9 +3865,9 @@ } }, "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "ci-info": { "version": "2.0.0", @@ -5115,9 +3905,9 @@ } }, "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==" }, "cliui": { "version": "3.2.0", @@ -5173,15 +3963,15 @@ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" }, "colors": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", - "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", "dev": true }, "combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "requires": { "delayed-stream": "~1.0.0" } @@ -5197,9 +3987,9 @@ } }, "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "common-tags": { "version": "1.8.0", @@ -5218,11 +4008,11 @@ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "compressible": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", - "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "requires": { - "mime-db": ">= 1.40.0 < 2" + "mime-db": ">= 1.43.0 < 2" } }, "compression": { @@ -5256,9 +4046,9 @@ }, "dependencies": { "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" } } }, @@ -5289,10 +4079,9 @@ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "dev": true, + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "requires": { "safe-buffer": "~5.1.1" } @@ -5303,9 +4092,9 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, "core-js": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" }, "core-util-is": { "version": "1.0.2", @@ -5333,6 +4122,11 @@ "object-assign": "^4.1.1" }, "dependencies": { + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + }, "fbjs": { "version": "0.8.17", "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", @@ -5350,13 +4144,22 @@ } }, "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "requires": { - "lru-cache": "^4.0.1", + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } } }, "cssom": { @@ -5375,9 +4178,9 @@ } }, "csvtojson": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/csvtojson/-/csvtojson-2.0.8.tgz", - "integrity": "sha512-DC6YFtsJiA7t/Yz+KjzT6GXuKtU/5gRbbl7HJqvDVVir+dxdw2/1EgwfgJdnsvUT7lOnON5DvGftKuYWX1nMOQ==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/csvtojson/-/csvtojson-2.0.10.tgz", + "integrity": "sha512-lUWFxGKyhraKCW8Qghz6Z0f2l/PqB1W3AO0HKJzGIQ5JRSlR651ekJDiGJbBT4sRNNv5ddnSGVEnsxP9XRCVpQ==", "requires": { "bluebird": "^3.5.1", "lodash": "^4.17.3", @@ -5606,9 +4409,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" } } }, @@ -5628,9 +4431,9 @@ "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=" }, "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, "deprecated-react-native-listview": { "version": "0.0.6", @@ -5649,9 +4452,9 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", "dev": true }, "detect-libc": { @@ -5666,9 +4469,9 @@ "dev": true }, "detox": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/detox/-/detox-13.1.1.tgz", - "integrity": "sha512-dDtV64wMryeHk/+Np339Gm5uEzjxFySUHxLmz9iMsDFgkPn+XDkBdPZtb76pRQwJnpSWlbKVP1zhcN9B6vfsJg==", + "version": "13.3.3", + "resolved": "https://registry.npmjs.org/detox/-/detox-13.3.3.tgz", + "integrity": "sha512-Rphzj8sMcx0ScRCVuRFA9SJcj5nn32SJkkG4PvpsrH862iiX4cSCBBvuy0MfOq49IF5kGkEwoNTuYxXZq6Jvqw==", "dev": true, "requires": { "@babel/core": "^7.4.5", @@ -5693,86 +4496,6 @@ "yargs-parser": "^13.0.0" }, "dependencies": { - "@babel/core": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.4.tgz", - "integrity": "sha512-+DaeBEpYq6b2+ZmHx3tHspC+ZRflrvLqwfv8E3hNr5LVQoyBnL8RPKSBCg+rK2W2My9PWlujBiqd0ZPsR9Q6zQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.5.0", - "@babel/helpers": "^7.5.4", - "@babel/parser": "^7.5.0", - "@babel/template": "^7.4.4", - "@babel/traverse": "^7.5.0", - "@babel/types": "^7.5.0", - "convert-source-map": "^1.1.0", - "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.11", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - } - }, - "@babel/generator": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.0.tgz", - "integrity": "sha512-1TTVrt7J9rcG5PMjvO7VEG3FrEoEJNHxumRq66GemPmzboLWtIjjcJgk8rokuAS7IiRSpgVSu5Vb9lc99iJkOA==", - "dev": true, - "requires": { - "@babel/types": "^7.5.0", - "jsesc": "^2.5.1", - "lodash": "^4.17.11", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - } - }, - "@babel/helpers": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.5.4.tgz", - "integrity": "sha512-6LJ6xwUEJP51w0sIgKyfvFMJvIb9mWAfohJp0+m6eHJigkFdcH8duZ1sfhn0ltJRzwUIT/yqqhdSfRpCpL7oow==", - "dev": true, - "requires": { - "@babel/template": "^7.4.4", - "@babel/traverse": "^7.5.0", - "@babel/types": "^7.5.0" - } - }, - "@babel/parser": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.0.tgz", - "integrity": "sha512-I5nW8AhGpOXGCCNYGc+p7ExQIBxRFnS2fd/d862bNOKvmoEPjYPcfIjsfdy0ujagYOIYPczKgD9l3FsgTkAzKA==", - "dev": true - }, - "@babel/traverse": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.0.tgz", - "integrity": "sha512-SnA9aLbyOCcnnbQEGwdfBggnc142h/rbqqsXcaATj2hZcegCl903pUD/lfpsNBlBSuWow/YDfRyJuWi2EPR5cg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.5.0", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.5.0", - "@babel/types": "^7.5.0", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.11" - } - }, - "@babel/types": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.0.tgz", - "integrity": "sha512-UFpDVqRABKsW01bvw7/wSUe56uy6RXM5+VJibVVAybDGxEW25jdwiFJEf7ASvSaC7sN7rbE/l3cLp2izav+CtQ==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.11", - "to-fast-properties": "^2.0.0" - } - }, "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", @@ -5794,17 +4517,6 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -5816,14 +4528,11 @@ "wrap-ansi": "^5.1.0" } }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true }, "find-up": { "version": "3.0.0", @@ -5857,15 +4566,6 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -5876,22 +4576,10 @@ "path-exists": "^3.0.0" } }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -5918,12 +4606,6 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true - }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -5944,15 +4626,6 @@ "ansi-regex": "^4.1.0" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", @@ -5988,9 +4661,9 @@ "dev": true }, "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", @@ -6002,13 +4675,13 @@ "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" + "yargs-parser": "^13.1.2" } }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -6045,9 +4718,9 @@ } }, "dom-walk": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", - "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" }, "domexception": { "version": "1.0.1", @@ -6059,19 +4732,19 @@ } }, "dottie": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.1.tgz", - "integrity": "sha512-ch5OQgvGDK2u8pSZeSYAQaV/lczImd7pMJ7BcEPXmnFVjy4yJIzP6CsODJUTH8mg1tyH1Z2abOiuJO3DjZ/GBw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz", + "integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg==", "dev": true }, "dtrace-provider": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.7.tgz", - "integrity": "sha1-3JObTT4GIM/gwc2APQ0tftBP/QQ=", + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", + "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", "dev": true, "optional": true, "requires": { - "nan": "^2.10.0" + "nan": "^2.14.0" } }, "ecc-jsbn": { @@ -6095,26 +4768,10 @@ "sigmund": "^1.0.1" }, "dependencies": { - "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, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -6135,17 +4792,27 @@ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "requires": { - "iconv-lite": "~0.4.13" + "iconv-lite": "^0.6.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } } }, "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "requires": { "once": "^1.4.0" } @@ -6173,23 +4840,28 @@ } }, "es-abstract": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", - "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", "dev": true, "requires": { - "es-to-primitive": "^1.2.0", + "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-keys": "^1.0.12" + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" } }, "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "requires": { "is-callable": "^1.1.4", @@ -6221,24 +4893,18 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "escodegen": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", - "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", "dev": true, "requires": { - "esprima": "^3.1.3", + "esprima": "^4.0.1", "estraverse": "^4.2.0", "esutils": "^2.0.2", "optionator": "^0.8.1", "source-map": "~0.6.1" }, "dependencies": { - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -6293,12 +4959,12 @@ }, "dependencies": { "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "version": "6.12.4", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", + "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", + "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" @@ -6310,45 +4976,12 @@ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -6358,20 +4991,10 @@ "ms": "^2.1.1" } }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, "external-editor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", - "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, "requires": { "chardet": "^0.7.0", @@ -6380,15 +5003,15 @@ } }, "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "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 }, "import-fresh": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", - "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -6396,9 +5019,9 @@ } }, "inquirer": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz", - "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", "dev": true, "requires": { "ansi-escapes": "^3.2.0", @@ -6407,7 +5030,7 @@ "cli-width": "^2.0.0", "external-editor": "^3.0.3", "figures": "^2.0.0", - "lodash": "^4.17.11", + "lodash": "^4.17.12", "mute-stream": "0.0.7", "run-async": "^2.2.0", "rxjs": "^6.4.0", @@ -6446,9 +5069,9 @@ "dev": true }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "resolve-from": { @@ -6458,9 +5081,9 @@ "dev": true }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "string-width": { @@ -6481,31 +5104,26 @@ "requires": { "ansi-regex": "^3.0.0" } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, "eslint-plugin-react": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.13.0.tgz", - "integrity": "sha512-uA5LrHylu8lW/eAH3bEQe9YdzpPaFd9yAJTwTi/i/BKTD7j6aQMKVAdGM/ML72zD6womuSK7EiGtMKuK06lWjQ==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.6.tgz", + "integrity": "sha512-kidMTE5HAEBSLu23CUDvj8dc3LdBU0ri1scwHBZjI41oDv4tjsWZKU7MQccFzH1QYPYhsnTF2ovh7JlcIcmxgg==", "dev": true, "requires": { - "array-includes": "^3.0.3", + "array-includes": "^3.1.1", + "array.prototype.flatmap": "^1.2.3", "doctrine": "^2.1.0", "has": "^1.0.3", - "jsx-ast-utils": "^2.1.0", - "object.fromentries": "^2.0.0", + "jsx-ast-utils": "^2.4.1", + "object.entries": "^1.1.2", + "object.fromentries": "^2.0.2", + "object.values": "^1.1.1", "prop-types": "^15.7.2", - "resolve": "^1.10.1" + "resolve": "^1.17.0", + "string.prototype.matchall": "^4.0.2" }, "dependencies": { "doctrine": { @@ -6520,9 +5138,9 @@ } }, "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -6530,15 +5148,18 @@ } }, "eslint-utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", - "dev": true + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } }, "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true }, "espree": { @@ -6558,12 +5179,20 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", "dev": true, "requires": { - "estraverse": "^4.0.0" + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "esrecurse": { @@ -6576,15 +5205,16 @@ } }, "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true }, "etag": { "version": "1.8.1", @@ -6630,25 +5260,6 @@ "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" - } } }, "exit": { @@ -6767,9 +5378,9 @@ "integrity": "sha512-4WKW0AL5+WEqO0zWavAfYGY1qwLsBgE//DN4TTcVEN2UlINgkv9b3vm2iHicoenWKSX9mKWmGOsU/iI5IST7pQ==" }, "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + "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==" }, "fast-levenshtein": { "version": "2.0.6", @@ -6778,11 +5389,11 @@ "dev": true }, "fb-watchman": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", - "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", "requires": { - "bser": "^2.0.0" + "bser": "2.1.1" } }, "fbjs": { @@ -6798,13 +5409,6 @@ "promise": "^7.1.1", "setimmediate": "^1.0.5", "ua-parser-js": "^0.7.18" - }, - "dependencies": { - "core-js": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", - "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==" - } } }, "fbjs-css-vars": { @@ -6829,10 +5433,15 @@ "through2": "^2.0.0" }, "dependencies": { - "core-js": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", - "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==" + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } } } }, @@ -6866,6 +5475,12 @@ "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" }, + "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==", + "optional": true + }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", @@ -6936,572 +5551,131 @@ } } }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "^2.0.0" - } - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - } - }, - "flatted": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", - "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", - "dev": true - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "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==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "fs-extra": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", - "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "requires": { - "graceful-fs": "^4.1.6" - } - } - } - }, - "fs-minipass": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", - "optional": true, - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "bundled": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.12.0", - "bundled": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "bundled": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "bundled": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "optional": true, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" + "glob": "^7.1.3" } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "optional": true, + } + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "requires": { + "for-in": "^1.0.1" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "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==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "fs-extra": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0" + }, + "dependencies": { + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "requires": { - "string-width": "^1.0.2 || 2" + "graceful-fs": "^4.1.6" } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true } } }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -7534,6 +5708,11 @@ "wide-align": "^1.1.0" } }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==" + }, "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", @@ -7600,9 +5779,9 @@ } }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -7644,14 +5823,9 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" }, "growl": { "version": "1.10.5", @@ -7664,73 +5838,35 @@ "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" }, - "handlebars": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.1.tgz", - "integrity": "sha512-C29UoFzHe9yM61lOsIlCE5/mQVGrnIOrOq7maQl76L7tYPCgC1og0Ajt6uWnX4ZTxBPnjw+CUvawphwCfJgUnA==", - "dev": true, - "requires": { - "neo-async": "^2.6.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "optional": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "uglify-js": { - "version": "3.6.8", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.8.tgz", - "integrity": "sha512-XhHJ3S3ZyMwP8kY1Gkugqx3CJh2C3O0y8NPiSxtm1tyD/pktLAkFZsFGpuNfTZddKDQ/bbDBLAd2YyA1pbi8HQ==", - "dev": true, - "optional": true, - "requires": { - "commander": "~2.20.3", - "source-map": "~0.6.1" - } - } - } - }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "requires": { - "ajv": "^6.5.5", + "ajv": "^6.12.3", "har-schema": "^2.0.0" }, "dependencies": { "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "version": "6.12.4", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", + "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", "requires": { - "fast-deep-equal": "^2.0.1", + "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + "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==" }, "json-schema-traverse": { "version": "0.4.1", @@ -7762,9 +5898,9 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" }, "has-unicode": { "version": "2.0.1", @@ -7825,17 +5961,17 @@ "dev": true }, "hoist-non-react-statics": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz", - "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", "requires": { "react-is": "^16.7.0" } }, "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==" + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" }, "html-encoding-sniffer": { "version": "1.0.2", @@ -7846,6 +5982,12 @@ "whatwg-encoding": "^1.0.1" } }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, "http-basic": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-2.5.1.tgz", @@ -7875,6 +6017,11 @@ "toidentifier": "1.0.0" }, "dependencies": { + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -7966,6 +6113,11 @@ "resolved": "https://registry.npmjs.org/immer/-/immer-2.1.5.tgz", "integrity": "sha512-xyjQyTBYIeiz6jd02Hg12jV+9QISwF1crLcwTlzHpWH4e0ryNWj1kacpTwimK3bJV5NKKXw458G2vpqoB/inFA==" }, + "immutable": { + "version": "4.0.0-rc.12", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0-rc.12.tgz", + "integrity": "sha512-0M2XxkZLx/mi3t8NVwIm1g8nHoEmM9p9UBl/G9k4+hm0kBgOVdMV/B3CY5dQ8qG8qc80NN4gDV4HQv6FTJ5q7A==" + }, "import-fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", @@ -8059,6 +6211,17 @@ } } }, + "internal-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", + "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "has": "^1.0.3", + "side-channel": "^1.0.2" + } + }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -8113,9 +6276,9 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, "is-ci": { @@ -8136,9 +6299,9 @@ } }, "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", "dev": true }, "is-decimal": { @@ -8257,18 +6420,13 @@ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" - }, "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", "dev": true, "requires": { - "has": "^1.0.1" + "has-symbols": "^1.0.1" } }, "is-stream": { @@ -8276,13 +6434,19 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", "dev": true, "requires": { - "has-symbols": "^1.0.0" + "has-symbols": "^1.0.1" } }, "is-typedarray": { @@ -8445,12 +6609,12 @@ } }, "istanbul-reports": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", - "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", "dev": true, "requires": { - "handlebars": "^4.1.2" + "html-escaper": "^2.0.0" } }, "jase": { @@ -8461,14 +6625,6 @@ "requires": { "core-util-is": "^1.0.1", "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } } }, "jest": { @@ -8513,6 +6669,12 @@ "wrap-ansi": "^5.1.0" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -8566,9 +6728,9 @@ } }, "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -8633,9 +6795,9 @@ "dev": true }, "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", @@ -8647,13 +6809,13 @@ "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" + "yargs-parser": "^13.1.2" } }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -8955,9 +7117,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "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 }, "micromatch": { @@ -9525,9 +7687,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "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 }, "micromatch": { @@ -9563,9 +7725,9 @@ } }, "jest-pnp-resolver": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", - "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", "dev": true }, "jest-regex-util": { @@ -9626,9 +7788,9 @@ }, "dependencies": { "@cnakazawa/watch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz", - "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", "dev": true, "requires": { "exec-sh": "^0.3.2", @@ -9922,9 +8084,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "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 }, "merge-stream": { @@ -9954,12 +8116,6 @@ "to-regex": "^3.0.2" } }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "rsvp": { "version": "4.8.5", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", @@ -10026,9 +8182,9 @@ }, "dependencies": { "@cnakazawa/watch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz", - "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", "dev": true, "requires": { "exec-sh": "^0.3.2", @@ -10117,6 +8273,12 @@ "wrap-ansi": "^5.1.0" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "exec-sh": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", @@ -10375,9 +8537,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "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 }, "locate-path": { @@ -10417,16 +8579,10 @@ "to-regex": "^3.0.2" } }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -10529,9 +8685,9 @@ "dev": true }, "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", @@ -10543,13 +8699,13 @@ "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" + "yargs-parser": "^13.1.2" } }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -10732,53 +8888,44 @@ "dev": true }, "js-base64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz", - "integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==" + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" }, "js-beautify": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.9.1.tgz", - "integrity": "sha512-oxxvVZdOdUfzk8IOLBF2XUZvl2GoBEfA+b0of4u2EBY/46NlXasi8JdFvazA5lCrf9/lQhTjyVy2QCUW7iq0MQ==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.13.0.tgz", + "integrity": "sha512-/Tbp1OVzZjbwzwJQFIlYLm9eWQ+3aYbBXLSaqb1mEJzhcQAfrqMMQYtjb6io+U6KpD0ID4F+Id3/xcjH3l/sqA==", "dev": true, "requires": { "config-chain": "^1.1.12", - "editorconfig": "^0.15.2", + "editorconfig": "^0.15.3", "glob": "^7.1.3", - "mkdirp": "~0.5.0", - "nopt": "~4.0.1" + "mkdirp": "^1.0.4", + "nopt": "^5.0.0" }, "dependencies": { - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true }, "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", "dev": true, "requires": { - "abbrev": "1", - "osenv": "^0.1.4" + "abbrev": "1" } } } }, "js-joda": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/js-joda/-/js-joda-1.10.1.tgz", - "integrity": "sha512-lDBKliZf2oLX4h1EjzkhBulpQRv51A9x2nhX1XnP1PD0LU7a30I7CKtAWZ//5c+Z6aWG8TO996vVr+4owE9vWA==" + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/js-joda/-/js-joda-1.11.0.tgz", + "integrity": "sha512-/HJpRhwP2fPyuSsCaZuoVJuaSIt8tUXykV4wOMRXrFk7RP9h9VWaFdS9YHKdMepxb/3TdXpL6IhfC9L0sqYVBw==" }, "js-tokens": { "version": "4.0.0", @@ -10786,9 +8933,9 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -10834,9 +8981,9 @@ }, "dependencies": { "acorn": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", "dev": true }, "sax": { @@ -10896,18 +9043,11 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } + "minimist": "^1.2.5" } }, "jsonfile": { @@ -10935,12 +9075,13 @@ } }, "jsx-ast-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.1.0.tgz", - "integrity": "sha512-yDGDG2DS4JcqhA6blsuYbtsT09xL8AoLuUR2Gb5exrw7UEM19sBcOTq+YBBhrNbl0PUC4R4LnFu+dHg2HKeVvA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", + "integrity": "sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w==", "dev": true, "requires": { - "array-includes": "^3.0.3" + "array-includes": "^3.1.1", + "object.assign": "^4.1.0" } }, "kind-of": { @@ -11039,9 +9180,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "lodash.flattendeep": { "version": "4.4.0", @@ -11049,16 +9190,6 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" - }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" - }, "lodash.pad": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", @@ -11136,9 +9267,9 @@ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" } } }, @@ -11150,14 +9281,6 @@ "tmpl": "1.0.x" } }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "requires": { - "p-defer": "^1.0.0" - } - }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -11355,13 +9478,6 @@ "@babel/register": "^7.0.0", "core-js": "^2.2.2", "escape-string-regexp": "^1.0.5" - }, - "dependencies": { - "core-js": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", - "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==" - } } }, "metro-babel-transformer": { @@ -11602,16 +9718,16 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" }, "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", "requires": { - "mime-db": "1.40.0" + "mime-db": "1.44.0" } }, "mimic-fn": { @@ -11636,25 +9752,25 @@ } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minipass": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", - "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" } }, "minizlib": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", - "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", "requires": { - "minipass": "^2.2.1" + "minipass": "^2.9.0" } }, "mixin-deep": { @@ -11677,11 +9793,11 @@ } }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" } }, "mocha": { @@ -11724,12 +9840,27 @@ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" } }, "supports-color": { @@ -11744,20 +9875,20 @@ } }, "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + "version": "2.27.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz", + "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==" }, "morgan": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", - "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", "requires": { - "basic-auth": "~2.0.0", + "basic-auth": "~2.0.1", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "~2.0.0", "on-finished": "~2.3.0", - "on-headers": "~1.0.1" + "on-headers": "~1.0.2" } }, "ms": { @@ -11815,9 +9946,9 @@ } }, "nan": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", - "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==" + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", + "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==" }, "nanomatch": { "version": "1.2.13", @@ -11848,9 +9979,9 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" } } }, @@ -11900,12 +10031,6 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -12128,6 +10253,12 @@ } } }, + "object-inspect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "dev": true + }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -12157,26 +10288,37 @@ "object-keys": "^1.0.11" } }, + "object.entries": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", + "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "has": "^1.0.3" + } + }, "object.fromentries": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", - "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.2.tgz", + "integrity": "sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.11.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", "function-bind": "^1.1.1", - "has": "^1.0.1" + "has": "^1.0.3" } }, "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" } }, "object.omit": { @@ -12196,6 +10338,18 @@ "isobject": "^3.0.1" } }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "obv": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/obv/-/obv-0.0.1.tgz", @@ -12247,6 +10401,11 @@ "wordwrap": "~0.0.2" }, "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" + }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", @@ -12255,17 +10414,17 @@ } }, "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", + "fast-levenshtein": "~2.0.6", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", - "wordwrap": "~1.0.0" + "word-wrap": "~1.2.3" } }, "options": { @@ -12288,6 +10447,16 @@ "mem": "^1.1.0" }, "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, "execa": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", @@ -12323,11 +10492,6 @@ "os-tmpdir": "^1.0.0" } }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" - }, "p-each-series": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", @@ -12342,11 +10506,6 @@ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==" - }, "p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", @@ -12386,9 +10545,9 @@ }, "dependencies": { "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -12597,9 +10756,9 @@ } }, "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "requires": { "p-try": "^2.0.0" } @@ -12716,20 +10875,15 @@ } } }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" - }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "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==" }, "progress": { "version": "2.0.3", @@ -12751,13 +10905,13 @@ "dev": true }, "prompts": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.2.1.tgz", - "integrity": "sha512-VObPvJiWPhpZI6C5m60XOzTfnYg/xc/an+r9VYymj9WJW3B/DIH+REzjpAACPf8brwPeP+7vz3bIim3S+AaMjw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", "dev": true, "requires": { "kleur": "^3.0.3", - "sisteransi": "^1.0.3" + "sisteransi": "^1.0.4" } }, "prop-types": { @@ -12793,9 +10947,9 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { - "version": "1.1.31", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", - "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==" + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" }, "pump": { "version": "3.0.0", @@ -12817,9 +10971,9 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" }, "randomatic": { "version": "3.1.1", @@ -12837,9 +10991,9 @@ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" } } }, @@ -12857,13 +11011,6 @@ "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - } } }, "react": { @@ -12914,9 +11061,9 @@ } }, "react-is": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", - "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "react-native": { "version": "0.59.10", @@ -12987,11 +11134,6 @@ "lodash.padstart": "^4.1.0" } }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, "npmlog": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", @@ -13027,21 +11169,24 @@ } }, "react-native-animatable": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/react-native-animatable/-/react-native-animatable-1.3.2.tgz", - "integrity": "sha512-rmah3KQ63ft8DxkzFUwJSuZeq+oSYwldoGF4DTOR5WM2WR5wiWLgBAtrAHlI3Di3by323uOR21s+MlqPcHz2Kw==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/react-native-animatable/-/react-native-animatable-1.3.3.tgz", + "integrity": "sha512-2ckIxZQAsvWn25Ho+DK3d1mXIgj7tITkrS4pYDvx96WyOttSvzzFeQnM2od0+FUMzILbdHDsDEqZvnz1DYNQ1w==", "requires": { - "prop-types": "^15.5.10" + "prop-types": "^15.7.2" } }, "react-native-calendars": { - "version": "1.102.0", - "resolved": "https://registry.npmjs.org/react-native-calendars/-/react-native-calendars-1.102.0.tgz", - "integrity": "sha512-lxV13B7CAvuey/KoXjg7BTSh6KQSD0tXu4skR5ycr+4DKZkw/FU6aLZRrQW50vsrADBGvcQi0jplMXWDOPayZA==", - "requires": { - "lodash.get": "^4.4.2", - "lodash.isequal": "^4.5.0", + "version": "1.314.0", + "resolved": "https://registry.npmjs.org/react-native-calendars/-/react-native-calendars-1.314.0.tgz", + "integrity": "sha512-LlKXikpbfGkZxZRnQ6sraSlDd7iXAF1/GewUwB8G+DyO5GRGCZVN1EcvuAuJEgJLjn6782HvVDLAbyr8ScQjxg==", + "requires": { + "hoist-non-react-statics": "^3.3.1", + "immutable": "^4.0.0-rc.12", + "lodash": "^4.17.15", + "moment": "^2.24.0", "prop-types": "^15.5.10", + "react-native-swipe-gestures": "^1.0.5", "xdate": "^0.8.0" } }, @@ -13051,12 +11196,12 @@ "integrity": "sha512-bHMyAOzFl+II0ZdfzobKsZKvTErmXfmQGalpxpGbeN8+/uhfhUcdp4WuIMecZhFyX6rbj3h3XXLdA12hVlGgmw==" }, "react-native-fs": { - "version": "2.13.3", - "resolved": "https://registry.npmjs.org/react-native-fs/-/react-native-fs-2.13.3.tgz", - "integrity": "sha512-B62LSSAEYQGItg7KVTzTVVCxezOYFBYp4DMVFbdoZUd1mZVFdqR2sy1HY1mye1VI/Lf3IbxSyZEQ0GmrrdwLjg==", + "version": "2.16.6", + "resolved": "https://registry.npmjs.org/react-native-fs/-/react-native-fs-2.16.6.tgz", + "integrity": "sha512-ZWOooD1AuFoAGY3HS2GY7Qx2LZo4oIg6AK0wbC68detxwvX75R/q9lRqThXNKP6vIo2VHWa0fYUo/SrLw80E8w==", "requires": { "base-64": "^0.1.0", - "utf8": "^2.1.1" + "utf8": "^3.0.0" } }, "react-native-hyperlink": { @@ -13077,6 +11222,11 @@ "react-native-animatable": "^1.2.3" }, "dependencies": { + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + }, "fbjs": { "version": "0.8.17", "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", @@ -13112,6 +11262,11 @@ "react-native-modal": "3.1.0" }, "dependencies": { + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + }, "fbjs": { "version": "0.8.17", "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", @@ -13150,9 +11305,14 @@ "integrity": "sha512-kE+bSLFwr0EvHGXOGLDyM+lNAPgt4Cy67v1jdHK9kjgc4osrJVs8WwmWJvQwjDuGNXl14aLD/Ud5JhB4KRlrsQ==" }, "react-native-share": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/react-native-share/-/react-native-share-1.1.3.tgz", - "integrity": "sha512-vKAJqgkEt7HjsF0HUwgom+E0FbmFNVZNncHwby1+O8/mXlKugh+Ym6rvv+A2ASHmD5TXKohJMYT2+jYofzPORA==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/react-native-share/-/react-native-share-1.2.1.tgz", + "integrity": "sha512-V9q1FM+LuYJ65qN3k6BLWs17mIbJCzGyMOhF3rb4MIQXdJfCUbtkDX9aaV86PzcsL1EudCA53HVTJBmWPDed0Q==" + }, + "react-native-swipe-gestures": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/react-native-swipe-gestures/-/react-native-swipe-gestures-1.0.5.tgz", + "integrity": "sha512-Ns7Bn9H/Tyw278+5SQx9oAblDZ7JixyzeOczcBK8dipQk2pD7Djkcfnf1nB/8RErAmMLL9iXgW0QHqiII8AhKw==" }, "react-native-vector-icons": { "version": "6.4.2", @@ -13205,24 +11365,11 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "requires": { - "invert-kv": "^2.0.0" - } - }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -13232,35 +11379,10 @@ "path-exists": "^3.0.0" } }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "requires": { "p-try": "^2.0.0" } @@ -13317,27 +11439,26 @@ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, "yargs": { - "version": "13.2.4", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", - "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.0" + "yargs-parser": "^13.1.2" } }, "yargs-parser": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.0.tgz", - "integrity": "sha512-Yq+32PrijHRri0vVKQEm+ys8mbqWjLiwQkMFNXEENutzLPP0bE4Lcd4iA3OQY5HF+GD3xXxf0MEHb8E4/SA3AA==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -13346,15 +11467,15 @@ } }, "react-native-version": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/react-native-version/-/react-native-version-3.1.0.tgz", - "integrity": "sha512-f8uX0I1SeRf8qinpUgFVYFnhAQdS+Sh2HktOKJq2ZLmJmZm8JE5DXWOFo+0tcog6qyOmZzr8MYLDhpBOO+imoQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-native-version/-/react-native-version-3.2.0.tgz", + "integrity": "sha512-Hgglpm0XIUOkhYLSFaa+YG9v+0excDgLO4/K2zPv3NFEpNo0q6BAsHf/JspeobMf3ju65al9hf134P5Mvu1C3w==", "dev": true, "requires": { "chalk": "^2.4.1", - "commander": "^2.9.0", + "commander": "^3.0.0", "common-tags": "^1.4.0", - "detect-indent": "^5.0.0", + "detect-indent": "^6.0.0", "dottie": "^2.0.0", "js-beautify": "^1.7.4", "lodash.flattendeep": "^4.4.0", @@ -13366,31 +11487,17 @@ "semver": "^6.0.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", "dev": true }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } + "commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true }, "plist": { "version": "3.0.1", @@ -13410,20 +11517,11 @@ "dev": true }, "semver": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", - "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, "xmlbuilder": { "version": "9.0.7", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", @@ -13495,9 +11593,9 @@ } }, "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -13509,9 +11607,9 @@ }, "dependencies": { "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" } } }, @@ -13576,9 +11674,9 @@ } }, "redux": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.4.tgz", - "integrity": "sha512-vKv4WdiJxOWKxK0yRoaK3Y4pxxB0ilzVx6dszU2W8wLxlb2yikRph4iV/ymtdJ6ZxpBLFbyrxklnT5yBbQSl3Q==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz", + "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==", "requires": { "loose-envify": "^1.4.0", "symbol-observable": "^1.2.0" @@ -13617,14 +11715,14 @@ "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" }, "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", + "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==" }, "regenerate-unicode-properties": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", - "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", "requires": { "regenerate": "^1.4.0" } @@ -13635,11 +11733,11 @@ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, "regenerator-transform": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", - "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", "requires": { - "private": "^0.1.6" + "@babel/runtime": "^7.8.4" } }, "regex-cache": { @@ -13659,6 +11757,16 @@ "safe-regex": "^1.1.0" } }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", @@ -13666,27 +11774,27 @@ "dev": true }, "regexpu-core": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", - "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", + "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", "requires": { "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.1.0", - "regjsgen": "^0.5.0", - "regjsparser": "^0.6.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.1.0" + "unicode-match-property-value-ecmascript": "^1.2.0" } }, "regjsgen": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", - "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==" + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==" }, "regjsparser": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", - "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", + "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", "requires": { "jsesc": "~0.5.0" }, @@ -13765,9 +11873,9 @@ "dev": true }, "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -13776,7 +11884,7 @@ "extend": "~3.0.2", "forever-agent": "~0.6.1", "form-data": "~2.3.2", - "har-validator": "~5.1.0", + "har-validator": "~5.1.3", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", @@ -13786,35 +11894,27 @@ "performance-now": "^2.1.0", "qs": "~6.5.2", "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", + "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" } }, "request-promise-core": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", - "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", "dev": true, "requires": { - "lodash": "^4.17.15" - }, - "dependencies": { - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - } + "lodash": "^4.17.19" } }, "request-promise-native": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", - "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", "dev": true, "requires": { - "request-promise-core": "1.1.3", + "request-promise-core": "1.1.4", "stealthy-require": "^1.1.1", "tough-cookie": "^2.3.3" } @@ -13840,9 +11940,9 @@ "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==" }, "resolve": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz", - "integrity": "sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "requires": { "path-parse": "^1.0.6" } @@ -13887,9 +11987,9 @@ "dev": true }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "requires": { "glob": "^7.1.3" } @@ -13900,12 +12000,9 @@ "integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==" }, "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "requires": { - "is-promise": "^2.1.0" - } + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" }, "rx-lite": { "version": "4.0.8", @@ -13921,9 +12018,9 @@ } }, "rxjs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.1.tgz", - "integrity": "sha512-y0j31WJc83wPu31vS1VlAFW5JGrnGC+j+TtGAa1fRQphy48+fDYiDmX8tjGloToEsMkxnouOg/1IzXGKkJnZMg==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", + "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -14190,9 +12287,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" }, "micromatch": { "version": "3.1.10", @@ -14213,18 +12310,13 @@ "snapdragon": "^0.8.1", "to-regex": "^3.0.2" } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" } } }, "sanitize-filename": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.1.tgz", - "integrity": "sha1-YS2hyWRz+gLczaktzVtKsWSmdyo=", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", "dev": true, "requires": { "truncate-utf8-bytes": "^1.0.0" @@ -14245,21 +12337,11 @@ } }, "seek-bzip": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", - "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", + "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", "requires": { - "commander": "~2.8.1" - }, - "dependencies": { - "commander": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", - "requires": { - "graceful-readlink": ">= 1.0.0" - } - } + "commander": "^2.8.1" } }, "selectorator": { @@ -14298,6 +12380,11 @@ "statuses": "~1.5.0" }, "dependencies": { + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", @@ -14395,6 +12482,16 @@ "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" }, + "side-channel": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", + "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "object-inspect": "^1.7.0" + } + }, "sigmund": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", @@ -14402,9 +12499,9 @@ "dev": true }, "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, "simple-plist": { "version": "0.2.1", @@ -14417,9 +12514,9 @@ } }, "sisteransi": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.3.tgz", - "integrity": "sha512-SbEG75TzH8G7eVXFSN5f9EExILKfly7SUvVY5DhhYLvfhKqhDFY0OzevWa/zwak0RLRfWS5AvfMWpd9gJvr5Yg==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, "slash": { @@ -14538,9 +12635,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" } } }, @@ -14558,11 +12655,11 @@ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" }, "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "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==", "requires": { - "atob": "^2.1.1", + "atob": "^2.1.2", "decode-uri-component": "^0.2.0", "resolve-url": "^0.2.1", "source-map-url": "^0.4.0", @@ -14570,9 +12667,9 @@ } }, "source-map-support": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", - "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -14591,23 +12688,23 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" }, "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -14654,9 +12751,9 @@ "dev": true }, "stacktrace-parser": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.7.tgz", - "integrity": "sha512-Evm+NuZ2ZTwGazsbsZC+EV1EGsvyxgIvtNwbyFfeXaq/8L78M5Kdh0qpmQaTkUpbOAKbbPP7c7qZa7u8XFsrUA==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", "requires": { "type-fest": "^0.7.1" } @@ -14744,6 +12841,40 @@ "strip-ansi": "^3.0.0" } }, + "string.prototype.matchall": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz", + "integrity": "sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "has-symbols": "^1.0.1", + "internal-slot": "^1.0.2", + "regexp.prototype.flags": "^1.3.0", + "side-channel": "^1.0.2" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -14833,24 +12964,24 @@ } }, "table": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/table/-/table-5.2.3.tgz", - "integrity": "sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ==", + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", "dev": true, "requires": { - "ajv": "^6.9.1", - "lodash": "^4.17.11", + "ajv": "^6.10.2", + "lodash": "^4.17.14", "slice-ansi": "^2.1.0", "string-width": "^3.0.0" }, "dependencies": { "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "version": "6.12.4", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", + "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", + "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" @@ -14862,10 +12993,16 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "is-fullwidth-code-point": { @@ -14903,9 +13040,9 @@ } }, "tail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/tail/-/tail-2.0.2.tgz", - "integrity": "sha512-raFipiKWdGKEzxbvZwnhUGqjvsv0gpa/1A479rL//NOxnNwYZDN4MPk6xJJdUFs8P2Xrff3nbH5fcyYRLU4UHQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/tail/-/tail-2.0.4.tgz", + "integrity": "sha512-xHkZdNWIzO++g+V/rHGqVoHd2LRxz+8t8bj6FGelfb8FHBjg5yjkX7Su/8sQSBo5alIspYkRp/fU0A2SM5h+5A==", "dev": true }, "tar": { @@ -14920,17 +13057,6 @@ "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", "yallist": "^3.0.3" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } } }, "tar-stream": { @@ -14954,6 +13080,14 @@ "dev": true, "requires": { "bluebird": "3.5.x" + }, + "dependencies": { + "bluebird": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", + "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", + "dev": true + } } }, "temp": { @@ -15032,9 +13166,9 @@ } }, "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -15259,19 +13393,12 @@ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } + "psl": "^1.1.28", + "punycode": "^2.1.1" } }, "tr46": { @@ -15289,11 +13416,6 @@ "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", "dev": true }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" - }, "trim-trailing-lines": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.3.tgz", @@ -15316,9 +13438,9 @@ } }, "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", "dev": true }, "tunnel-agent": { @@ -15365,9 +13487,9 @@ "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=" }, "ua-parser-js": { - "version": "0.7.19", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz", - "integrity": "sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ==" + "version": "0.7.21", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", + "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==" }, "uc.micro": { "version": "1.0.6", @@ -15410,9 +13532,9 @@ } }, "unchanged": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unchanged/-/unchanged-2.2.0.tgz", - "integrity": "sha512-L+MJNfyvFZkjw9WYRbmZBnYncBoASRNxE9eCm5SZWc2whdw19tPVigjJXNwu+/O+nCwp1kYYT8LX+jNuJakF9w==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unchanged/-/unchanged-2.2.1.tgz", + "integrity": "sha512-pMlMNfqtfjOVpDAKVBH+LjnhnTwWYUrJq9fU3nGRYrw6JnprJEH1/cehJikRTf+o6dmkpX5XRRspb5mUAhxeZQ==", "requires": { "curriable": "^1.3.0", "pathington": "^1.1.7" @@ -15443,14 +13565,14 @@ } }, "unicode-match-property-value-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", - "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==" }, "unicode-property-aliases-ecmascript": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", - "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==" }, "unified": { "version": "7.1.0", @@ -15601,9 +13723,9 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, "utf8": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz", - "integrity": "sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY=" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" }, "utf8-byte-length": { "version": "1.0.4", @@ -15625,13 +13747,15 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" } }, "utils-merge": { @@ -15640,9 +13764,9 @@ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, "validate-npm-package-license": { "version": "3.0.4", @@ -15704,12 +13828,12 @@ } }, "w3c-hr-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", - "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", "dev": true, "requires": { - "browser-process-hrtime": "^0.1.2" + "browser-process-hrtime": "^1.0.0" } }, "walker": { @@ -15727,13 +13851,6 @@ "requires": { "exec-sh": "^0.2.0", "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } } }, "webidl-conversions": { @@ -15752,9 +13869,9 @@ } }, "whatwg-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", - "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.4.0.tgz", + "integrity": "sha512-rsum2ulz2iuZH08mJkT0Yi6JnKhwdw4oeyMjokgxd+mmqYSd9cPpOQf01TIWgjxG/U4+QR+AwKq6lSbXVxkyoQ==" }, "whatwg-mimetype": { "version": "2.3.0", @@ -15794,6 +13911,12 @@ "string-width": "^1.0.2 || 2" } }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -15889,9 +14012,9 @@ } }, "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz", + "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==" }, "xpipe": { "version": "1.0.5", @@ -15899,9 +14022,9 @@ "integrity": "sha1-jdi/Rfw/f1Xw4FS4ePQ6YmFNr98=" }, "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { "version": "3.2.1", @@ -15909,9 +14032,9 @@ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yargs": { "version": "9.0.1", @@ -15980,4 +14103,4 @@ } } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index d10fd7f1394881695fafd1574af4668f63d42093..496b612e76bf1c6ff70abc8fe5239eb76fc86079 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "Marie Kochsiek", "Tina Baumann", "Sofiya Tepikin", - "Mariya Zadnepryanets" + "Mariya Zadnepryanets", + "Lisa Hillebrand" ], "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", @@ -27,7 +28,7 @@ "postinstall": "npx jetify" }, "dependencies": { - "@ptomasroos/react-native-multi-slider": "^1.0.0", + "@ptomasroos/react-native-multi-slider": "^2.2.0", "ajv": "^5.5.2", "assert": "^1.4.1", "csvtojson": "^2.0.8", @@ -49,7 +50,7 @@ "react-native-push-notification": "github:sdvig/react-native-push-notification", "react-native-restart": "0.0.9", "react-native-share": "^1.1.3", - "react-native-vector-icons": "^6.4.2", + "react-native-vector-icons": "6.4.2", "react-redux": "^6.0.0", "realm": "^3.6.5", "redux": "^4.0.1", @@ -120,4 +121,4 @@ }, "test-runner": "mocha" } -} \ No newline at end of file +} diff --git a/selection.json b/selection.json new file mode 100755 index 0000000000000000000000000000000000000000..22aea2a24ad601916f98282381157675f6ee3a58 --- /dev/null +++ b/selection.json @@ -0,0 +1 @@ +{"IcoMoonType":"selection","icons":[{"icon":{"paths":["M978.192 487.15c-3.642-2.692-8.217-3.808-12.7-3.108l-404.883 62.3c-6.692 1.025-12.15 5.917-13.892 12.458-1.75 6.542 0.533 13.5 5.817 17.725l319.775 255.833c7.367 5.892 18.108 4.7 24-2.658 60.858-75.458 93.9-169.558 93.558-266.5-0.008-21.708-1.642-43.392-4.9-64.85-0.683-4.483-3.117-8.517-6.775-11.2v0zM880.042 794.808l-275.883-220.65 349.217-53.725c1.558 14.2 2.342 28.475 2.358 42.767 0.308 83.333-26.233 164.542-75.692 231.608z","M492.717 553.217l-114.842-387.667c-1.283-4.35-4.25-8.008-8.225-10.167-3.983-2.158-8.667-2.65-13.008-1.358-149.65 44.225-263.183 166.675-295.983 319.233s20.367 310.85 138.608 412.675l-103.933 103.933h-95.333v34.133h102.4c4.525 0 8.867-1.8 12.067-5l111.633-111.633c184.242 135.142 442.283 100.867 584.875-77.667 5.892-7.367 4.7-18.108-2.667-24l-315.592-252.483zM475.525 952.442c-80.117 0.058-158.242-24.958-223.417-71.542l55.092-55.075v56.708l34.133-34.133v-80.4h-80.433l-34.133 34.133h56.708l-58.025 58.025c-105.542-89.675-154.825-229.1-129.1-365.183 25.733-136.083 122.525-247.883 253.517-292.833l109.583 369.425c0.983 3.275 2.933 6.175 5.6 8.325l300.933 240.642c-73.108 84.008-179.092 132.133-290.458 131.908z","M921.6 0c-4.525 0-8.867 1.8-12.067 5l-132.492 132.492c-104.008-68.267-232.842-87.167-352.083-51.667-9.042 2.675-14.2 12.175-11.517 21.217l116.358 392.742c2.142 7.233 8.783 12.2 16.333 12.217 0.875 0 1.75-0.067 2.608-0.208l404.908-62.292c9.3-1.433 15.692-10.133 14.267-19.433-17.025-108.425-75.267-206.083-162.575-272.592l123.325-123.342h95.333v-34.133h-102.4zM926.092 416.425l-366.575 56.325-105.358-355.283c101.033-25.342 208.033-8.283 296.175 47.208l-84.733 84.7v-56.708l-34.133 34.133v80.4h80.433l34.133-34.133h-56.708l89.15-89.125c76.158 56.675 128.717 139.458 147.617 232.483v0z","M938.667 51.2h85.333v34.133h-85.333z","M887.467 102.4h136.533v34.133h-136.533z","M989.867 153.6h34.133v34.133h-34.133z","M887.467 153.6h85.333v34.133h-85.333z","M0 938.667h85.333v34.133h-85.333z","M0 887.467h136.533v34.133h-136.533z","M0 836.267h34.133v34.133h-34.133z","M51.2 836.267h85.333v34.133h-85.333z"],"attrs":[{},{},{},{},{},{},{},{},{},{},{}],"isMulticolor":false,"isMulticolor2":false,"grid":0,"tags":["statistics"]},"attrs":[{},{},{},{},{},{},{},{},{},{},{}],"properties":{"order":2,"id":2,"name":"statistics","prevSize":32,"code":59648},"setIdx":0,"setId":2,"iconIdx":0},{"icon":{"paths":["M18.006 0c-9.322 0-16.88 7.558-16.88 16.88v187.092c0.002 9.322 7.558 16.88 16.88 16.88s16.88-7.558 16.88-16.88v-187.092c0-9.322-7.556-16.88-16.88-16.88z","M1005.996 990.24h-967.94c13.25-74.266 64.254-339.404 134.452-446.468 12.788 11.386 29.62 18.324 48.046 18.324 17.384 0 33.35-6.166 45.84-16.422 9.598 26.156 15.472 60.96 21.592 97.334 11.464 68.13 23.322 138.452 63.164 176.572-0.254 2.464-0.39 4.964-0.39 7.496 0 39.89 32.452 72.344 72.344 72.344 39.89 0 72.342-32.452 72.342-72.344 0-7.7-1.22-15.114-3.46-22.080 31.302-49.986 38.098-137.474 45.272-229.966 6.288-81.084 12.784-164.584 36.87-210.060 13.13 13.336 31.372 21.624 51.522 21.624 20.19 0 38.464-8.322 51.6-21.704 17.594 32.478 22.606 84.46 27.474 135.012 5.922 61.51 11.526 119.708 38.352 155.906-1.414 5.634-2.174 11.522-2.174 17.59 0 39.89 32.452 72.344 72.344 72.344s72.344-32.452 72.344-72.344c0-7.744-1.236-15.2-3.5-22.2 28.724-43.006 35.702-114.888 43.062-190.832 5.062-52.238 10.294-106.254 23.212-145.062 12.93-38.846 30.704-56.172 57.63-56.172 9.324 0 16.88-7.558 16.88-16.88s-7.556-16.88-16.88-16.88c-41.986 0-72.152 26.668-89.662 79.268-14.118 42.42-19.542 98.366-24.784 152.468-5.914 61.050-12.014 123.864-30.228 162.294-12.79-11.402-29.636-18.348-48.076-18.348-19.902 0-37.948 8.080-51.042 21.128-14.75-30.794-19.38-78.816-23.876-125.518-5.99-62.238-12.184-126.46-42.508-164.826 1.414-5.636 2.174-11.526 2.174-17.592 0-39.89-32.452-72.344-72.344-72.344s-72.344 32.452-72.344 72.344c0 5.964 0.74 11.754 2.106 17.302-36.906 48.862-44.162 142.184-51.814 240.864-5.892 75.98-11.968 154.218-32.7 200.42-12.756-11.256-29.488-18.106-47.796-18.106-23.846 0-45.026 11.602-58.212 29.452-24.506-33.326-34.206-90.86-43.616-146.78-7.982-47.44-15.566-92.416-32.324-124.136 2.546-7.38 3.946-15.286 3.946-23.518 0-39.89-32.452-72.344-72.342-72.344s-72.344 32.452-72.344 72.344c0 8.406 1.456 16.474 4.104 23.986-50.636 68.72-91.154 209.734-117.428 323.118v-565.372c0-9.322-7.558-16.88-16.88-16.88s-16.88 7.558-16.88 16.88v735.642c0 0.104 0.014 0.202 0.016 0.306 0.006 0.336 0.024 0.668 0.050 1 0.018 0.234 0.036 0.466 0.062 0.696 0.038 0.32 0.088 0.634 0.144 0.948 0.042 0.246 0.088 0.488 0.14 0.73 0.062 0.282 0.138 0.56 0.216 0.838 0.072 0.264 0.146 0.526 0.232 0.784 0.082 0.248 0.174 0.488 0.268 0.732 0.106 0.274 0.212 0.55 0.33 0.818 0.098 0.22 0.208 0.434 0.312 0.65 0.136 0.272 0.272 0.542 0.42 0.806 0.12 0.21 0.248 0.412 0.374 0.614 0.158 0.252 0.316 0.502 0.486 0.748 0.146 0.21 0.302 0.41 0.46 0.612 0.172 0.22 0.34 0.442 0.52 0.652s0.37 0.412 0.558 0.614c0.176 0.186 0.348 0.374 0.534 0.554 0.212 0.204 0.432 0.4 0.654 0.596 0.182 0.16 0.362 0.32 0.552 0.472 0.234 0.19 0.48 0.364 0.724 0.542 0.198 0.142 0.392 0.284 0.596 0.416 0.246 0.16 0.498 0.308 0.752 0.456 0.224 0.13 0.45 0.26 0.68 0.382 0.24 0.124 0.486 0.238 0.734 0.354 0.264 0.122 0.526 0.24 0.796 0.348 0.228 0.090 0.462 0.174 0.694 0.254 0.302 0.106 0.606 0.208 0.916 0.294 0.22 0.064 0.446 0.118 0.672 0.174 0.326 0.078 0.654 0.152 0.988 0.212 0.1 0.018 0.194 0.048 0.292 0.062 0.086 0.014 0.168 0.010 0.254 0.020 0.796 0.118 1.606 0.196 2.438 0.198 0.014 0 0.024 0.002 0.038 0.002 0.016 0 0.032-0.002 0.050-0.002h987.914c9.324 0 16.88-7.558 16.88-16.88 0.004-9.32-7.55-16.88-16.874-16.88zM813.25 634.816c21.274 0 38.586 17.308 38.586 38.586 0 21.276-17.308 38.586-38.586 38.586-21.274 0-38.586-17.308-38.586-38.586s17.312-38.586 38.586-38.586zM625.654 275.666c21.274 0 38.586 17.308 38.586 38.586 0 21.276-17.308 38.586-38.586 38.586-21.274 0-38.586-17.308-38.586-38.586 0-21.276 17.312-38.586 38.586-38.586zM423.108 788.49c21.276 0 38.584 17.308 38.584 38.586s-17.308 38.586-38.584 38.586c-21.276 0-38.586-17.308-38.586-38.586s17.308-38.586 38.586-38.586zM220.558 451.166c21.276 0 38.584 17.308 38.584 38.586 0 21.276-17.308 38.586-38.584 38.586-13.382 0-25.186-6.856-32.11-17.23-0.652-2.33-1.822-4.528-3.468-6.434-1.934-4.594-3.006-9.634-3.006-14.922-0.002-21.276 17.308-38.586 38.584-38.586z"],"attrs":[{},{}],"isMulticolor":false,"isMulticolor2":false,"grid":0,"tags":["chart"]},"attrs":[{},{}],"properties":{"order":3,"id":1,"name":"chart","prevSize":32,"code":59649},"setIdx":0,"setId":2,"iconIdx":1},{"icon":{"paths":["M757.389 70.621c-8.21-40.236-43.855-70.621-86.493-70.621-9.763 0-17.655 7.892-17.655 17.655s7.892 17.655 17.655 17.655c29.202 0 52.966 23.764 52.966 52.966s-23.764 52.966-52.966 52.966c-9.763 0-17.655 7.892-17.655 17.655s7.892 17.655 17.655 17.655c42.62 0 78.283-30.385 86.493-70.621h231.3v158.897h-953.379v-158.897h300.138c9.763 0 17.655-7.892 17.655-17.655s-7.892-17.655-17.655-17.655h-32.062c7.309-20.515 26.73-35.31 49.717-35.31 29.202 0 52.966 23.764 52.966 52.966s-23.764 52.966-52.966 52.966c-9.763 0-17.655 7.892-17.655 17.655s7.892 17.655 17.655 17.655c48.675 0 88.276-39.601 88.276-88.276s-39.601-88.276-88.276-88.276c-42.62 0-78.283 30.385-86.493 70.621h-266.611v935.724h1024v-935.724h-266.611zM988.69 971.034h-953.379v-670.897h953.379v670.897z","M459.034 35.31c29.202 0 52.966 23.764 52.966 52.966s-23.764 52.966-52.966 52.966c-9.763 0-17.655 7.892-17.655 17.655s7.892 17.655 17.655 17.655c48.675 0 88.276-39.601 88.276-88.276s-39.601-88.276-88.276-88.276c-9.763 0-17.655 7.892-17.655 17.655s7.892 17.655 17.655 17.655z","M564.966 35.31c29.202 0 52.966 23.764 52.966 52.966s-23.764 52.966-52.966 52.966c-9.763 0-17.655 7.892-17.655 17.655s7.892 17.655 17.655 17.655c48.675 0 88.276-39.601 88.276-88.276s-39.601-88.276-88.276-88.276c-9.763 0-17.655 7.892-17.655 17.655s7.892 17.655 17.655 17.655z","M409.747 423.724c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M533.333 423.724c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M656.92 423.724c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M780.506 423.724c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M904.092 423.724c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M162.575 564.966c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M286.161 564.966c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M409.747 564.966c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M533.333 564.966c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M656.92 564.966c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M780.506 564.966c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M904.092 564.966c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M162.575 688.552c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M286.161 688.552c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M409.747 688.552c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M533.333 688.552c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M656.92 688.552c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M780.506 688.552c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M904.092 688.552c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M162.575 829.793c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M286.161 829.793c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M409.747 829.793c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M533.333 829.793c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z","M656.92 829.793c0 11.782-9.551 21.333-21.333 21.333s-21.333-9.551-21.333-21.333c0-11.782 9.551-21.333 21.333-21.333s21.333 9.551 21.333 21.333z"],"attrs":[{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}],"isMulticolor":false,"isMulticolor2":false,"grid":0,"tags":["calendar"]},"attrs":[{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}],"properties":{"order":4,"id":0,"name":"calendar","prevSize":32,"code":59650},"setIdx":0,"setId":2,"iconIdx":2}],"height":1024,"metadata":{"name":"icomoon"},"preferences":{"showGlyphs":true,"showQuickUse":true,"showQuickUse2":true,"showSVGs":true,"fontPref":{"prefix":"icon-","metadata":{"fontFamily":"icomoon"},"metrics":{"emSize":1024,"baseline":6.25,"whitespace":50},"embed":false},"imagePref":{"prefix":"icon-","png":true,"useClassSelector":true,"color":0,"bgColor":16777215,"classSelector":".icon"},"historySize":50,"showCodes":true,"gridSize":16}} \ No newline at end of file diff --git a/slices/navigation.js b/slices/navigation.js index 89a442c5c4039f44ab53c6f22840d341d5f842b8..babdb03beefe99d3838d84125032f11ca3724278 100644 --- a/slices/navigation.js +++ b/slices/navigation.js @@ -1,5 +1,5 @@ import { createSlice } from 'redux-starter-kit' -import { pages, isSymptomView } from '../components/pages' +import { pages } from '../components/pages' const navigationSlice = createSlice({ slice: 'navigation', @@ -7,29 +7,18 @@ const navigationSlice = createSlice({ currentPage: 'Home', }, reducers: { - navigate: (state, action) => { + navigate: (_state, action) => { return { currentPage: action.payload, - previousPage: state.currentPage, } }, - goBack: ({ currentPage, previousPage }) => { - - if (currentPage === 'CycleDay' || isSymptomView(currentPage)) { - if (previousPage) { - return { - currentPage: previousPage - } - } - } - - const page = pages.find(p => p.component === currentPage) + goBack: ({ currentPage }) => { + const page = pages.find((p) => p.component === currentPage) return { currentPage: page.parent, - previousPage: currentPage, } - } - } + }, + }, }) // Extract the action creators object and the reducer diff --git a/styles/colors.js b/styles/colors.js new file mode 100644 index 0000000000000000000000000000000000000000..047a60fd61507ea66f4c1ffee32c5361d84cd3fe --- /dev/null +++ b/styles/colors.js @@ -0,0 +1,59 @@ +const redColor = '#c3000d' +export const shadesOfRed = ['#e7999e', '#db666d', '#cf323d', '#c3000d'] // light to dark +const violetColor = '#6a7b98' +const shadesOfViolet = ['#e3e7ed', '#c8cfdc', '#acb8cb', '#91a0ba', '#7689a9', violetColor] // light to dark +const yellowColor = '#dbb40c' +const shadesOfYellow = ['#f0e19d', '#e9d26d', '#e2c33c', yellowColor] // light to dark +const magentaColor = '#6f2565' +const shadesOfMagenta = ['#a87ca2', '#8b5083', magentaColor] // light to dark +const pinkColor = '#9e346c' +const shadesOfPink = ['#c485a6', '#b15c89', pinkColor] // light to dark +const lightGreenColor = '#bccd67' +const orangeColor = '#bc6642' +const mintColor = '#6ca299' + +export default { + greyDark: '#555', + grey: '#888', + greyLight: '#CCC', + orange: '#F38337', + purple: '#3A2671', + purpleLight: '#938EB2', + turquoiseDark: '#69CBC1', + turquoise: '#CFECEA', + turquoiseLight: '#E9F2ED', + iconColors: { + 'bleeding': { + color: redColor, + shades: shadesOfRed, + }, + 'mucus': { + color: violetColor, + shades: shadesOfViolet, + }, + 'cervix': { + color: yellowColor, + shades: shadesOfYellow, + }, + 'sex': { + color: magentaColor, + shades: shadesOfMagenta, + }, + 'desire': { + color: pinkColor, + shades: shadesOfPink, + }, + 'pain': { + color: lightGreenColor, + shades: [lightGreenColor], + }, + 'mood': { + color: orangeColor, + shades: [orangeColor], + }, + 'note': { + color: mintColor, + shades: [mintColor], + }, + }, +} \ No newline at end of file diff --git a/styles/containers.js b/styles/containers.js new file mode 100644 index 0000000000000000000000000000000000000000..6526d3a69067a53c7c296296e37d74ad835b63f2 --- /dev/null +++ b/styles/containers.js @@ -0,0 +1,33 @@ +import Colors from './colors' +import Spacing from './spacing' + +export default { + box: { + borderColor: Colors.orange, + borderRadius: 5, + borderWidth: 1, + marginTop: Spacing.small, + marginRight: Spacing.small, + paddingHorizontal: Spacing.small, + paddingVertical: Spacing.tiny + }, + boxActive: { + backgroundColor: Colors.orange, + }, + centerItems: { + alignItems: 'center', + flex: 1, + justifyContent: 'center' + }, + rowContainer: { + alignItems: 'center', + flexDirection: 'row', + justifyContent: 'space-between' + }, + selectGroupContainer: { + alignItems: 'center', + flexDirection: 'row', + flexWrap: 'wrap', + marginVertical: Spacing.small + } +} \ No newline at end of file diff --git a/styles/index.js b/styles/index.js index e54b8bbe9e85658827d23410cbdc7096726ccdbc..080add1ef791f5cf3180bde6b753f333fb8c0677 100644 --- a/styles/index.js +++ b/styles/index.js @@ -1,490 +1,6 @@ -import { StyleSheet } from 'react-native' +import Colors from './colors' +import Containers from './containers' +import Spacing from './spacing' +import Typography, { fonts as Fonts, sizes as Sizes } from './typography' -export const primaryColor = '#000D19' -export const secondaryColor = '#4FAFA7' -export const secondaryColorLight = '#91749d' -export const fontOnPrimaryColor = 'white' -export const shadesOfRed = [ - '#e7999e', - '#db666d', - '#cf323d', - '#c3000d' -] // light to dark -export const cycleDayColor = '#29287f' -export const periodColor = '#802249' - -const headerFont = 'Prompt-ExtraLight' - -const textFont = 'OpenSans-Light' -const textFontBold = 'OpenSans-SemiBold' -const textFontItalic = 'OpenSans-LightItalic' - -const regularSize = 16 -const hintSize = 14 - -const defaultBottomMargin = 5 -const defaultIndentation = 10 -const defaultTopMargin = 10 -const colorInActive = '#666666' - -export const calendarTheme = { - textDayFontFamily: textFont, - textMonthFontFamily: textFontBold, - textDayHeaderFontFamily: textFont, - textDayFontSize: regularSize, - textMonthFontSize: regularSize, - textDayHeaderFontSize: hintSize, - textSectionTitleColor: 'grey' -} - -export default StyleSheet.create({ - appText: { - color: 'black', - fontFamily: textFont, - fontSize: regularSize, - letterSpacing: 0.5 - }, - hint: { - fontFamily: textFontItalic, - fontSize: hintSize, - }, - paragraph: { - marginBottom: defaultBottomMargin - }, - emphasis: { - fontWeight: 'bold', - fontFamily: textFontBold, - color: secondaryColor, - }, - link: { - color: cycleDayColor, - textDecorationLine: 'underline' - }, - title: { - fontSize: 18, - color: 'black', - marginBottom: defaultBottomMargin, - }, - textWrappingView: { - marginHorizontal: defaultIndentation, - marginTop: defaultTopMargin - }, - welcome: { - fontSize: 20, - fontFamily: 'serif', - margin: 30, - textAlign: 'center', - textAlignVertical: 'center' - }, - dateHeader: { - fontSize: 20, - fontFamily: headerFont, - color: fontOnPrimaryColor, - textAlign: 'center', - }, - headerText: { - fontSize: 30, - fontFamily: headerFont, - color: fontOnPrimaryColor, - textAlign: 'center', - paddingBottom: 4 - }, - accentCircle: { - borderColor: secondaryColor, - borderWidth: 1, - width: 40, - height: 40, - borderRadius: 100, - position: 'absolute', - alignSelf: 'center', - }, - errorMessage: { - color: shadesOfRed[2], - marginLeft: 10, - marginTop: 6 - }, - button: { - paddingVertical: 10, - paddingHorizontal: 20, - borderRadius: 5, - alignItems: 'center', - }, - homeButton: { - width: 200, - marginTop: 5 - }, - homeButtonText: { - color: fontOnPrimaryColor - }, - homeView: { - alignItems: 'center', - marginVertical: 40 - }, - homeDescriptionText: { - width: 200, - marginBottom: defaultBottomMargin, - }, - homeElement: { - marginBottom: 30, - flexDirection: 'row', - }, - homeIconTextWrapper: { - alignItems: 'center', - justifyContent: 'center', - width: 80, - position: 'absolute', - }, - homeIconAndText: { - justifyContent: 'center' - }, - homeCircle: { - borderRadius: 100, - borderWidth: 2.3, - width: 80, - height: 80, - alignItems: 'center', - justifyContent: 'center', - borderColor: secondaryColor, - }, - iconText: { - fontSize: 25 - }, - cycleDayNumber: { - fontSize: 15, - color: fontOnPrimaryColor, - textAlign: 'center', - fontFamily: headerFont - }, - symptomViewHeading: { - fontWeight: 'bold', - fontFamily: textFontBold, - flex: 1 - }, - symptomSection: { - marginBottom: 10 - }, - symptomBoxImage: { - width: 50, - height: 50 - }, - symptomBoxesView: { - flexDirection: 'row', - flexWrap: 'wrap', - justifyContent: 'space-evenly' - }, - symptomBox: { - borderColor: secondaryColor, - borderStyle: 'solid', - borderWidth: 1, - borderTopLeftRadius: 10, - borderTopRightRadius: 10, - alignItems: 'center', - marginTop: '10%', - paddingVertical: '6%', - marginHorizontal: 1, - width: 110, - height: 80, - }, - symptomBoxActive: { - backgroundColor: secondaryColor, - }, - symptomTextActive: { - color: fontOnPrimaryColor - }, - symptomInFuture: { - borderColor: 'lightgrey', - color: 'lightgrey' - }, - symptomDataBox: { - borderColor: secondaryColor, - borderStyle: 'solid', - borderLeftWidth: 1, - borderRightWidth: 1, - borderBottomWidth: 1, - borderBottomLeftRadius: 10, - borderBottomRightRadius: 10, - alignItems: 'center', - justifyContent: 'center', - padding: '3%', - marginHorizontal: 1, - width: 110, - height: 50, - }, - symptomDataText: { - fontSize: 12 - }, - header: { - backgroundColor: primaryColor, - alignItems: 'center', - justifyContent: 'center', - height: 80 - }, - navigationArrow: { - padding: 20, - position: 'absolute' - }, - navigationArrowLeft: { left: 0 }, - navigationArrowRight: { right: 0 }, - menu: { - backgroundColor: primaryColor, - alignItems: 'center', - justifyContent: 'space-between', - flexDirection: 'row', - height: 60 - }, - menuItem: { - alignItems: 'center', - flex: 1, - paddingVertical: 15 - }, - menuText: { - color: fontOnPrimaryColor, - fontFamily: headerFont - }, - menuTextInActive: { - color: colorInActive, - fontFamily: headerFont - }, - temperatureTextInput: { - fontSize: 20, - color: 'black', - textAlign: 'center', - width: '30%' - }, - temperatureTextInputSuggestion: { - color: '#939393' - }, - symptomEditButton: { - width: 130 - }, - framedSegment: { - borderColor: secondaryColor, - borderStyle: 'solid', - borderWidth: 1, - borderRadius: 10, - marginTop: defaultTopMargin, - marginHorizontal: defaultIndentation, - padding: 7, - fontFamily: textFont - }, - framedSegmentLast: { - marginBottom: defaultTopMargin, - }, - framedSegmentTitle: { - fontWeight: 'bold', - fontFamily: textFontBold - }, - framedSegmentInlineChildren: { - flexDirection: 'row', - alignItems: 'center' - }, - infoPopUpWrapper: { - position: 'absolute', - width: '100%', - height: '100%' - }, - infoPopUp: { - backgroundColor: 'white', - padding: 15, - marginHorizontal: 20, - marginTop: 20, - maxHeight: '92%' - }, - dimmed: { - position: 'absolute', - backgroundColor: 'black', - opacity: 0.5, - width: '100%', - height: '100%' - }, - infoSymptomClose: { - alignItems: 'flex-end' - }, - infoSymptomText: { - marginTop: 10 - }, - settingsButton: { - padding: 10, - alignItems: 'center', - margin: 10, - borderRadius: 5, - }, - settingsButtonAccent: { - backgroundColor: secondaryColor - }, - settingsButtonDisabled: { - backgroundColor: colorInActive - }, - settingsButtonText: { - color: fontOnPrimaryColor - }, - settingsButtonSecondaryText: { - color: secondaryColor - - }, - statsRow: { - flexDirection: 'row', - flexWrap: 'wrap' - }, - menuLabel: { - fontSize: 15, - color: fontOnPrimaryColor - }, - selectBox: { - backgroundColor: 'lightgrey', - marginRight: 7, - marginVertical: 5, - paddingHorizontal: 15, - paddingVertical: 10, - borderRadius: 10 - }, - selectBoxActive: { - backgroundColor: secondaryColor, - color: fontOnPrimaryColor - }, - selectBoxTextActive: { - color: fontOnPrimaryColor - }, - selectBoxSection: { - flexDirection: 'row', - flexWrap: 'wrap', - marginTop: 7, - }, - selectTabGroup: { - marginTop: 7, - flexDirection: 'row' - }, - selectTab: { - backgroundColor: 'lightgrey', - borderStyle: 'solid', - borderLeftWidth: 1, - paddingVertical: 10, - paddingHorizontal: 15, - borderColor: 'white', - marginBottom: 3, - alignItems: 'center', - justifyContent: 'center' - }, - selectTabActive: { - backgroundColor: secondaryColor, - color: fontOnPrimaryColor - }, - selectTabLast: { - borderTopRightRadius: 10, - borderBottomRightRadius: 10, - }, - selectTabFirst: { - borderTopLeftRadius: 10, - borderBottomLeftRadius: 10, - borderLeftWidth: null - }, - page: { - marginHorizontal: 10, - marginTop: 20, - }, - calendarToday: { - fontWeight: 'bold', - fontSize: 20, - color: secondaryColor, - marginTop: 1 - }, - passwordField: { - marginHorizontal: 10, - marginTop: 10 - }, - textInputField: { - padding: 10, - marginVertical: 10, - backgroundColor: 'white', - borderColor: secondaryColor, - borderStyle: 'solid', - borderWidth: 1, - }, - passwordPromptPage: { - padding: 30, - flex: 1, - justifyContent: 'center', - alignItems: 'center' - }, - passwordPromptField: { - padding: 10, - marginTop: 10, - marginHorizontal: 10, - borderBottomWidth: 3, - borderBottomColor: primaryColor, - width: '100%', - fontSize: 20, - marginVertical: 20 - }, - passwordPromptButton: { - backgroundColor: secondaryColor, - padding: 10, - alignItems: 'center', - margin: 10, - width: '100%', - borderRadius: 10 - }, - passwordPromptButtonText: { - color: fontOnPrimaryColor, - fontSize: 20 - }, - passwordPromptForgotPasswordText: { - marginTop: 20, - color: 'grey' - }, - headerDeleteButton: { - paddingHorizontal: 20, - paddingVertical: 20, - position: 'absolute', - right: 0 - }, - infoButtonSymptomView: { - position: 'absolute', - padding: 15, - right: 0 - }, - licensePage: { - paddingVertical: 20, - paddingHorizontal: 10 - }, - licenseButtons: { - flexDirection: 'row', - justifyContent: 'flex-end', - marginTop: 40 - }, - licenseButton: { - marginLeft: 30, - width: 100 - } -}) - -export const iconStyles = { - navigationArrow: { - size: 20, - color: fontOnPrimaryColor - }, - symptomHeaderIcons: { - size: 20, - color: fontOnPrimaryColor - }, - symptomBox: { - size: 40 - }, - symptomBoxActive: { - color: fontOnPrimaryColor - }, - info: { - color: secondaryColor, - fontSize: 25 - }, - menuIcon: { - size: 20, - color: fontOnPrimaryColor - }, - menuIconInactive: { - color: colorInActive, - }, - infoPopUpClose: { - size: 25 - } -} +export { Colors, Containers, Fonts, Spacing, Sizes, Typography } diff --git a/styles/spacing.js b/styles/spacing.js new file mode 100644 index 0000000000000000000000000000000000000000..50eb0d75915985dd24ea194d696dd38ece6ad56e --- /dev/null +++ b/styles/spacing.js @@ -0,0 +1,10 @@ +import { fontRatio } from '../config' + +export default { + tiny: 4 / fontRatio, + small: 10 / fontRatio, + base: 16 / fontRatio, + large: 20 / fontRatio, + symptomTileWidth: '48%', + textWidth: '70%' +} \ No newline at end of file diff --git a/styles/typography.js b/styles/typography.js new file mode 100644 index 0000000000000000000000000000000000000000..5b1bfd0385ce676f128e86abdf5860f1d25ab923 --- /dev/null +++ b/styles/typography.js @@ -0,0 +1,110 @@ +import { fontRatio } from '../config' + +import Colors from './colors' +import Spacing from './spacing' + +export const fonts = { + main: 'Jost-400-Book', + bold : 'Jost-700-Bold', +} + +export const sizes = { + tiny: 7 / fontRatio, + footnote: 10 / fontRatio, + small: 13 / fontRatio, + base: 18 / fontRatio, + subtitle: 22 / fontRatio, + title: 24 / fontRatio, + huge: 32 / fontRatio, + icon: 40 / fontRatio, +} + +const accentText = { + fontFamily: fonts.bold, + textAlignVertical: 'center', + textTransform: 'uppercase' +} + +const accentTextBig = { + ...accentText, + fontSize: 30 / fontRatio, +} + +const accentTextGiant = { + ...accentText, + fontSize: sizes.icon / fontRatio, +} + +const accentTextHuge = { + ...accentText, + fontSize: sizes.huge, +} + +const accentTextSmall = { + ...accentText, + fontSize: sizes.small +} + +const title = { + color: Colors.purple, + marginVertical: Spacing.large +} + +const label = { + fontSize: sizes.small, + textTransform: 'uppercase' +} + +export default { + accentOrange: { + ...accentTextSmall, + color: Colors.orange + }, + accentPurpleBig: { + ...accentTextBig, + color: Colors.purple + }, + accentPurpleGiant: { + ...accentTextGiant, + color: Colors.purple + }, + accentPurpleHuge: { + ...accentTextHuge, + color: Colors.purple + }, + mainText: { + fontFamily: fonts.main, + fontSize: sizes.base + }, + label: { + ...label + }, + labelBold: { + color: Colors.greyDark, + fontWeight: 'bold', + ...label + }, + labelLight: { + color: Colors.grey, + fontSize: sizes.footnote, + }, + subtitle: { + fontSize: sizes.subtitle, + ...title + }, + title: { + alignSelf: 'center', + fontFamily: fonts.bold, + fontWeight: '700', + fontSize: sizes.title, + marginHorizontal: Spacing.base, + ...title + }, + titleWithoutMargin: { + alignSelf: 'center', + color: Colors.purple, + fontFamily: fonts.bold, + fontWeight: '700', + fontSize: sizes.title, + } +} diff --git a/test/home-helpers.spec.js b/test/home-helpers.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..696a7b9482fb3e8da3f6fbd69cfa702c883960e2 --- /dev/null +++ b/test/home-helpers.spec.js @@ -0,0 +1,25 @@ +import { expect } from 'chai' + +import {getOrdinalSuffix } from '../components/helpers/home' + +describe('Home helper: getOrdinalSuffix', () => { + it('For 1, it returns suffix \'st\'', () => { + expect(getOrdinalSuffix(1)).to.eql('st') + }) + + it('For 2, it returns suffix \'nd\'', () => { + expect(getOrdinalSuffix(2)).to.eql('nd') + }) + + it('For 3, it returns suffix \'rd\'', () => { + expect(getOrdinalSuffix(3)).to.eql('rd') + }) + + it('For 11, it returns suffix \'th\'', () => { + expect(getOrdinalSuffix(11)).to.eql('th') + }) + + it('For 23, it returns suffix \'rd\'', () => { + expect(getOrdinalSuffix(23)).to.eql('rd') + }) +})