diff --git a/.eslintrc.json b/.eslintrc.json
index 2e0929e..b45a604 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -25,7 +25,8 @@
"jest"
],
"rules": {
- "space-before-function-paren": 0
+ "space-before-function-paren": 0,
+ "standard/no-callback-literal": 0
},
"settings": {
"react": {
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 6f14992..e9a0407 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -16,5 +16,9 @@ jobs:
run: npm ci
- name: Run JS linter
run: npm run lint
- - name: Run unit tests
- run: npm test
\ No newline at end of file
+ - name: Run unit tests with code coverage
+ run: npm run coverage:collect
+ - name: Generate code coverage report
+ uses: coverallsapp/github-action@master
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index b363e4e..e2e627a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
/node_modules
/dist
/lib
+/coverage
npm-debug.log*
.DS_Store
diff --git a/README.md b/README.md
index b6b0393..2d97019 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,27 @@
# react-speech-recognition
-A React component that converts speech from the microphone to text.
+A React hook that converts speech from the microphone to text and makes it available to your React components.
[![npm version](https://img.shields.io/npm/v/react-speech-recognition.svg)](https://www.npmjs.com/package/react-speech-recognition)
[![npm downloads](https://img.shields.io/npm/dm/react-speech-recognition.svg)](https://www.npmjs.com/package/react-speech-recognition)
[![license](https://img.shields.io/github/license/JamesBrill/react-speech-recognition.svg)](https://opensource.org/licenses/MIT)
-
+[![Coverage Status](https://coveralls.io/repos/github/JamesBrill/react-speech-recognition/badge.svg?branch=commands)](https://coveralls.io/github/JamesBrill/react-speech-recognition?branch=commands)
## How it works
-`SpeechRecognition` is a higher order component that wraps one of your React components.
-In doing so, it injects some additional properties into the component that allow it
-to access a transcript of speech picked up from the user's microphone.
+`useSpeechRecognition` is a React hook that gives a component access to a transcript of speech picked up from the user's microphone.
+
+`SpeechRecognition` manages the global state of the Web Speech API, exposing functions to turn the microphone on and off.
Under the hood,
-it uses [Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition).
-Currently, **this component will only work in Chrome**. It fails gracefully on other browsers.
+it uses [Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition). Note that browser support for this API is currently limited, with Chrome having the best experience - see [supported browsers](#supported-browsers) for more information.
+
+This version requires React 16.8 so that React hooks can be used. If you're used to version 2.x of `react-speech-recognition` or want to use an older version of React, you can see the old README [here](https://github.com/JamesBrill/react-speech-recognition/tree/v2.1.4). If you want to migrate to version 3.x, see the migration guide [here](docs/V3-MIGRATION.md).
-It is recommended that you use Webpack to bundle this module with your web code.
+## Useful links
+* [Basic example](#basic-example)
+* [Supported browsers](#supported-browsers)
+* [API docs](docs/API.md)
+* [Version 3 migration guide](docs/V3-MIGRATION.md)
## Installation
@@ -26,138 +31,194 @@ To install:
To import in your React code:
-`import SpeechRecognition from 'react-speech-recognition'`
+`import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition'`
-## Example usage
+## Basic example
-As only one component can be wrapped by `SpeechRecognition`, it is recommended that you add it to one of your root React components such as `App`. The transcription can then be passed down to child components.
+The most basic example of a component using this hook would be:
```
-import React, { Component } from "react";
-import PropTypes from "prop-types";
-import SpeechRecognition from "react-speech-recognition";
+import React from 'react'
+import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition'
-const propTypes = {
- // Props injected by SpeechRecognition
- transcript: PropTypes.string,
- resetTranscript: PropTypes.func,
- browserSupportsSpeechRecognition: PropTypes.bool
-};
+const Dictaphone = () => {
+ const { transcript, resetTranscript } = useSpeechRecognition()
-const Dictaphone = ({
- transcript,
- resetTranscript,
- browserSupportsSpeechRecognition
-}) => {
- if (!browserSupportsSpeechRecognition) {
- return null;
+ if (!SpeechRecognition.browserSupportsSpeechRecognition()) {
+ return null
}
return (
+
Start
+
Stop
Reset
-
{transcript}
+
{transcript}
- );
-};
-
-Dictaphone.propTypes = propTypes;
-
-export default SpeechRecognition(Dictaphone);
+ )
+}
+export default Dictaphone
```
-## Global options
+You can see more examples in the example React app attached to this repo. See [Developing](#developing).
+
+## Detecting browser support for Web Speech API
-You can configure the default initial state of the Speech Recognition API. To change these defaults, you need to pass an options object into the wrapper like so:
+Currently, this feature is not supported in all browsers, with the best experience being available on desktop Chrome. However, it fails gracefully on other browsers. It is recommended that you render some fallback content if it is not supported by the user's browser:
```
-const options = {
- autoStart: false
+if (!SpeechRecognition.browserSupportsSpeechRecognition()) {
+ // Render some fallback content
}
-
-export default SpeechRecognition(options)(YourComponent)
```
-### autoStart [bool]
+### Supported browsers
-By default, the Speech Recognition API will immediately start listening to speech from the microphone. To have the API initially turned off, set this to `false`.
+As of June 2020, the following browsers support the Web Speech API:
-### continuous [bool]
+* Chrome (desktop): this is by far the smoothest experience
+* Microsoft Edge
+* Chrome (Android): a word of warning about this platform, which is that there can be an annoying beeping sound when turning the microphone on. This is part of the Android OS and cannot be controlled from the browser
+* Android webview
+* Samsung Internet
-By default, the Speech Recognition API is continuously listening to speech from the microphone when it is turned on. To have the API stop listening after the user has finished speaking, set this to `false`. For example, if you are building a chat app that only starts listening to the user's speech after a button click, you should set both `continuous` and `autoStart` options to `false`. Call [startListening](https://github.com/JamesBrill/react-speech-recognition#startListening-function) to make the API start listening again.
+For all other browsers, you can render fallback content using the `SpeechRecognition.browserSupportsSpeechRecognition` function described above.
-## Props added to your component
+## Controlling the microphone
-### transcript [string]
+Before consuming the transcript, you should be familiar with `SpeechRecognition`, which gives you control over the microphone. The state of the microphone is global, so any functions you call on this object will affect _all_ components using `useSpeechRecognition`.
-Transcription of all speech that has been spoken into the microphone. Is equivalent to the final transcript followed by the interim transcript, separated by a space.
+### Turning the microphone on
-### resetTranscript [function]
+To start listening to speech, call the `startListening` function.
-Sets the transcription to an empty string.
+```
+SpeechRecognition.startListening()
+```
-### startListening [function]
+This is an asynchronous function, so it will need to be awaited if you want to do something after the microphone has been turned on.
-Causes the Web Speech API to start listening to speech from the microphone.
+### Turning the microphone off
-NOTE: if the `continuous` option is set to `false`, then `startListening` will reset the `transcript` prop.
+To turn the microphone off, but still finish processing any speech in progress, call `stopListening`.
-### stopListening [function]
+```
+SpeechRecognition.stopListening()
+```
-Causes the Web Speech API to stop listening to speech from the microphone, but will finish processing any remaining speech.
+To turn the microphone off, and cancel the processing of any speech in progress, call `abortListening`.
-### abortListening [function]
+```
+SpeechRecognition.abortListening()
+```
-Causes the Web Speech API to stop listening to speech from the microphone, and also stop processing the current speech.
+## Consuming the microphone transcript
-### browserSupportsSpeechRecognition [bool]
+To make the microphone transcript available in your component, simply add:
-If false, the browser does not support the Speech Recognition API.
+```
+const { transcript } = useSpeechRecognition()
+```
-### listening [bool]
+## Resetting the microphone transcript
-If true, the Web Speech API is listening to speech from the microphone.
+To set the transcript to an empty string, you can call the `resetTranscript` function provided by `useSpeechRecognition`. Note that this is local to your component and does not affect any other components using Speech Recognition.
-### interimTranscript [string]
+```
+const { resetTranscript } = useSpeechRecognition()
+```
-Transcription of speech for which transcription hasn't finished yet.
+## Commands
-For the current words being spoken, the interim transcript reflects each successive guess made by the transcription algorithm. When the browser’s confidence in its guess is maximized, it is added to the final transcript.
+To respond when the user says a particular phrase, you can pass in a list of commands to the `useSpeechRecognition` hook. Each command is an object with the following properties:
+- `command`: This is a string or `RegExp` representing the phrase you want to listen for
+- `callback`: The function that is executed when the command is spoken
+- `matchInterim`: Boolean that determines whether "interim" results should be matched against the command. This will make your component respond faster to commands, but also makes false positives more likely - i.e. the command may be detected when it is not spoken. This is `false` by default and should only be set for simple commands.
-The difference between interim and final transcripts can be illustrated by an example over four iterations of the transcription algorithm:
+### Command symbols
-| Final transcript | Interim transcript |
-|-------------------|--------------------|
-| 'Hello, I am' | 'jam' |
-| 'Hello, I am' | 'jams' |
-| 'Hello, I am' | 'James' |
-| 'Hello, I am James' | '' |
+To make commands easier to write, the following symbols are supported:
+- Splats: this is just a `*` and will match multi-word text:
+ - Example: `'I would like to order *'`
+ - The words that match the splat will be passed into the callback, one argument per splat
+- Named variables: this is written `:` and will match a single word:
+ - Example: `'I am :height metres tall'`
+ - The one word that matches the named variable will be passed into the callback
+- Optional words: this is a phrase wrapped in parentheses `(` and `)`, and is not required to match the command:
+ - Example: `'Pass the salt (please)'`
+ - The above example would match both `'Pass the salt'` and `'Pass the salt please'`
-### finalTranscript [string]
+### Example with commands
-Transcription of speech for which transcription has finished.
+```
+import React, { useState } from 'react'
+import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition'
+
+const Dictaphone = () => {
+ const [message, setMessage] = useState('')
+ const commands = [
+ {
+ command: 'I would like to order *',
+ callback: (food) => setMessage(`Your order is for: ${food}`)
+ },
+ {
+ command: 'The weather is :condition today',
+ callback: (condition) => setMessage(`Today, the weather is ${condition}`)
+ },
+ {
+ command: 'My top sports are * and *',
+ callback: (sport1, sport2) => setMessage(`#1: ${sport1}, #2: ${sport2}`)
+ },
+ {
+ command: 'Pass the salt (please)',
+ callback: () => setMessage('My pleasure')
+ },
+ {
+ command: 'Hello',
+ callback: () => setMessage('Hi there!'),
+ matchInterim: true
+ }
+ ]
+
+ const { transcript } = useSpeechRecognition({ commands })
+
+ if (!SpeechRecognition.browserSupportsSpeechRecognition()) {
+ return null
+ }
-### recognition [Object]
+ return (
+
+
{message}
+
{transcript}
+
+ )
+}
+export default Dictaphone
+```
-The underlying [object](https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition) used
-by Web Speech API. It can be used to change the
-transcription language, which is the browser language if not specified. For example, to set the transcription language to Chinese:
+## Continuous listening
-`recognition.lang = 'zh-CN'`
+By default, the microphone will stop listening when the user stops speaking. This reflects the approach taken by "press to talk" buttons on modern devices.
-## Troubleshooting
+If you want to listen continuously, set the `continuous` property to `true` when calling `startListening`. The microphone will continue to listen, even after the user has stopped speaking.
-### How to use `react-speech-recognition` offline?
+```
+SpeechRecognition.startListening({ continuous: true })
+```
-Unfortunately, speech recognition will not function in Chrome when offline. According to the [Web Speech API docs](https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API/Using_the_Web_Speech_API): `On Chrome, using Speech Recognition on a web page involves a server-based recognition engine. Your audio is sent to a web service for recognition processing, so it won't work offline.`
+## Changing language
-If you are building an offline web app, you can detect when the browser is offline by inspecting the value of `navigator.onLine`. If it is `true`, you can render the transcript generated by React Speech Recognition. If it is `false`, it's advisable to render offline fallback content that signifies that speech recognition is disabled. The online/offline API is simple to use - you can read how to use it [here](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/Online_and_offline_events).
+To listen for a specific language, you can pass a language tag (e.g. `'zh-CN'` for Chinese) when calling `startListening`. See [here](docs/API.md#language-string) for a list of supported languages.
-### The transcript contains duplicate words!
+```
+SpeechRecognition.startListening({ language: 'zh-CN' })
+```
-There is a [bug in Android Chrome](https://stackoverflow.com/questions/35112561/speech-recognition-api-duplicated-phrases-on-android/43458449#43458449) that causes the Web Speech API to generate duplicate words in the speech recognition result. Possible workarounds:
-- Set the `continuous` option to `false`
-- [Detect Android Chrome](https://stackoverflow.com/questions/21741841/detecting-ios-android-operating-system) and render fallback content on that browser
+## How to use `react-speech-recognition` offline?
+
+Unfortunately, speech recognition will not function in Chrome when offline. According to the [Web Speech API docs](https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API/Using_the_Web_Speech_API): `On Chrome, using Speech Recognition on a web page involves a server-based recognition engine. Your audio is sent to a web service for recognition processing, so it won't work offline.`
+
+If you are building an offline web app, you can detect when the browser is offline by inspecting the value of `navigator.onLine`. If it is `true`, you can render the transcript generated by React Speech Recognition. If it is `false`, it's advisable to render offline fallback content that signifies that speech recognition is disabled. The online/offline API is simple to use - you can read how to use it [here](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/Online_and_offline_events).
## Developing
@@ -169,6 +230,10 @@ npm run dev
On `http://localhost:3000`, you'll be able to speak into the microphone and see your speech as text on the web page. There are also controls for turning speech recognition on and off. You can make changes to the web app itself in the `example` directory. Any changes you make to the web app or `react-speech-recognition` itself will be live reloaded in the browser.
+## API docs
+
+View the API docs [here](docs/API.md) or follow the guide above to learn how to use `react-speech-recognition`.
+
## License
MIT
diff --git a/docs/API.md b/docs/API.md
new file mode 100644
index 0000000..c260a00
--- /dev/null
+++ b/docs/API.md
@@ -0,0 +1,238 @@
+# API docs
+
+## Interface
+
+* [useSpeechRecognition](#useSpeechRecognition)
+* [SpeechRecognition](#SpeechRecognition)
+
+## useSpeechRecognition
+
+React hook for consuming speech recorded by the microphone. Import with:
+
+```
+import { useSpeechRecognition } from 'react-speech-recognition'
+```
+
+### Input props
+
+These are passed as an object argument to `useSpeechRecognition`:
+
+```
+useSpeechRecognition({ transcribing, clearTranscriptOnListen, commands })
+```
+
+#### transcribing [bool]
+
+Is this component collecting a transcript or not? This is independent of the global `listening` state of the microphone. `true` by default.
+
+#### clearTranscriptOnListen [bool]
+
+Does this component clear its transcript when the microphone is turned on? Has no effect when continuous listening is enabled. `true` by default.
+
+#### commands [list]
+
+See [Commands](../README.md#Commands).
+
+### Output state
+
+These are returned from `useSpeechRecognition`:
+
+```
+ const {
+ transcript,
+ interimTranscript,
+ finalTranscript,
+ resetTranscript,
+ listening,
+ } = useSpeechRecognition()
+```
+
+#### transcript [string]
+
+Transcription of all speech that has been spoken into the microphone. Is equivalent to the final transcript followed by the interim transcript, separated by a space.
+
+#### resetTranscript [function]
+
+Sets `transcript` to an empty string.
+
+#### listening [bool]
+
+If true, the Web Speech API is listening to speech from the microphone.
+
+#### interimTranscript [string]
+
+Transcription of speech that the Web Speech API is still processing (i.e. it's still deciding what has just been spoken).
+
+For the current words being spoken, the interim transcript reflects each successive guess made by the transcription algorithm. When the browser’s confidence in its guess is maximized, it is added to the final transcript.
+
+The difference between interim and final transcripts can be illustrated by an example over four iterations of the transcription algorithm:
+
+| Final transcript | Interim transcript |
+|-------------------|--------------------|
+| 'Hello, I am' | 'jam' |
+| 'Hello, I am' | 'jams' |
+| 'Hello, I am' | 'James' |
+| 'Hello, I am James' | '' |
+
+#### finalTranscript [string]
+
+Transcription of speech that the Web Speech API has finished processing.
+
+## SpeechRecognition
+
+Object providing functions to manage the global state of the microphone. Import with:
+
+```
+import SpeechRecognition from 'react-speech-recognition'
+```
+
+### Functions
+
+#### startListening (async)
+
+Start listening to speech.
+
+```
+SpeechRecognition.startListening()
+```
+
+This is an asynchronous function, so it will need to be awaited if you want to do something after the microphone has been turned on.
+
+It can be called with an options argument. For example:
+
+```
+SpeechRecognition.startListening({
+ continuous: true,
+ language: 'zh-CN'
+})
+```
+
+The following options are available:
+
+##### continuous [bool]
+
+By default, the microphone will stop listening when the user stops speaking (`continuous: false`). This reflects the approach taken by "press to talk" buttons on modern devices.
+
+If you want to listen continuously, set the `continuous` property to `true` when calling `startListening`. The microphone will continue to listen, even after the user has stopped speaking.
+
+```
+SpeechRecognition.startListening({ continuous: true })
+```
+
+##### language [string]
+
+To listen for a specific language, you can pass a language tag (e.g. `'zh-CN'` for Chinese) when calling `startListening`.
+
+```
+SpeechRecognition.startListening({ language: 'zh-CN' })
+```
+
+Some known supported languages (based on [this Stack Overflow post](http://stackoverflow.com/a/14302134/338039)):
+
+* Afrikaans `af`
+* Basque `eu`
+* Bulgarian `bg`
+* Catalan `ca`
+* Arabic (Egypt) `ar-EG`
+* Arabic (Jordan) `ar-JO`
+* Arabic (Kuwait) `ar-KW`
+* Arabic (Lebanon) `ar-LB`
+* Arabic (Qatar) `ar-QA`
+* Arabic (UAE) `ar-AE`
+* Arabic (Morocco) `ar-MA`
+* Arabic (Iraq) `ar-IQ`
+* Arabic (Algeria) `ar-DZ`
+* Arabic (Bahrain) `ar-BH`
+* Arabic (Lybia) `ar-LY`
+* Arabic (Oman) `ar-OM`
+* Arabic (Saudi Arabia) `ar-SA`
+* Arabic (Tunisia) `ar-TN`
+* Arabic (Yemen) `ar-YE`
+* Czech `cs`
+* Dutch `nl-NL`
+* English (Australia) `en-AU`
+* English (Canada) `en-CA`
+* English (India) `en-IN`
+* English (New Zealand) `en-NZ`
+* English (South Africa) `en-ZA`
+* English(UK) `en-GB`
+* English(US) `en-US`
+* Finnish `fi`
+* French `fr-FR`
+* Galician `gl`
+* German `de-DE`
+* Greek `el-GR`
+* Hebrew `he`
+* Hungarian `hu`
+* Icelandic `is`
+* Italian `it-IT`
+* Indonesian `id`
+* Japanese `ja`
+* Korean `ko`
+* Latin `la`
+* Mandarin Chinese `zh-CN`
+* Taiwanese `zh-TW`
+* Cantonese `zh-HK`
+* Malaysian `ms-MY`
+* Norwegian `no-NO`
+* Polish `pl`
+* Pig Latin `xx-piglatin`
+* Portuguese `pt-PT`
+* Portuguese (Brasil) `pt-br`
+* Romanian `ro-RO`
+* Russian `ru`
+* Serbian `sr-SP`
+* Slovak `sk`
+* Spanish (Argentina) `es-AR`
+* Spanish (Bolivia) `es-BO`
+* Spanish (Chile) `es-CL`
+* Spanish (Colombia) `es-CO`
+* Spanish (Costa Rica) `es-CR`
+* Spanish (Dominican Republic) `es-DO`
+* Spanish (Ecuador) `es-EC`
+* Spanish (El Salvador) `es-SV`
+* Spanish (Guatemala) `es-GT`
+* Spanish (Honduras) `es-HN`
+* Spanish (Mexico) `es-MX`
+* Spanish (Nicaragua) `es-NI`
+* Spanish (Panama) `es-PA`
+* Spanish (Paraguay) `es-PY`
+* Spanish (Peru) `es-PE`
+* Spanish (Puerto Rico) `es-PR`
+* Spanish (Spain) `es-ES`
+* Spanish (US) `es-US`
+* Spanish (Uruguay) `es-UY`
+* Spanish (Venezuela) `es-VE`
+* Swedish `sv-SE`
+* Turkish `tr`
+* Zulu `zu`
+
+#### stopListening
+
+Turn the microphone off, but still finish processing any speech in progress.
+
+```
+SpeechRecognition.stopListening()
+```
+
+#### abortListening
+
+Turn the microphone off, and cancel the processing of any speech in progress.
+
+```
+SpeechRecognition.abortListening()
+```
+
+#### browserSupportsSpeechRecognition
+
+The Web Speech API is not supported on all browsers, so it is recommended that you render some fallback content if it is not supported by the user's browser:
+
+```
+if (!SpeechRecognition.browserSupportsSpeechRecognition()) {
+ // Render some fallback content
+}
+```
+
+#### getRecognition
+
+This returns the underlying [object](https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition) used by Web Speech API.
\ No newline at end of file
diff --git a/docs/V3-MIGRATION.md b/docs/V3-MIGRATION.md
new file mode 100644
index 0000000..636c1c0
--- /dev/null
+++ b/docs/V3-MIGRATION.md
@@ -0,0 +1,144 @@
+# Migrating from v2 to v3
+
+v3 makes use of React hooks to simplify the consumption of `react-speech-recognition`:
+* Replacing the higher order component with a React hook
+* Introducing commands, functions that get executed when the user says a particular phrase
+* A clear separation between all parts of `react-speech-recognition` that are global (e.g. whether the microphone is listening or not) and local (e.g. transcripts). This makes it possible to have multiple components consuming the global microphone input while maintaining their own transcripts and commands
+* Some default prop values have changed so check those out below
+
+## The original Dictaphone example
+
+### In v2
+
+```
+import React, { Component } from "react";
+import PropTypes from "prop-types";
+import SpeechRecognition from "react-speech-recognition";
+
+const propTypes = {
+ // Props injected by SpeechRecognition
+ transcript: PropTypes.string,
+ resetTranscript: PropTypes.func,
+ browserSupportsSpeechRecognition: PropTypes.bool
+};
+
+const Dictaphone = ({
+ transcript,
+ resetTranscript,
+ browserSupportsSpeechRecognition
+}) => {
+ if (!browserSupportsSpeechRecognition) {
+ return null;
+ }
+
+ return (
+
+ Reset
+ {transcript}
+
+ );
+};
+
+Dictaphone.propTypes = propTypes;
+
+export default SpeechRecognition(Dictaphone);
+```
+
+### In v3
+
+```
+import React, { useEffect } from 'react'
+import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition'
+
+const Dictaphone = () => {
+ const { transcript, resetTranscript } = useSpeechRecognition()
+
+ useEffect(() => {
+ SpeechRecognition.startListening({ continuous: true })
+ }, []);
+
+ if (!SpeechRecognition.browserSupportsSpeechRecognition()) {
+ return null
+ }
+
+ return (
+
+ )
+}
+export default Dictaphone
+```
+
+## autoStart
+
+This was a global option in v2 that would cause the microphone to start listening from the beginning by default. In v3, the microphone is initially turned off by default. It can be turned on when your component first renders by either `useEffect` if you're using hooks or `componentDidMount` if you're still using class components. It is recommended that you do this close to the root of your application as this affects global state.
+
+```
+useEffect(() => {
+ SpeechRecognition.startListening({ continuous: true })
+}, []);
+```
+
+## continuous
+
+This was another global option in v2 that would by default have the microphone permanently listen to the user, even when they finished speaking. This default behaviour did not match the most common usage pattern, which is to use `react-speech-recognition` for "press to talk" buttons that stop listening once a command has been spoken.
+
+`continuous` is now an option that can be passed to `SpeechRecognition.startListening`. It is `false` by default, but can be overridden like so:
+
+```
+SpeechRecognition.startListening({ continuous: true })
+```
+
+## clearTranscriptOnListen
+
+This is a new prop in v3 that is passed into `useSpeechRecognition` from the consumer. Its default value makes a subtle change to the previous behaviour. When `continuous` was set to `false` in v2, the transcript would not be reset when the microphone started listening again. `clearTranscriptOnListen` changes that, clearing the component's transcript at the beginning of every new discontinuous speech. To replicate the old behaviour, this can be turned off when passing props into `useSpeechRecognition`:
+
+```
+const { transcript } = useSpeechRecognition({ clearTranscriptOnListen: false })
+```
+
+## Injected props
+
+`SpeechRecognition` used to inject props into components in v2. These props are still available, but in different forms.
+
+### transcript
+
+This is now state returned by `useSpeechRecognition`. This transcript is local to the component using the hook.
+
+### resetTranscript
+
+This is now state returned by `useSpeechRecognition`. This only resets the component's transcript, not any global state.
+
+### startListening
+
+This is now available as `SpeechRecognition.startListening`, an asynchronous function documented [here](API.md#startListening-async).
+
+### stopListening
+
+This is now available as `SpeechRecognition.stopListening`, documented [here](API.md#stopListening).
+
+### abortListening
+
+This is now available as `SpeechRecognition.abortListening`, documented [here](API.md#abortListening).
+
+### browserSupportsSpeechRecognition
+
+This is now available as the function `SpeechRecognition.browserSupportsSpeechRecognition`, documented [here](API.md#browserSupportsSpeechRecognition).
+
+### listening
+
+This is now state returned by `useSpeechRecognition`. This is the global listening state.
+
+### interimTranscript
+
+This is now state returned by `useSpeechRecognition`. This transcript is local to the component using the hook.
+
+### finalTranscript
+
+This is now state returned by `useSpeechRecognition`. This transcript is local to the component using the hook.
+
+### recognition
+
+This is now returned by the function `SpeechRecognition.getRecognition`, documented [here](API.md#getRecognition).
diff --git a/example/src/Dictaphone.js b/example/src/Dictaphone.js
deleted file mode 100644
index ba6bc32..0000000
--- a/example/src/Dictaphone.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-import SpeechRecognition from './SpeechRecognition'
-
-const propTypes = {
- // Props injected by SpeechRecognition
- transcript: PropTypes.string,
- resetTranscript: PropTypes.func,
- browserSupportsSpeechRecognition: PropTypes.bool
-}
-
-const Dictaphone = ({
- transcript,
- resetTranscript,
- startListening,
- stopListening,
- browserSupportsSpeechRecognition
-}) => {
- if (!browserSupportsSpeechRecognition) {
- return null
- }
-
- return (
-
- Reset
- Start
- Stop
- {transcript}
-
- )
-}
-
-Dictaphone.propTypes = propTypes
-
-export default SpeechRecognition(Dictaphone)
diff --git a/example/src/Dictaphone/Dictaphone.js b/example/src/Dictaphone/Dictaphone.js
new file mode 100644
index 0000000..0dbc024
--- /dev/null
+++ b/example/src/Dictaphone/Dictaphone.js
@@ -0,0 +1,42 @@
+import React, { useState, useEffect } from 'react'
+import SpeechRecognition, { useSpeechRecognition } from '../SpeechRecognition'
+
+const Dictaphone = ({ commands }) => {
+ const [transcribing, setTranscribing] = useState(true)
+ const [clearTranscriptOnListen, setClearTranscriptOnListen] = useState(true)
+ const toggleTranscribing = () => setTranscribing(!transcribing)
+ const toggleClearTranscriptOnListen = () => setClearTranscriptOnListen(!clearTranscriptOnListen)
+ const {
+ transcript,
+ interimTranscript,
+ finalTranscript,
+ resetTranscript,
+ listening,
+ } = useSpeechRecognition({ transcribing, clearTranscriptOnListen, commands })
+ useEffect(() => {
+ if (interimTranscript !== '') {
+ console.log('Got interim result:', interimTranscript)
+ }
+ if (finalTranscript !== '') {
+ console.log('Got final result:', finalTranscript)
+ }
+ }, [interimTranscript, finalTranscript]);
+
+ if (!SpeechRecognition.browserSupportsSpeechRecognition()) {
+ return null
+ }
+
+ return (
+
+ listening: {listening ? 'on' : 'off'}
+ transcribing: {transcribing ? 'on' : 'off'}
+ clearTranscriptOnListen: {clearTranscriptOnListen ? 'on' : 'off'}
+ Reset
+ Toggle transcribing
+ Toggle clearTranscriptOnListen
+ {transcript}
+
+ )
+}
+
+export default Dictaphone
\ No newline at end of file
diff --git a/example/src/Dictaphone/DictaphoneWidgetA.js b/example/src/Dictaphone/DictaphoneWidgetA.js
new file mode 100644
index 0000000..ac58a73
--- /dev/null
+++ b/example/src/Dictaphone/DictaphoneWidgetA.js
@@ -0,0 +1,32 @@
+import React, { useState } from 'react'
+import Dictaphone from './Dictaphone'
+
+const DictaphoneWidgetA = () => {
+ const [message, setMessage] = useState('')
+ const commands = [
+ {
+ command: 'I would like to order *',
+ callback: (food) => setMessage(`Your order is for: ${food}`),
+ matchInterim: true
+ },
+ {
+ command: 'The weather is :condition today',
+ callback: (condition) => setMessage(`Today, the weather is ${condition}`)
+ },
+ {
+ command: 'Hello',
+ callback: () => setMessage('Hi there'),
+ matchInterim: true
+ }
+ ]
+
+ return (
+
+
Dictaphone A
+
{message}
+
+
+ )
+}
+
+export default DictaphoneWidgetA
\ No newline at end of file
diff --git a/example/src/Dictaphone/DictaphoneWidgetB.js b/example/src/Dictaphone/DictaphoneWidgetB.js
new file mode 100644
index 0000000..a801189
--- /dev/null
+++ b/example/src/Dictaphone/DictaphoneWidgetB.js
@@ -0,0 +1,36 @@
+import React, { useState } from 'react'
+import Dictaphone from './Dictaphone'
+
+const DictaphoneWidgetB = () => {
+ const [message, setMessage] = useState('')
+ const commands = [
+ {
+ command: '* is my name',
+ callback: (name) => setMessage(`Hi ${name}!`),
+ matchInterim: true
+ },
+ {
+ command: 'My top sports are * and *',
+ callback: (sport1, sport2) => setMessage(`#1: ${sport1}, #2: ${sport2}`)
+ },
+ {
+ command: 'Goodbye',
+ callback: () => setMessage('So long!'),
+ matchInterim: true
+ },
+ {
+ command: 'Pass the salt (please)',
+ callback: () => setMessage('My pleasure')
+ }
+ ]
+
+ return (
+
+
Dictaphone B
+
{message}
+
+
+ )
+}
+
+export default DictaphoneWidgetB
\ No newline at end of file
diff --git a/example/src/Dictaphone/index.js b/example/src/Dictaphone/index.js
new file mode 100644
index 0000000..ff8521a
--- /dev/null
+++ b/example/src/Dictaphone/index.js
@@ -0,0 +1,4 @@
+import DictaphoneWidgetA from './DictaphoneWidgetA'
+import DictaphoneWidgetB from './DictaphoneWidgetB'
+
+export { DictaphoneWidgetA, DictaphoneWidgetB }
\ No newline at end of file
diff --git a/example/src/Dictaphones.js b/example/src/Dictaphones.js
new file mode 100644
index 0000000..da45a8b
--- /dev/null
+++ b/example/src/Dictaphones.js
@@ -0,0 +1,34 @@
+import React, { useState } from 'react'
+import { DictaphoneWidgetA, DictaphoneWidgetB } from './Dictaphone'
+import SpeechRecognition from './SpeechRecognition'
+
+export default () => {
+ const [showFirstWidget, setShowFirstWidget] = useState(true)
+ const toggleShowFirstWidget = () => setShowFirstWidget(!showFirstWidget)
+
+ const listenContinuously = () => SpeechRecognition.startListening({
+ continuous: true,
+ language: 'en-GB'
+ })
+ const listenContinuouslyInChinese = () => SpeechRecognition.startListening({
+ continuous: true,
+ language: 'zh-CN'
+ })
+ const listenOnce = () => SpeechRecognition.startListening({ continuous: false })
+
+ if (!SpeechRecognition.browserSupportsSpeechRecognition()) {
+ return null
+ }
+
+ return (
+
+ {showFirstWidget && }
+
+ Listen once
+ Listen continuously
+ Listen continuously (Chinese)
+ Toggle first widget
+ Stop
+
+ )
+}
diff --git a/example/src/index.js b/example/src/index.js
index 40b4c07..763e258 100644
--- a/example/src/index.js
+++ b/example/src/index.js
@@ -1,10 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom';
-import Dictaphone from './Dictaphone';
+import Dictaphones from './Dictaphones';
ReactDOM.render(
-
+
,
document.getElementById('root')
);
diff --git a/package-lock.json b/package-lock.json
index c2fa095..28285b1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,13 +1,13 @@
{
"name": "react-speech-recognition",
- "version": "2.1.4",
+ "version": "3.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@babel/cli": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.10.3.tgz",
- "integrity": "sha512-lWB3yH5/fWY8pi2Kj5/fA+17guJ9feSBw5DNjTju3/nRi9sXnl1JPh7aKQOSvdNbiDbkzzoGYtsr46M8dGmXDQ==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.10.4.tgz",
+ "integrity": "sha512-xX99K4V1BzGJdQANK5cwK+EpF1vP9gvqhn+iWvG+TubCjecplW7RSQimJ2jcCvu6fnK5pY6mZMdu6EWTj32QVA==",
"dev": true,
"requires": {
"chokidar": "^2.1.8",
@@ -22,18 +22,18 @@
}
},
"@babel/code-frame": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.3.tgz",
- "integrity": "sha512-fDx9eNW0qz0WkUeqL6tXEXzVlPh6Y5aCDEZesl0xBGA8ndRukX91Uk44ZqnkECp01NAZUdCAl+aiQNGi0k88Eg==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+ "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.10.3"
+ "@babel/highlight": "^7.10.4"
}
},
"@babel/compat-data": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.10.3.tgz",
- "integrity": "sha512-BDIfJ9uNZuI0LajPfoYV28lX8kyCPMHY6uY4WH1lJdcicmAfxCK5ASzaeV0D/wsUaRH/cLk+amuxtC37sZ8TUg==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.10.4.tgz",
+ "integrity": "sha512-t+rjExOrSVvjQQXNp5zAIYDp00KjdvGl/TpDX5REPr0S9IAIPQMTilcfG6q8c0QFmj9lSTVySV2VTsyggvtNIw==",
"dev": true,
"requires": {
"browserslist": "^4.12.0",
@@ -42,19 +42,19 @@
}
},
"@babel/core": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.3.tgz",
- "integrity": "sha512-5YqWxYE3pyhIi84L84YcwjeEgS+fa7ZjK6IBVGTjDVfm64njkR2lfDhVR5OudLk8x2GK59YoSyVv+L/03k1q9w==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.10.3",
- "@babel/generator": "^7.10.3",
- "@babel/helper-module-transforms": "^7.10.1",
- "@babel/helpers": "^7.10.1",
- "@babel/parser": "^7.10.3",
- "@babel/template": "^7.10.3",
- "@babel/traverse": "^7.10.3",
- "@babel/types": "^7.10.3",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.4.tgz",
+ "integrity": "sha512-3A0tS0HWpy4XujGc7QtOIHTeNwUgWaZc/WuS5YQrfhU67jnVmsD6OGPc1AKHH0LJHQICGncy3+YUjIhVlfDdcA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/generator": "^7.10.4",
+ "@babel/helper-module-transforms": "^7.10.4",
+ "@babel/helpers": "^7.10.4",
+ "@babel/parser": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.10.4",
+ "@babel/types": "^7.10.4",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.1",
@@ -83,64 +83,64 @@
}
},
"@babel/generator": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.3.tgz",
- "integrity": "sha512-drt8MUHbEqRzNR0xnF8nMehbY11b1SDkRw03PSNH/3Rb2Z35oxkddVSi3rcaak0YJQ86PCuE7Qx1jSFhbLNBMA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz",
+ "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==",
"dev": true,
"requires": {
- "@babel/types": "^7.10.3",
+ "@babel/types": "^7.10.4",
"jsesc": "^2.5.1",
"lodash": "^4.17.13",
"source-map": "^0.5.0"
}
},
"@babel/helper-annotate-as-pure": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz",
- "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==",
+ "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==",
"dev": true,
"requires": {
- "@babel/types": "^7.10.1"
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-builder-binary-assignment-operator-visitor": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.3.tgz",
- "integrity": "sha512-lo4XXRnBlU6eRM92FkiZxpo1xFLmv3VsPFk61zJKMm7XYJfwqXHsYJTY6agoc4a3L8QPw1HqWehO18coZgbT6A==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-explode-assignable-expression": "^7.10.3",
- "@babel/types": "^7.10.3"
+ "@babel/helper-explode-assignable-expression": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-builder-react-jsx": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.3.tgz",
- "integrity": "sha512-vkxmuFvmovtqTZknyMGj9+uQAZzz5Z9mrbnkJnPkaYGfKTaSsYcjQdXP0lgrWLVh8wU6bCjOmXOpx+kqUi+S5Q==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-annotate-as-pure": "^7.10.1",
- "@babel/types": "^7.10.3"
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-builder-react-jsx-experimental": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.1.tgz",
- "integrity": "sha512-irQJ8kpQUV3JasXPSFQ+LCCtJSc5ceZrPFVj6TElR6XCHssi3jV8ch3odIrNtjJFRZZVbrOEfJMI79TPU/h1pQ==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.4.tgz",
+ "integrity": "sha512-LyacH/kgQPgLAuaWrvvq1+E7f5bLyT8jXCh7nM67sRsy2cpIGfgWJ+FCnAKQXfY+F0tXUaN6FqLkp4JiCzdK8Q==",
"dev": true,
"requires": {
- "@babel/helper-annotate-as-pure": "^7.10.1",
- "@babel/helper-module-imports": "^7.10.1",
- "@babel/types": "^7.10.1"
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "@babel/helper-module-imports": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-compilation-targets": {
- "version": "7.10.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz",
- "integrity": "sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz",
+ "integrity": "sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ==",
"dev": true,
"requires": {
- "@babel/compat-data": "^7.10.1",
+ "@babel/compat-data": "^7.10.4",
"browserslist": "^4.12.0",
"invariant": "^2.2.4",
"levenary": "^1.1.1",
@@ -148,337 +148,337 @@
}
},
"@babel/helper-create-class-features-plugin": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.3.tgz",
- "integrity": "sha512-iRT9VwqtdFmv7UheJWthGc/h2s7MqoweBF9RUj77NFZsg9VfISvBTum3k6coAhJ8RWv2tj3yUjA03HxPd0vfpQ==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.4.tgz",
+ "integrity": "sha512-9raUiOsXPxzzLjCXeosApJItoMnX3uyT4QdM2UldffuGApNrF8e938MwNpDCK9CPoyxrEoCgT+hObJc3mZa6lQ==",
"dev": true,
"requires": {
- "@babel/helper-function-name": "^7.10.3",
- "@babel/helper-member-expression-to-functions": "^7.10.3",
- "@babel/helper-optimise-call-expression": "^7.10.3",
- "@babel/helper-plugin-utils": "^7.10.3",
- "@babel/helper-replace-supers": "^7.10.1",
- "@babel/helper-split-export-declaration": "^7.10.1"
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-member-expression-to-functions": "^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"
}
},
"@babel/helper-create-regexp-features-plugin": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.1.tgz",
- "integrity": "sha512-Rx4rHS0pVuJn5pJOqaqcZR4XSgeF9G/pO/79t+4r7380tXFJdzImFnxMU19f83wjSrmKHq6myrM10pFHTGzkUA==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-annotate-as-pure": "^7.10.1",
- "@babel/helper-regex": "^7.10.1",
+ "@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.10.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.3.tgz",
- "integrity": "sha512-bxRzDi4Sin/k0drWCczppOhov1sBSdBvXJObM1NLHQzjhXhwRtn7aRWGvLJWCYbuu2qUk3EKs6Ci9C9ps8XokQ==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.4.tgz",
+ "integrity": "sha512-nIij0oKErfCnLUCWaCaHW0Bmtl2RO9cN7+u2QT8yqTywgALKlyUVOvHDElh+b5DwVC6YB1FOYFOTWcN/+41EDA==",
"dev": true,
"requires": {
- "@babel/helper-function-name": "^7.10.3",
- "@babel/types": "^7.10.3",
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/types": "^7.10.4",
"lodash": "^4.17.13"
}
},
"@babel/helper-explode-assignable-expression": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.3.tgz",
- "integrity": "sha512-0nKcR64XrOC3lsl+uhD15cwxPvaB6QKUDlD84OT9C3myRbhJqTMYir69/RWItUvHpharv0eJ/wk7fl34ONSwZw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.4.tgz",
+ "integrity": "sha512-4K71RyRQNPRrR85sr5QY4X3VwG4wtVoXZB9+L3r1Gp38DhELyHCtovqydRi7c1Ovb17eRGiQ/FD5s8JdU0Uy5A==",
"dev": true,
"requires": {
- "@babel/traverse": "^7.10.3",
- "@babel/types": "^7.10.3"
+ "@babel/traverse": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-function-name": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.3.tgz",
- "integrity": "sha512-FvSj2aiOd8zbeqijjgqdMDSyxsGHaMt5Tr0XjQsGKHD3/1FP3wksjnLAWzxw7lvXiej8W1Jt47SKTZ6upQNiRw==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-get-function-arity": "^7.10.3",
- "@babel/template": "^7.10.3",
- "@babel/types": "^7.10.3"
+ "@babel/helper-get-function-arity": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-get-function-arity": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.3.tgz",
- "integrity": "sha512-iUD/gFsR+M6uiy69JA6fzM5seno8oE85IYZdbVVEuQaZlEzMO2MXblh+KSPJgsZAUx0EEbWXU0yJaW7C9CdAVg==",
+ "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==",
"dev": true,
"requires": {
- "@babel/types": "^7.10.3"
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-hoist-variables": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.3.tgz",
- "integrity": "sha512-9JyafKoBt5h20Yv1+BXQMdcXXavozI1vt401KBiRc2qzUepbVnd7ogVNymY1xkQN9fekGwfxtotH2Yf5xsGzgg==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz",
+ "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==",
"dev": true,
"requires": {
- "@babel/types": "^7.10.3"
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-member-expression-to-functions": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.3.tgz",
- "integrity": "sha512-q7+37c4EPLSjNb2NmWOjNwj0+BOyYlssuQ58kHEWk1Z78K5i8vTUsteq78HMieRPQSl/NtpQyJfdjt3qZ5V2vw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz",
+ "integrity": "sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A==",
"dev": true,
"requires": {
- "@babel/types": "^7.10.3"
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-module-imports": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.3.tgz",
- "integrity": "sha512-Jtqw5M9pahLSUWA+76nhK9OG8nwYXzhQzVIGFoNaHnXF/r4l7kz4Fl0UAW7B6mqC5myoJiBP5/YQlXQTMfHI9w==",
+ "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==",
"dev": true,
"requires": {
- "@babel/types": "^7.10.3"
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-module-transforms": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz",
- "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz",
+ "integrity": "sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q==",
"dev": true,
"requires": {
- "@babel/helper-module-imports": "^7.10.1",
- "@babel/helper-replace-supers": "^7.10.1",
- "@babel/helper-simple-access": "^7.10.1",
- "@babel/helper-split-export-declaration": "^7.10.1",
- "@babel/template": "^7.10.1",
- "@babel/types": "^7.10.1",
+ "@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.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/types": "^7.10.4",
"lodash": "^4.17.13"
}
},
"@babel/helper-optimise-call-expression": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.3.tgz",
- "integrity": "sha512-kT2R3VBH/cnSz+yChKpaKRJQJWxdGoc6SjioRId2wkeV3bK0wLLioFpJROrX0U4xr/NmxSSAWT/9Ih5snwIIzg==",
+ "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==",
"dev": true,
"requires": {
- "@babel/types": "^7.10.3"
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-plugin-utils": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.3.tgz",
- "integrity": "sha512-j/+j8NAWUTxOtx4LKHybpSClxHoq6I91DQ/mKgAXn5oNUPIUiGppjPIX3TDtJWPrdfP9Kfl7e4fgVMiQR9VE/g==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+ "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
"dev": true
},
"@babel/helper-regex": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.1.tgz",
- "integrity": "sha512-7isHr19RsIJWWLLFn21ubFt223PjQyg1HY7CZEMRr820HttHPpVvrsIN3bUOo44DEfFV4kBXO7Abbn9KTUZV7g==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.4.tgz",
+ "integrity": "sha512-inWpnHGgtg5NOF0eyHlC0/74/VkdRITY9dtTpB2PrxKKn+AkVMRiZz/Adrx+Ssg+MLDesi2zohBW6MVq6b4pOQ==",
"dev": true,
"requires": {
"lodash": "^4.17.13"
}
},
"@babel/helper-remap-async-to-generator": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.3.tgz",
- "integrity": "sha512-sLB7666ARbJUGDO60ZormmhQOyqMX/shKBXZ7fy937s+3ID8gSrneMvKSSb+8xIM5V7Vn6uNVtOY1vIm26XLtA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.4.tgz",
+ "integrity": "sha512-86Lsr6NNw3qTNl+TBcF1oRZMaVzJtbWTyTko+CQL/tvNvcGYEFKbLXDPxtW0HKk3McNOk4KzY55itGWCAGK5tg==",
"dev": true,
"requires": {
- "@babel/helper-annotate-as-pure": "^7.10.1",
- "@babel/helper-wrap-function": "^7.10.1",
- "@babel/template": "^7.10.3",
- "@babel/traverse": "^7.10.3",
- "@babel/types": "^7.10.3"
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "@babel/helper-wrap-function": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-replace-supers": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz",
- "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-member-expression-to-functions": "^7.10.1",
- "@babel/helper-optimise-call-expression": "^7.10.1",
- "@babel/traverse": "^7.10.1",
- "@babel/types": "^7.10.1"
+ "@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.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz",
- "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==",
+ "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==",
"dev": true,
"requires": {
- "@babel/template": "^7.10.1",
- "@babel/types": "^7.10.1"
+ "@babel/template": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-split-export-declaration": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz",
- "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz",
+ "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==",
"dev": true,
"requires": {
- "@babel/types": "^7.10.1"
+ "@babel/types": "^7.10.4"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.3.tgz",
- "integrity": "sha512-bU8JvtlYpJSBPuj1VUmKpFGaDZuLxASky3LhaKj3bmpSTY6VWooSM8msk+Z0CZoErFye2tlABF6yDkT3FOPAXw==",
+ "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==",
"dev": true
},
"@babel/helper-wrap-function": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz",
- "integrity": "sha512-C0MzRGteVDn+H32/ZgbAv5r56f2o1fZSA/rj/TYo8JEJNHg+9BdSmKBUND0shxWRztWhjlT2cvHYuynpPsVJwQ==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-function-name": "^7.10.1",
- "@babel/template": "^7.10.1",
- "@babel/traverse": "^7.10.1",
- "@babel/types": "^7.10.1"
+ "@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.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz",
- "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz",
+ "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==",
"dev": true,
"requires": {
- "@babel/template": "^7.10.1",
- "@babel/traverse": "^7.10.1",
- "@babel/types": "^7.10.1"
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
"@babel/highlight": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.3.tgz",
- "integrity": "sha512-Ih9B/u7AtgEnySE2L2F0Xm0GaM729XqqLfHkalTsbjXGyqmf/6M0Cu0WpvqueUlW+xk88BHw9Nkpj49naU+vWw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+ "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.10.3",
+ "@babel/helper-validator-identifier": "^7.10.4",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.3.tgz",
- "integrity": "sha512-oJtNJCMFdIMwXGmx+KxuaD7i3b8uS7TTFYW/FNG2BT8m+fmGHoiPYoH0Pe3gya07WuFmM5FCDIr1x0irkD/hyA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz",
+ "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==",
"dev": true
},
"@babel/plugin-proposal-async-generator-functions": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.3.tgz",
- "integrity": "sha512-WUUWM7YTOudF4jZBAJIW9D7aViYC/Fn0Pln4RIHlQALyno3sXSjqmTA4Zy1TKC2D49RCR8Y/Pn4OIUtEypK3CA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.4.tgz",
+ "integrity": "sha512-MJbxGSmejEFVOANAezdO39SObkURO5o/8b6fSH6D1pi9RZQt+ldppKPXfqgUWpSQ9asM6xaSaSJIaeWMDRP0Zg==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.3",
- "@babel/helper-remap-async-to-generator": "^7.10.3",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-remap-async-to-generator": "^7.10.4",
"@babel/plugin-syntax-async-generators": "^7.8.0"
}
},
"@babel/plugin-proposal-class-properties": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.1.tgz",
- "integrity": "sha512-sqdGWgoXlnOdgMXU+9MbhzwFRgxVLeiGBqTrnuS7LC2IBU31wSsESbTUreT2O418obpfPdGUR2GbEufZF1bpqw==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-create-class-features-plugin": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-create-class-features-plugin": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-proposal-dynamic-import": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.1.tgz",
- "integrity": "sha512-Cpc2yUVHTEGPlmiQzXj026kqwjEQAD9I4ZC16uzdbgWgitg/UHKHLffKNCQZ5+y8jpIZPJcKcwsr2HwPh+w3XA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz",
+ "integrity": "sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
"@babel/plugin-syntax-dynamic-import": "^7.8.0"
}
},
"@babel/plugin-proposal-json-strings": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.1.tgz",
- "integrity": "sha512-m8r5BmV+ZLpWPtMY2mOKN7wre6HIO4gfIiV+eOmsnZABNenrt/kzYBwrh+KOfgumSWpnlGs5F70J8afYMSJMBg==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz",
+ "integrity": "sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
"@babel/plugin-syntax-json-strings": "^7.8.0"
}
},
"@babel/plugin-proposal-nullish-coalescing-operator": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.1.tgz",
- "integrity": "sha512-56cI/uHYgL2C8HVuHOuvVowihhX0sxb3nnfVRzUeVHTWmRHTZrKuAh/OBIMggGU/S1g/1D2CRCXqP+3u7vX7iA==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
}
},
"@babel/plugin-proposal-numeric-separator": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.1.tgz",
- "integrity": "sha512-jjfym4N9HtCiNfyyLAVD8WqPYeHUrw4ihxuAynWj6zzp2gf9Ey2f7ImhFm6ikB3CLf5Z/zmcJDri6B4+9j9RsA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1",
- "@babel/plugin-syntax-numeric-separator": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4"
}
},
"@babel/plugin-proposal-object-rest-spread": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.3.tgz",
- "integrity": "sha512-ZZh5leCIlH9lni5bU/wB/UcjtcVLgR8gc+FAgW2OOY+m9h1II3ItTO1/cewNUcsIDZSYcSaz/rYVls+Fb0ExVQ==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.4.tgz",
+ "integrity": "sha512-6vh4SqRuLLarjgeOf4EaROJAHjvu9Gl+/346PbDH9yWbJyfnJ/ah3jmYKYtswEyCoWZiidvVHjHshd4WgjB9BA==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.3",
+ "@babel/helper-plugin-utils": "^7.10.4",
"@babel/plugin-syntax-object-rest-spread": "^7.8.0",
- "@babel/plugin-transform-parameters": "^7.10.1"
+ "@babel/plugin-transform-parameters": "^7.10.4"
}
},
"@babel/plugin-proposal-optional-catch-binding": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.1.tgz",
- "integrity": "sha512-VqExgeE62YBqI3ogkGoOJp1R6u12DFZjqwJhqtKc2o5m1YTUuUWnos7bZQFBhwkxIFpWYJ7uB75U7VAPPiKETA==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
}
},
"@babel/plugin-proposal-optional-chaining": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.3.tgz",
- "integrity": "sha512-yyG3n9dJ1vZ6v5sfmIlMMZ8azQoqx/5/nZTSWX1td6L1H1bsjzA8TInDChpafCZiJkeOFzp/PtrfigAQXxI1Ng==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.4.tgz",
+ "integrity": "sha512-ZIhQIEeavTgouyMSdZRap4VPPHqJJ3NEs2cuHs5p0erH+iz6khB0qfgU8g7UuJkG88+fBMy23ZiU+nuHvekJeQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.3",
+ "@babel/helper-plugin-utils": "^7.10.4",
"@babel/plugin-syntax-optional-chaining": "^7.8.0"
}
},
"@babel/plugin-proposal-private-methods": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.1.tgz",
- "integrity": "sha512-RZecFFJjDiQ2z6maFprLgrdnm0OzoC23Mx89xf1CcEsxmHuzuXOdniEuI+S3v7vjQG4F5sa6YtUp+19sZuSxHg==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz",
+ "integrity": "sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw==",
"dev": true,
"requires": {
- "@babel/helper-create-class-features-plugin": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-create-class-features-plugin": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-proposal-unicode-property-regex": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.1.tgz",
- "integrity": "sha512-JjfngYRvwmPwmnbRZyNiPFI8zxCZb8euzbCG/LxyKdeTb59tVciKo9GK9bi6JYKInk1H11Dq9j/zRqIH4KigfQ==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz",
+ "integrity": "sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA==",
"dev": true,
"requires": {
- "@babel/helper-create-regexp-features-plugin": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-create-regexp-features-plugin": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-syntax-async-generators": {
@@ -500,12 +500,12 @@
}
},
"@babel/plugin-syntax-class-properties": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz",
- "integrity": "sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-syntax-dynamic-import": {
@@ -518,12 +518,12 @@
}
},
"@babel/plugin-syntax-import-meta": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.1.tgz",
- "integrity": "sha512-ypC4jwfIVF72og0dgvEcFRdOM2V9Qm1tu7RGmdZOlhsccyK0wisXmMObGuWEOd5jQ+K9wcIgSNftCpk2vkjUfQ==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-syntax-json-strings": {
@@ -536,21 +536,21 @@
}
},
"@babel/plugin-syntax-jsx": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.1.tgz",
- "integrity": "sha512-+OxyOArpVFXQeXKLO9o+r2I4dIoVoy6+Uu0vKELrlweDM3QJADZj+Z+5ERansZqIZBcLj42vHnDI8Rz9BnRIuQ==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-syntax-logical-assignment-operators": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.1.tgz",
- "integrity": "sha512-XyHIFa9kdrgJS91CUH+ccPVTnJShr8nLGc5bG2IhGXv5p1Rd+8BleGE5yzIg2Nc1QZAdHDa0Qp4m6066OL96Iw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-syntax-nullish-coalescing-operator": {
@@ -563,12 +563,12 @@
}
},
"@babel/plugin-syntax-numeric-separator": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz",
- "integrity": "sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-syntax-object-rest-spread": {
@@ -599,456 +599,456 @@
}
},
"@babel/plugin-syntax-top-level-await": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.1.tgz",
- "integrity": "sha512-hgA5RYkmZm8FTFT3yu2N9Bx7yVVOKYT6yEdXXo6j2JTm0wNxgqaGeQVaSHRjhfnQbX91DtjFB6McRFSlcJH3xQ==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz",
+ "integrity": "sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-arrow-functions": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.1.tgz",
- "integrity": "sha512-6AZHgFJKP3DJX0eCNJj01RpytUa3SOGawIxweHkNX2L6PYikOZmoh5B0d7hIHaIgveMjX990IAa/xK7jRTN8OA==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-async-to-generator": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.1.tgz",
- "integrity": "sha512-XCgYjJ8TY2slj6SReBUyamJn3k2JLUIiiR5b6t1mNCMSvv7yx+jJpaewakikp0uWFQSF7ChPPoe3dHmXLpISkg==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-module-imports": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.1",
- "@babel/helper-remap-async-to-generator": "^7.10.1"
+ "@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.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.1.tgz",
- "integrity": "sha512-B7K15Xp8lv0sOJrdVAoukKlxP9N59HS48V1J3U/JGj+Ad+MHq+am6xJVs85AgXrQn4LV8vaYFOB+pr/yIuzW8Q==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-block-scoping": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.1.tgz",
- "integrity": "sha512-8bpWG6TtF5akdhIm/uWTyjHqENpy13Fx8chg7pFH875aNLwX8JxIxqm08gmAT+Whe6AOmaTeLPe7dpLbXt+xUw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.4.tgz",
+ "integrity": "sha512-J3b5CluMg3hPUii2onJDRiaVbPtKFPLEaV5dOPY5OeAbDi1iU/UbbFFTgwb7WnanaDy7bjU35kc26W3eM5Qa0A==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
"lodash": "^4.17.13"
}
},
"@babel/plugin-transform-classes": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.3.tgz",
- "integrity": "sha512-irEX0ChJLaZVC7FvvRoSIxJlmk0IczFLcwaRXUArBKYHCHbOhe57aG8q3uw/fJsoSXvZhjRX960hyeAGlVBXZw==",
- "dev": true,
- "requires": {
- "@babel/helper-annotate-as-pure": "^7.10.1",
- "@babel/helper-define-map": "^7.10.3",
- "@babel/helper-function-name": "^7.10.3",
- "@babel/helper-optimise-call-expression": "^7.10.3",
- "@babel/helper-plugin-utils": "^7.10.3",
- "@babel/helper-replace-supers": "^7.10.1",
- "@babel/helper-split-export-declaration": "^7.10.1",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz",
+ "integrity": "sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA==",
+ "dev": true,
+ "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"
}
},
"@babel/plugin-transform-computed-properties": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.3.tgz",
- "integrity": "sha512-GWzhaBOsdbjVFav96drOz7FzrcEW6AP5nax0gLIpstiFaI3LOb2tAg06TimaWU6YKOfUACK3FVrxPJ4GSc5TgA==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.3"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-destructuring": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.1.tgz",
- "integrity": "sha512-V/nUc4yGWG71OhaTH705pU8ZSdM6c1KmmLP8ys59oOYbT7RpMYAR3MsVOt6OHL0WzG7BlTU076va9fjJyYzJMA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz",
+ "integrity": "sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-dotall-regex": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.1.tgz",
- "integrity": "sha512-19VIMsD1dp02RvduFUmfzj8uknaO3uiHHF0s3E1OHnVsNj8oge8EQ5RzHRbJjGSetRnkEuBYO7TG1M5kKjGLOA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz",
+ "integrity": "sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA==",
"dev": true,
"requires": {
- "@babel/helper-create-regexp-features-plugin": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-create-regexp-features-plugin": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-duplicate-keys": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.1.tgz",
- "integrity": "sha512-wIEpkX4QvX8Mo9W6XF3EdGttrIPZWozHfEaDTU0WJD/TDnXMvdDh30mzUl/9qWhnf7naicYartcEfUghTCSNpA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz",
+ "integrity": "sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-exponentiation-operator": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.1.tgz",
- "integrity": "sha512-lr/przdAbpEA2BUzRvjXdEDLrArGRRPwbaF9rvayuHRvdQ7lUTTkZnhZrJ4LE2jvgMRFF4f0YuPQ20vhiPYxtA==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-for-of": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.1.tgz",
- "integrity": "sha512-US8KCuxfQcn0LwSCMWMma8M2R5mAjJGsmoCBVwlMygvmDUMkTCykc84IqN1M7t+agSfOmLYTInLCHJM+RUoz+w==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-function-name": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.1.tgz",
- "integrity": "sha512-//bsKsKFBJfGd65qSNNh1exBy5Y9gD9ZN+DvrJ8f7HXr4avE5POW6zB7Rj6VnqHV33+0vXWUwJT0wSHubiAQkw==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-function-name": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-literals": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.1.tgz",
- "integrity": "sha512-qi0+5qgevz1NHLZroObRm5A+8JJtibb7vdcPQF1KQE12+Y/xxl8coJ+TpPW9iRq+Mhw/NKLjm+5SHtAHCC7lAw==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-member-expression-literals": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.1.tgz",
- "integrity": "sha512-UmaWhDokOFT2GcgU6MkHC11i0NQcL63iqeufXWfRy6pUOGYeCGEKhvfFO6Vz70UfYJYHwveg62GS83Rvpxn+NA==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-modules-amd": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.1.tgz",
- "integrity": "sha512-31+hnWSFRI4/ACFr1qkboBbrTxoBIzj7qA69qlq8HY8p7+YCzkCT6/TvQ1a4B0z27VeWtAeJd6pr5G04dc1iHw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.4.tgz",
+ "integrity": "sha512-3Fw+H3WLUrTlzi3zMiZWp3AR4xadAEMv6XRCYnd5jAlLM61Rn+CRJaZMaNvIpcJpQ3vs1kyifYvEVPFfoSkKOA==",
"dev": true,
"requires": {
- "@babel/helper-module-transforms": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.1",
+ "@babel/helper-module-transforms": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4",
"babel-plugin-dynamic-import-node": "^2.3.3"
}
},
"@babel/plugin-transform-modules-commonjs": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.1.tgz",
- "integrity": "sha512-AQG4fc3KOah0vdITwt7Gi6hD9BtQP/8bhem7OjbaMoRNCH5Djx42O2vYMfau7QnAzQCa+RJnhJBmFFMGpQEzrg==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-module-transforms": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.1",
- "@babel/helper-simple-access": "^7.10.1",
+ "@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-modules-systemjs": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.3.tgz",
- "integrity": "sha512-GWXWQMmE1GH4ALc7YXW56BTh/AlzvDWhUNn9ArFF0+Cz5G8esYlVbXfdyHa1xaD1j+GnBoCeoQNlwtZTVdiG/A==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.4.tgz",
+ "integrity": "sha512-Tb28LlfxrTiOTGtZFsvkjpyjCl9IoaRI52AEU/VIwOwvDQWtbNJsAqTXzh+5R7i74e/OZHH2c2w2fsOqAfnQYQ==",
"dev": true,
"requires": {
- "@babel/helper-hoist-variables": "^7.10.3",
- "@babel/helper-module-transforms": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.3",
+ "@babel/helper-hoist-variables": "^7.10.4",
+ "@babel/helper-module-transforms": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4",
"babel-plugin-dynamic-import-node": "^2.3.3"
}
},
"@babel/plugin-transform-modules-umd": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.1.tgz",
- "integrity": "sha512-EIuiRNMd6GB6ulcYlETnYYfgv4AxqrswghmBRQbWLHZxN4s7mupxzglnHqk9ZiUpDI4eRWewedJJNj67PWOXKA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz",
+ "integrity": "sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA==",
"dev": true,
"requires": {
- "@babel/helper-module-transforms": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-module-transforms": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-named-capturing-groups-regex": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.3.tgz",
- "integrity": "sha512-I3EH+RMFyVi8Iy/LekQm948Z4Lz4yKT7rK+vuCAeRm0kTa6Z5W7xuhRxDNJv0FPya/her6AUgrDITb70YHtTvA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz",
+ "integrity": "sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA==",
"dev": true,
"requires": {
- "@babel/helper-create-regexp-features-plugin": "^7.8.3"
+ "@babel/helper-create-regexp-features-plugin": "^7.10.4"
}
},
"@babel/plugin-transform-new-target": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.1.tgz",
- "integrity": "sha512-MBlzPc1nJvbmO9rPr1fQwXOM2iGut+JC92ku6PbiJMMK7SnQc1rytgpopveE3Evn47gzvGYeCdgfCDbZo0ecUw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz",
+ "integrity": "sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-object-super": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.1.tgz",
- "integrity": "sha512-WnnStUDN5GL+wGQrJylrnnVlFhFmeArINIR9gjhSeYyvroGhBrSAXYg/RHsnfzmsa+onJrTJrEClPzgNmmQ4Gw==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1",
- "@babel/helper-replace-supers": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-replace-supers": "^7.10.4"
}
},
"@babel/plugin-transform-parameters": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.1.tgz",
- "integrity": "sha512-tJ1T0n6g4dXMsL45YsSzzSDZCxiHXAQp/qHrucOq5gEHncTA3xDxnd5+sZcoQp+N1ZbieAaB8r/VUCG0gqseOg==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.4.tgz",
+ "integrity": "sha512-RurVtZ/D5nYfEg0iVERXYKEgDFeesHrHfx8RT05Sq57ucj2eOYAP6eu5fynL4Adju4I/mP/I6SO0DqNWAXjfLQ==",
"dev": true,
"requires": {
- "@babel/helper-get-function-arity": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-get-function-arity": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-property-literals": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.1.tgz",
- "integrity": "sha512-Kr6+mgag8auNrgEpbfIWzdXYOvqDHZOF0+Bx2xh4H2EDNwcbRb9lY6nkZg8oSjsX+DH9Ebxm9hOqtKW+gRDeNA==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-react-display-name": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.3.tgz",
- "integrity": "sha512-dOV44bnSW5KZ6kYF6xSHBth7TFiHHZReYXH/JH3XnFNV+soEL1F5d8JT7AJ3ZBncd19Qul7SN4YpBnyWOnQ8KA==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.3"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-react-jsx": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.3.tgz",
- "integrity": "sha512-Y21E3rZmWICRJnvbGVmDLDZ8HfNDIwjGF3DXYHx1le0v0mIHCs0Gv5SavyW5Z/jgAHLaAoJPiwt+Dr7/zZKcOQ==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-builder-react-jsx": "^7.10.3",
- "@babel/helper-builder-react-jsx-experimental": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.3",
- "@babel/plugin-syntax-jsx": "^7.10.1"
+ "@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-development": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.1.tgz",
- "integrity": "sha512-XwDy/FFoCfw9wGFtdn5Z+dHh6HXKHkC6DwKNWpN74VWinUagZfDcEJc3Y8Dn5B3WMVnAllX8Kviaw7MtC5Epwg==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.4.tgz",
+ "integrity": "sha512-RM3ZAd1sU1iQ7rI2dhrZRZGv0aqzNQMbkIUCS1txYpi9wHQ2ZHNjo5TwX+UD6pvFW4AbWqLVYvKy5qJSAyRGjQ==",
"dev": true,
"requires": {
- "@babel/helper-builder-react-jsx-experimental": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.1",
- "@babel/plugin-syntax-jsx": "^7.10.1"
+ "@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-self": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.1.tgz",
- "integrity": "sha512-4p+RBw9d1qV4S749J42ZooeQaBomFPrSxa9JONLHJ1TxCBo3TzJ79vtmG2S2erUT8PDDrPdw4ZbXGr2/1+dILA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.4.tgz",
+ "integrity": "sha512-yOvxY2pDiVJi0axdTWHSMi5T0DILN+H+SaeJeACHKjQLezEzhLx9nEF9xgpBLPtkZsks9cnb5P9iBEi21En3gg==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1",
- "@babel/plugin-syntax-jsx": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-jsx": "^7.10.4"
}
},
"@babel/plugin-transform-react-jsx-source": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.1.tgz",
- "integrity": "sha512-neAbaKkoiL+LXYbGDvh6PjPG+YeA67OsZlE78u50xbWh2L1/C81uHiNP5d1fw+uqUIoiNdCC8ZB+G4Zh3hShJA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.4.tgz",
+ "integrity": "sha512-FTK3eQFrPv2aveerUSazFmGygqIdTtvskG50SnGnbEUnRPcGx2ylBhdFIzoVS1ty44hEgcPoCAyw5r3VDEq+Ug==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1",
- "@babel/plugin-syntax-jsx": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-jsx": "^7.10.4"
}
},
"@babel/plugin-transform-react-pure-annotations": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.3.tgz",
- "integrity": "sha512-n/fWYGqvTl7OLZs/QcWaKMFdADPvC3V6jYuEOpPyvz97onsW9TXn196fHnHW1ZgkO20/rxLOgKnEtN1q9jkgqA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.4.tgz",
+ "integrity": "sha512-+njZkqcOuS8RaPakrnR9KvxjoG1ASJWpoIv/doyWngId88JoFlPlISenGXjrVacZUIALGUr6eodRs1vmPnF23A==",
"dev": true,
"requires": {
- "@babel/helper-annotate-as-pure": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.3"
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-regenerator": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.3.tgz",
- "integrity": "sha512-H5kNeW0u8mbk0qa1jVIVTeJJL6/TJ81ltD4oyPx0P499DhMJrTmmIFCmJ3QloGpQG8K9symccB7S7SJpCKLwtw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz",
+ "integrity": "sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw==",
"dev": true,
"requires": {
"regenerator-transform": "^0.14.2"
}
},
"@babel/plugin-transform-reserved-words": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.1.tgz",
- "integrity": "sha512-qN1OMoE2nuqSPmpTqEM7OvJ1FkMEV+BjVeZZm9V9mq/x1JLKQ4pcv8riZJMNN3u2AUGl0ouOMjRr2siecvHqUQ==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz",
+ "integrity": "sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-shorthand-properties": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.1.tgz",
- "integrity": "sha512-AR0E/lZMfLstScFwztApGeyTHJ5u3JUKMjneqRItWeEqDdHWZwAOKycvQNCasCK/3r5YXsuNG25funcJDu7Y2g==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-spread": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.1.tgz",
- "integrity": "sha512-8wTPym6edIrClW8FI2IoaePB91ETOtg36dOkj3bYcNe7aDMN2FXEoUa+WrmPc4xa1u2PQK46fUX2aCb+zo9rfw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.4.tgz",
+ "integrity": "sha512-1e/51G/Ni+7uH5gktbWv+eCED9pP8ZpRhZB3jOaI3mmzfvJTWHkuyYTv0Z5PYtyM+Tr2Ccr9kUdQxn60fI5WuQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-sticky-regex": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.1.tgz",
- "integrity": "sha512-j17ojftKjrL7ufX8ajKvwRilwqTok4q+BjkknmQw9VNHnItTyMP5anPFzxFJdCQs7clLcWpCV3ma+6qZWLnGMA==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1",
- "@babel/helper-regex": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-regex": "^7.10.4"
}
},
"@babel/plugin-transform-template-literals": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.3.tgz",
- "integrity": "sha512-yaBn9OpxQra/bk0/CaA4wr41O0/Whkg6nqjqApcinxM7pro51ojhX6fv1pimAnVjVfDy14K0ULoRL70CA9jWWA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.4.tgz",
+ "integrity": "sha512-4NErciJkAYe+xI5cqfS8pV/0ntlY5N5Ske/4ImxAVX7mk9Rxt2bwDTGv1Msc2BRJvWQcmYEC+yoMLdX22aE4VQ==",
"dev": true,
"requires": {
- "@babel/helper-annotate-as-pure": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.3"
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-typeof-symbol": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.1.tgz",
- "integrity": "sha512-qX8KZcmbvA23zDi+lk9s6hC1FM7jgLHYIjuLgULgc8QtYnmB3tAVIYkNoKRQ75qWBeyzcoMoK8ZQmogGtC/w0g==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz",
+ "integrity": "sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-unicode-escapes": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.1.tgz",
- "integrity": "sha512-zZ0Poh/yy1d4jeDWpx/mNwbKJVwUYJX73q+gyh4bwtG0/iUlzdEu0sLMda8yuDFS6LBQlT/ST1SJAR6zYwXWgw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz",
+ "integrity": "sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-unicode-regex": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.1.tgz",
- "integrity": "sha512-Y/2a2W299k0VIUdbqYm9X2qS6fE0CUBhhiPpimK6byy7OJ/kORLlIX+J6UrjgNu5awvs62k+6RSslxhcvVw2Tw==",
+ "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==",
"dev": true,
"requires": {
- "@babel/helper-create-regexp-features-plugin": "^7.10.1",
- "@babel/helper-plugin-utils": "^7.10.1"
+ "@babel/helper-create-regexp-features-plugin": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/preset-env": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.10.3.tgz",
- "integrity": "sha512-jHaSUgiewTmly88bJtMHbOd1bJf2ocYxb5BWKSDQIP5tmgFuS/n0gl+nhSrYDhT33m0vPxp+rP8oYYgPgMNQlg==",
- "dev": true,
- "requires": {
- "@babel/compat-data": "^7.10.3",
- "@babel/helper-compilation-targets": "^7.10.2",
- "@babel/helper-module-imports": "^7.10.3",
- "@babel/helper-plugin-utils": "^7.10.3",
- "@babel/plugin-proposal-async-generator-functions": "^7.10.3",
- "@babel/plugin-proposal-class-properties": "^7.10.1",
- "@babel/plugin-proposal-dynamic-import": "^7.10.1",
- "@babel/plugin-proposal-json-strings": "^7.10.1",
- "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.1",
- "@babel/plugin-proposal-numeric-separator": "^7.10.1",
- "@babel/plugin-proposal-object-rest-spread": "^7.10.3",
- "@babel/plugin-proposal-optional-catch-binding": "^7.10.1",
- "@babel/plugin-proposal-optional-chaining": "^7.10.3",
- "@babel/plugin-proposal-private-methods": "^7.10.1",
- "@babel/plugin-proposal-unicode-property-regex": "^7.10.1",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.10.4.tgz",
+ "integrity": "sha512-tcmuQ6vupfMZPrLrc38d0sF2OjLT3/bZ0dry5HchNCQbrokoQi4reXqclvkkAT5b+gWc23meVWpve5P/7+w/zw==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.10.4",
+ "@babel/helper-compilation-targets": "^7.10.4",
+ "@babel/helper-module-imports": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-proposal-async-generator-functions": "^7.10.4",
+ "@babel/plugin-proposal-class-properties": "^7.10.4",
+ "@babel/plugin-proposal-dynamic-import": "^7.10.4",
+ "@babel/plugin-proposal-json-strings": "^7.10.4",
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4",
+ "@babel/plugin-proposal-numeric-separator": "^7.10.4",
+ "@babel/plugin-proposal-object-rest-spread": "^7.10.4",
+ "@babel/plugin-proposal-optional-catch-binding": "^7.10.4",
+ "@babel/plugin-proposal-optional-chaining": "^7.10.4",
+ "@babel/plugin-proposal-private-methods": "^7.10.4",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.10.4",
"@babel/plugin-syntax-async-generators": "^7.8.0",
- "@babel/plugin-syntax-class-properties": "^7.10.1",
+ "@babel/plugin-syntax-class-properties": "^7.10.4",
"@babel/plugin-syntax-dynamic-import": "^7.8.0",
"@babel/plugin-syntax-json-strings": "^7.8.0",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0",
- "@babel/plugin-syntax-numeric-separator": "^7.10.1",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
"@babel/plugin-syntax-object-rest-spread": "^7.8.0",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.0",
"@babel/plugin-syntax-optional-chaining": "^7.8.0",
- "@babel/plugin-syntax-top-level-await": "^7.10.1",
- "@babel/plugin-transform-arrow-functions": "^7.10.1",
- "@babel/plugin-transform-async-to-generator": "^7.10.1",
- "@babel/plugin-transform-block-scoped-functions": "^7.10.1",
- "@babel/plugin-transform-block-scoping": "^7.10.1",
- "@babel/plugin-transform-classes": "^7.10.3",
- "@babel/plugin-transform-computed-properties": "^7.10.3",
- "@babel/plugin-transform-destructuring": "^7.10.1",
- "@babel/plugin-transform-dotall-regex": "^7.10.1",
- "@babel/plugin-transform-duplicate-keys": "^7.10.1",
- "@babel/plugin-transform-exponentiation-operator": "^7.10.1",
- "@babel/plugin-transform-for-of": "^7.10.1",
- "@babel/plugin-transform-function-name": "^7.10.1",
- "@babel/plugin-transform-literals": "^7.10.1",
- "@babel/plugin-transform-member-expression-literals": "^7.10.1",
- "@babel/plugin-transform-modules-amd": "^7.10.1",
- "@babel/plugin-transform-modules-commonjs": "^7.10.1",
- "@babel/plugin-transform-modules-systemjs": "^7.10.3",
- "@babel/plugin-transform-modules-umd": "^7.10.1",
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.10.3",
- "@babel/plugin-transform-new-target": "^7.10.1",
- "@babel/plugin-transform-object-super": "^7.10.1",
- "@babel/plugin-transform-parameters": "^7.10.1",
- "@babel/plugin-transform-property-literals": "^7.10.1",
- "@babel/plugin-transform-regenerator": "^7.10.3",
- "@babel/plugin-transform-reserved-words": "^7.10.1",
- "@babel/plugin-transform-shorthand-properties": "^7.10.1",
- "@babel/plugin-transform-spread": "^7.10.1",
- "@babel/plugin-transform-sticky-regex": "^7.10.1",
- "@babel/plugin-transform-template-literals": "^7.10.3",
- "@babel/plugin-transform-typeof-symbol": "^7.10.1",
- "@babel/plugin-transform-unicode-escapes": "^7.10.1",
- "@babel/plugin-transform-unicode-regex": "^7.10.1",
+ "@babel/plugin-syntax-top-level-await": "^7.10.4",
+ "@babel/plugin-transform-arrow-functions": "^7.10.4",
+ "@babel/plugin-transform-async-to-generator": "^7.10.4",
+ "@babel/plugin-transform-block-scoped-functions": "^7.10.4",
+ "@babel/plugin-transform-block-scoping": "^7.10.4",
+ "@babel/plugin-transform-classes": "^7.10.4",
+ "@babel/plugin-transform-computed-properties": "^7.10.4",
+ "@babel/plugin-transform-destructuring": "^7.10.4",
+ "@babel/plugin-transform-dotall-regex": "^7.10.4",
+ "@babel/plugin-transform-duplicate-keys": "^7.10.4",
+ "@babel/plugin-transform-exponentiation-operator": "^7.10.4",
+ "@babel/plugin-transform-for-of": "^7.10.4",
+ "@babel/plugin-transform-function-name": "^7.10.4",
+ "@babel/plugin-transform-literals": "^7.10.4",
+ "@babel/plugin-transform-member-expression-literals": "^7.10.4",
+ "@babel/plugin-transform-modules-amd": "^7.10.4",
+ "@babel/plugin-transform-modules-commonjs": "^7.10.4",
+ "@babel/plugin-transform-modules-systemjs": "^7.10.4",
+ "@babel/plugin-transform-modules-umd": "^7.10.4",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.10.4",
+ "@babel/plugin-transform-new-target": "^7.10.4",
+ "@babel/plugin-transform-object-super": "^7.10.4",
+ "@babel/plugin-transform-parameters": "^7.10.4",
+ "@babel/plugin-transform-property-literals": "^7.10.4",
+ "@babel/plugin-transform-regenerator": "^7.10.4",
+ "@babel/plugin-transform-reserved-words": "^7.10.4",
+ "@babel/plugin-transform-shorthand-properties": "^7.10.4",
+ "@babel/plugin-transform-spread": "^7.10.4",
+ "@babel/plugin-transform-sticky-regex": "^7.10.4",
+ "@babel/plugin-transform-template-literals": "^7.10.4",
+ "@babel/plugin-transform-typeof-symbol": "^7.10.4",
+ "@babel/plugin-transform-unicode-escapes": "^7.10.4",
+ "@babel/plugin-transform-unicode-regex": "^7.10.4",
"@babel/preset-modules": "^0.1.3",
- "@babel/types": "^7.10.3",
+ "@babel/types": "^7.10.4",
"browserslist": "^4.12.0",
"core-js-compat": "^3.6.2",
"invariant": "^2.2.2",
@@ -1070,33 +1070,33 @@
}
},
"@babel/preset-react": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.10.1.tgz",
- "integrity": "sha512-Rw0SxQ7VKhObmFjD/cUcKhPTtzpeviEFX1E6PgP+cYOhQ98icNqtINNFANlsdbQHrmeWnqdxA4Tmnl1jy5tp3Q==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.10.4.tgz",
+ "integrity": "sha512-BrHp4TgOIy4M19JAfO1LhycVXOPWdDbTRep7eVyatf174Hff+6Uk53sDyajqZPu8W1qXRBiYOfIamek6jA7YVw==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.10.1",
- "@babel/plugin-transform-react-display-name": "^7.10.1",
- "@babel/plugin-transform-react-jsx": "^7.10.1",
- "@babel/plugin-transform-react-jsx-development": "^7.10.1",
- "@babel/plugin-transform-react-jsx-self": "^7.10.1",
- "@babel/plugin-transform-react-jsx-source": "^7.10.1",
- "@babel/plugin-transform-react-pure-annotations": "^7.10.1"
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-transform-react-display-name": "^7.10.4",
+ "@babel/plugin-transform-react-jsx": "^7.10.4",
+ "@babel/plugin-transform-react-jsx-development": "^7.10.4",
+ "@babel/plugin-transform-react-jsx-self": "^7.10.4",
+ "@babel/plugin-transform-react-jsx-source": "^7.10.4",
+ "@babel/plugin-transform-react-pure-annotations": "^7.10.4"
}
},
"@babel/runtime": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.3.tgz",
- "integrity": "sha512-RzGO0RLSdokm9Ipe/YD+7ww8X2Ro79qiXZF3HU9ljrM+qnJmH1Vqth+hbiQZy761LnMJTMitHDuKVYTk3k4dLw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz",
+ "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==",
"dev": true,
"requires": {
"regenerator-runtime": "^0.13.4"
}
},
"@babel/runtime-corejs3": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.3.tgz",
- "integrity": "sha512-HA7RPj5xvJxQl429r5Cxr2trJwOfPjKiqhCXcdQPSqO2G0RHPZpXu4fkYmBaTKCp2c/jRaMK9GB/lN+7zvvFPw==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.4.tgz",
+ "integrity": "sha512-BFlgP2SoLO9HJX9WBwN67gHWMBhDX/eDz64Jajd6mR/UAUzqrNMm99d4qHnVaKscAElZoFiPv+JpR/Siud5lXw==",
"dev": true,
"requires": {
"core-js-pure": "^3.0.0",
@@ -1104,28 +1104,28 @@
}
},
"@babel/template": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.3.tgz",
- "integrity": "sha512-5BjI4gdtD+9fHZUsaxPHPNpwa+xRkDO7c7JbhYn2afvrkDu5SfAAbi9AIMXw2xEhO/BR35TqiW97IqNvCo/GqA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+ "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.10.3",
- "@babel/parser": "^7.10.3",
- "@babel/types": "^7.10.3"
+ "@babel/code-frame": "^7.10.4",
+ "@babel/parser": "^7.10.4",
+ "@babel/types": "^7.10.4"
}
},
"@babel/traverse": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.3.tgz",
- "integrity": "sha512-qO6623eBFhuPm0TmmrUFMT1FulCmsSeJuVGhiLodk2raUDFhhTECLd9E9jC4LBIWziqt4wgF6KuXE4d+Jz9yug==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz",
+ "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.10.3",
- "@babel/generator": "^7.10.3",
- "@babel/helper-function-name": "^7.10.3",
- "@babel/helper-split-export-declaration": "^7.10.1",
- "@babel/parser": "^7.10.3",
- "@babel/types": "^7.10.3",
+ "@babel/code-frame": "^7.10.4",
+ "@babel/generator": "^7.10.4",
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-split-export-declaration": "^7.10.4",
+ "@babel/parser": "^7.10.4",
+ "@babel/types": "^7.10.4",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.13"
@@ -1149,12 +1149,12 @@
}
},
"@babel/types": {
- "version": "7.10.3",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.3.tgz",
- "integrity": "sha512-nZxaJhBXBQ8HVoIcGsf9qWep3Oh3jCENK54V4mRF7qaJabVsAYdbTtmSD8WmAp1R6ytPiu5apMwSXyxB1WlaBA==",
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
+ "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.10.3",
+ "@babel/helper-validator-identifier": "^7.10.4",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
@@ -1864,6 +1864,16 @@
"@sinonjs/commons": "^1.7.0"
}
},
+ "@testing-library/react-hooks": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-3.3.0.tgz",
+ "integrity": "sha512-rE9geI1+HJ6jqXkzzJ6abREbeud6bLF8OmF+Vyc7gBoPwZAEVBYjbC1up5nNoVfYBhO5HUwdD4u9mTehAUeiyw==",
+ "dev": true,
+ "requires": {
+ "@babel/runtime": "^7.5.4",
+ "@types/testing-library__react-hooks": "^3.0.0"
+ }
+ },
"@types/babel__core": {
"version": "7.1.9",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz",
@@ -1897,9 +1907,9 @@
}
},
"@types/babel__traverse": {
- "version": "7.0.12",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.12.tgz",
- "integrity": "sha512-t4CoEokHTfcyfb4hUaF9oOHu9RmmNWnm1CP0YmMqOOfClKascOmvlEM736vlqeScuGvBDsHkf8R2INd4DWreQA==",
+ "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"
@@ -1958,9 +1968,9 @@
"dev": true
},
"@types/node": {
- "version": "14.0.14",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.14.tgz",
- "integrity": "sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ==",
+ "version": "14.0.19",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.19.tgz",
+ "integrity": "sha512-yf3BP/NIXF37BjrK5klu//asUWitOEoUP5xE1mhSUjazotwJ/eJDgEmMQNlOeWOVv72j24QQ+3bqXHE++CFGag==",
"dev": true
},
"@types/normalize-package-data": {
@@ -1970,17 +1980,52 @@
"dev": true
},
"@types/prettier": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz",
- "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.2.tgz",
+ "integrity": "sha512-IkVfat549ggtkZUthUzEX49562eGikhSYeVGX97SkMFn+sTZrgRewXjQ4tPKFPCykZHkX1Zfd9OoELGqKU2jJA==",
+ "dev": true
+ },
+ "@types/prop-types": {
+ "version": "15.7.3",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
+ "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==",
"dev": true
},
+ "@types/react": {
+ "version": "16.9.41",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.41.tgz",
+ "integrity": "sha512-6cFei7F7L4wwuM+IND/Q2cV1koQUvJ8iSV+Gwn0c3kvABZ691g7sp3hfEQHOUBJtccl1gPi+EyNjMIl9nGA0ug==",
+ "dev": true,
+ "requires": {
+ "@types/prop-types": "*",
+ "csstype": "^2.2.0"
+ }
+ },
+ "@types/react-test-renderer": {
+ "version": "16.9.2",
+ "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-16.9.2.tgz",
+ "integrity": "sha512-4eJr1JFLIAlWhzDkBCkhrOIWOvOxcCAfQh+jiKg7l/nNZcCIL2MHl2dZhogIFKyHzedVWHaVP1Yydq/Ruu4agw==",
+ "dev": true,
+ "requires": {
+ "@types/react": "*"
+ }
+ },
"@types/stack-utils": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
"integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
"dev": true
},
+ "@types/testing-library__react-hooks": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@types/testing-library__react-hooks/-/testing-library__react-hooks-3.2.0.tgz",
+ "integrity": "sha512-dE8iMTuR5lzB+MqnxlzORlXzXyCL0EKfzH0w/lau20OpkHD37EaWjZDz0iNG8b71iEtxT4XKGmSKAGVEqk46mw==",
+ "dev": true,
+ "requires": {
+ "@types/react": "*",
+ "@types/react-test-renderer": "*"
+ }
+ },
"@types/yargs": {
"version": "15.0.5",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz",
@@ -2097,28 +2142,10 @@
"integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
"dev": true
},
- "airbnb-prop-types": {
- "version": "2.15.0",
- "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.15.0.tgz",
- "integrity": "sha512-jUh2/hfKsRjNFC4XONQrxo/n/3GG4Tn6Hl0WlFQN5PY9OMC9loSCoAYKnZsWaP8wEfd5xcrPloK0Zg6iS1xwVA==",
- "dev": true,
- "requires": {
- "array.prototype.find": "^2.1.0",
- "function.prototype.name": "^1.1.1",
- "has": "^1.0.3",
- "is-regex": "^1.0.4",
- "object-is": "^1.0.1",
- "object.assign": "^4.1.0",
- "object.entries": "^1.1.0",
- "prop-types": "^15.7.2",
- "prop-types-exact": "^1.2.0",
- "react-is": "^16.9.0"
- }
- },
"ajv": {
- "version": "6.12.2",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
- "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
+ "version": "6.12.3",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz",
+ "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
@@ -2249,12 +2276,6 @@
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
"dev": true
},
- "array-filter": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz",
- "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=",
- "dev": true
- },
"array-includes": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz",
@@ -2272,24 +2293,25 @@
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
"dev": true
},
- "array.prototype.find": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.1.1.tgz",
- "integrity": "sha512-mi+MYNJYLTx2eNYy+Yh6raoQacCsNeeMUaspFPh9Y141lFSsWxxB8V9mM2ye+eqiRs917J6/pJ4M9ZPzenWckA==",
+ "array.prototype.flat": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz",
+ "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
- "es-abstract": "^1.17.4"
+ "es-abstract": "^1.17.0-next.1"
}
},
- "array.prototype.flat": {
+ "array.prototype.flatmap": {
"version": "1.2.3",
- "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz",
- "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==",
+ "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"
+ "es-abstract": "^1.17.0-next.1",
+ "function-bind": "^1.1.1"
}
},
"asn1": {
@@ -2586,12 +2608,6 @@
"file-uri-to-path": "1.0.0"
}
},
- "boolbase": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
- "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
- "dev": true
- },
"boxen": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
@@ -2692,13 +2708,13 @@
"dev": true
},
"browserslist": {
- "version": "4.12.2",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.2.tgz",
- "integrity": "sha512-MfZaeYqR8StRZdstAK9hCKDd2StvePCYp5rHzQCPicUjfFliDgmuaBNPHYUTpAywBN8+Wc/d7NYVFkO0aqaBUw==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.13.0.tgz",
+ "integrity": "sha512-MINatJ5ZNrLnQ6blGvePd/QOz9Xtu+Ne+x29iQSCHfkU5BugKVJwZKn/iiL8UbpIpa3JhviKjz+XxMo0m2caFQ==",
"dev": true,
"requires": {
- "caniuse-lite": "^1.0.30001088",
- "electron-to-chromium": "^1.3.483",
+ "caniuse-lite": "^1.0.30001093",
+ "electron-to-chromium": "^1.3.488",
"escalade": "^3.0.1",
"node-releases": "^1.1.58"
}
@@ -2748,9 +2764,9 @@
"dev": true
},
"caniuse-lite": {
- "version": "1.0.30001089",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001089.tgz",
- "integrity": "sha512-RnL5dbdqAfQ5oxHjFUU8uiyJMvTKoXfRn0Asp2R5cpRsyiY5+kLl0fcocQijb0V9XAWFEG/2A/vSswRmpYarmA==",
+ "version": "1.0.30001094",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001094.tgz",
+ "integrity": "sha512-ufHZNtMaDEuRBpTbqD93tIQnngmJ+oBknjvr0IbFympSdtFpAUFmNv4mVKbb53qltxFx0nK3iy32S9AqkLzUNA==",
"dev": true
},
"capture-exit": {
@@ -2797,20 +2813,6 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
"dev": true
},
- "cheerio": {
- "version": "1.0.0-rc.3",
- "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz",
- "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==",
- "dev": true,
- "requires": {
- "css-select": "~1.2.0",
- "dom-serializer": "~0.1.1",
- "entities": "~1.1.1",
- "htmlparser2": "^3.9.1",
- "lodash": "^4.15.0",
- "parse5": "^3.0.1"
- }
- },
"chokidar": {
"version": "2.1.8",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
@@ -2876,9 +2878,9 @@
}
},
"cli-width": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
- "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
+ "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
"dev": true
},
"cliui": {
@@ -3088,24 +3090,6 @@
"integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
"dev": true
},
- "css-select": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
- "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
- "dev": true,
- "requires": {
- "boolbase": "~1.0.0",
- "css-what": "2.1",
- "domutils": "1.5.1",
- "nth-check": "~1.0.1"
- }
- },
- "css-what": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
- "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
- "dev": true
- },
"cssom": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
@@ -3129,6 +3113,12 @@
}
}
},
+ "csstype": {
+ "version": "2.6.11",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.11.tgz",
+ "integrity": "sha512-l8YyEC9NBkSm783PFTvh0FmJy7s5pFKrDp49ZL7zBGX3fWkO+N4EEyan1qqp8cwPLDcD0OSdyY6hAMoxp34JFw==",
+ "dev": true
+ },
"dashdash": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
@@ -3159,10 +3149,13 @@
}
},
"decamelize": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
- "dev": true
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-3.2.0.tgz",
+ "integrity": "sha512-4TgkVUsmmu7oCSyGBm5FvfMoACuoh9EOidm7V5/J2X2djAwwt57qb3F2KMP2ITqODTCSwb+YRV+0Zqrv18k/hw==",
+ "dev": true,
+ "requires": {
+ "xregexp": "^4.2.4"
+ }
},
"decimal.js": {
"version": "10.2.0",
@@ -3262,12 +3255,6 @@
"integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==",
"dev": true
},
- "discontinuous-range": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz",
- "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=",
- "dev": true
- },
"doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@@ -3277,22 +3264,6 @@
"esutils": "^2.0.2"
}
},
- "dom-serializer": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
- "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
- "dev": true,
- "requires": {
- "domelementtype": "^1.3.0",
- "entities": "^1.1.1"
- }
- },
- "domelementtype": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
- "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
- "dev": true
- },
"domexception": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz",
@@ -3310,25 +3281,6 @@
}
}
},
- "domhandler": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
- "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
- "dev": true,
- "requires": {
- "domelementtype": "1"
- }
- },
- "domutils": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
- "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
- "dev": true,
- "requires": {
- "dom-serializer": "0",
- "domelementtype": "1"
- }
- },
"dot-prop": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
@@ -3355,9 +3307,9 @@
}
},
"electron-to-chromium": {
- "version": "1.3.483",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.483.tgz",
- "integrity": "sha512-+05RF8S9rk8S0G8eBCqBRBaRq7+UN3lDs2DAvnG8SBSgQO3hjy0+qt4CmRk5eiuGbTcaicgXfPmBi31a+BD3lg==",
+ "version": "1.3.490",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.490.tgz",
+ "integrity": "sha512-jKJF1mKXrQkT0ZiuJ/oV63Q02hAeWz0GGt/z6ryc518uCHtMyS9+wYAysZtBQ8rsjqFPAYXV4TIz5GQ8xyubPA==",
"dev": true
},
"emoji-regex": {
@@ -3375,83 +3327,6 @@
"once": "^1.4.0"
}
},
- "entities": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
- "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
- "dev": true
- },
- "enzyme": {
- "version": "3.11.0",
- "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.11.0.tgz",
- "integrity": "sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==",
- "dev": true,
- "requires": {
- "array.prototype.flat": "^1.2.3",
- "cheerio": "^1.0.0-rc.3",
- "enzyme-shallow-equal": "^1.0.1",
- "function.prototype.name": "^1.1.2",
- "has": "^1.0.3",
- "html-element-map": "^1.2.0",
- "is-boolean-object": "^1.0.1",
- "is-callable": "^1.1.5",
- "is-number-object": "^1.0.4",
- "is-regex": "^1.0.5",
- "is-string": "^1.0.5",
- "is-subset": "^0.1.1",
- "lodash.escape": "^4.0.1",
- "lodash.isequal": "^4.5.0",
- "object-inspect": "^1.7.0",
- "object-is": "^1.0.2",
- "object.assign": "^4.1.0",
- "object.entries": "^1.1.1",
- "object.values": "^1.1.1",
- "raf": "^3.4.1",
- "rst-selector-parser": "^2.2.3",
- "string.prototype.trim": "^1.2.1"
- }
- },
- "enzyme-adapter-react-16": {
- "version": "1.15.2",
- "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.2.tgz",
- "integrity": "sha512-SkvDrb8xU3lSxID8Qic9rB8pvevDbLybxPK6D/vW7PrT0s2Cl/zJYuXvsd1EBTz0q4o3iqG3FJhpYz3nUNpM2Q==",
- "dev": true,
- "requires": {
- "enzyme-adapter-utils": "^1.13.0",
- "enzyme-shallow-equal": "^1.0.1",
- "has": "^1.0.3",
- "object.assign": "^4.1.0",
- "object.values": "^1.1.1",
- "prop-types": "^15.7.2",
- "react-is": "^16.12.0",
- "react-test-renderer": "^16.0.0-0",
- "semver": "^5.7.0"
- }
- },
- "enzyme-adapter-utils": {
- "version": "1.13.0",
- "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.13.0.tgz",
- "integrity": "sha512-YuEtfQp76Lj5TG1NvtP2eGJnFKogk/zT70fyYHXK2j3v6CtuHqc8YmgH/vaiBfL8K1SgVVbQXtTcgQZFwzTVyQ==",
- "dev": true,
- "requires": {
- "airbnb-prop-types": "^2.15.0",
- "function.prototype.name": "^1.1.2",
- "object.assign": "^4.1.0",
- "object.fromentries": "^2.0.2",
- "prop-types": "^15.7.2",
- "semver": "^5.7.1"
- }
- },
- "enzyme-shallow-equal": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.1.tgz",
- "integrity": "sha512-hGA3i1so8OrYOZSM9whlkNmVHOicJpsjgTzC+wn2JMJXhq1oO4kA4bJ5MsfzSIcC71aLDKzJ6gZpIxrqt3QTAQ==",
- "dev": true,
- "requires": {
- "has": "^1.0.3",
- "object-is": "^1.0.2"
- }
- },
"error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -3638,9 +3513,9 @@
}
},
"eslint-plugin-babel": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-babel/-/eslint-plugin-babel-5.3.0.tgz",
- "integrity": "sha512-HPuNzSPE75O+SnxHIafbW5QB45r2w78fxqwK3HmjqIUoPfPzVrq6rD+CINU3yzoDSzEhUkX07VUphbF73Lth/w==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-babel/-/eslint-plugin-babel-5.3.1.tgz",
+ "integrity": "sha512-VsQEr6NH3dj664+EyxJwO4FCYm/00JhYb3Sk3ft8o+fpKuIfQ9TaW6uVUfvwMXHcf/lsnRIoyFPsLMyiWCSL/g==",
"dev": true,
"requires": {
"eslint-rule-composer": "^0.3.0"
@@ -3690,9 +3565,9 @@
}
},
"eslint-plugin-jest": {
- "version": "23.17.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.17.1.tgz",
- "integrity": "sha512-/o36fw67qNbJGWbSBIBMfseMsNP/d88WUHAGHCi1xFwsNB3XXZGdvxbOw49j3iQz6MCW/yw8OeOsuQhi6mM5ZA==",
+ "version": "23.18.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.18.0.tgz",
+ "integrity": "sha512-wLPM/Rm1SGhxrFQ2TKM/BYsYPhn7ch6ZEK92S2o/vGkAAnDXM0I4nTIo745RIX+VlCRMFgBuJEax6XfTHMdeKg==",
"dev": true,
"requires": {
"@typescript-eslint/experimental-utils": "^2.5.0"
@@ -3733,22 +3608,22 @@
"dev": true
},
"eslint-plugin-react": {
- "version": "7.20.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.0.tgz",
- "integrity": "sha512-rqe1abd0vxMjmbPngo4NaYxTcR3Y4Hrmc/jg4T+sYz63yqlmJRknpEQfmWY+eDWPuMmix6iUIK+mv0zExjeLgA==",
+ "version": "7.20.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.3.tgz",
+ "integrity": "sha512-txbo090buDeyV0ugF3YMWrzLIUqpYTsWSDZV9xLSmExE1P/Kmgg9++PD931r+KEWS66O1c9R4srLVVHmeHpoAg==",
"dev": true,
"requires": {
"array-includes": "^3.1.1",
+ "array.prototype.flatmap": "^1.2.3",
"doctrine": "^2.1.0",
"has": "^1.0.3",
- "jsx-ast-utils": "^2.2.3",
- "object.entries": "^1.1.1",
+ "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.15.1",
- "string.prototype.matchall": "^4.0.2",
- "xregexp": "^4.3.0"
+ "resolve": "^1.17.0",
+ "string.prototype.matchall": "^4.0.2"
},
"dependencies": {
"doctrine": {
@@ -4228,29 +4103,12 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
- "function.prototype.name": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.2.tgz",
- "integrity": "sha512-C8A+LlHBJjB2AdcRPorc5JvJ5VUoWlXdEHLOJdCI7kjHEtGTpHQUiqMvCIKUwIsGwZX2jZJy761AXsn356bJQg==",
- "dev": true,
- "requires": {
- "define-properties": "^1.1.3",
- "es-abstract": "^1.17.0-next.1",
- "functions-have-names": "^1.2.0"
- }
- },
"functional-red-black-tree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
"dev": true
},
- "functions-have-names": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.1.tgz",
- "integrity": "sha512-j48B/ZI7VKs3sgeI2cZp7WXWmZXu7Iq5pl5/vptV5N2mq+DGFuS/ulaDjtaoLpYzuD6u8UgrUKHfgo7fDTSiBA==",
- "dev": true
- },
"gensync": {
"version": "1.0.0-beta.1",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
@@ -4458,15 +4316,6 @@
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
"dev": true
},
- "html-element-map": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/html-element-map/-/html-element-map-1.2.0.tgz",
- "integrity": "sha512-0uXq8HsuG1v2TmQ8QkIhzbrqeskE4kn52Q18QJ9iAA/SnHoEKXWiUxHQtclRsCFWEUD2So34X+0+pZZu862nnw==",
- "dev": true,
- "requires": {
- "array-filter": "^1.0.0"
- }
- },
"html-encoding-sniffer": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
@@ -4482,33 +4331,6 @@
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"dev": true
},
- "htmlparser2": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
- "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
- "dev": true,
- "requires": {
- "domelementtype": "^1.3.1",
- "domhandler": "^2.3.0",
- "domutils": "^1.5.1",
- "entities": "^1.1.1",
- "inherits": "^2.0.1",
- "readable-stream": "^3.1.1"
- },
- "dependencies": {
- "readable-stream": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
- "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
- "dev": true,
- "requires": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- }
- }
- }
- },
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
@@ -4662,21 +4484,21 @@
"dev": true
},
"inquirer": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.2.0.tgz",
- "integrity": "sha512-E0c4rPwr9ByePfNlTIB8z51kK1s2n6jrHuJeEHENl/sbq2G/S1auvibgEwNR4uSyiU+PiYHqSwsgGiXjG8p5ZQ==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.0.tgz",
+ "integrity": "sha512-K+LZp6L/6eE5swqIcVXrxl21aGDU4S50gKH0/d96OMQnSBCyGyZl/oZhbkVmdp5sBoINHd4xZvFSARh2dk6DWA==",
"dev": true,
"requires": {
"ansi-escapes": "^4.2.1",
- "chalk": "^3.0.0",
+ "chalk": "^4.1.0",
"cli-cursor": "^3.1.0",
- "cli-width": "^2.0.0",
+ "cli-width": "^3.0.0",
"external-editor": "^3.0.3",
"figures": "^3.0.0",
"lodash": "^4.17.15",
"mute-stream": "0.0.8",
"run-async": "^2.4.0",
- "rxjs": "^6.5.3",
+ "rxjs": "^6.6.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0",
"through": "^2.3.6"
@@ -4693,9 +4515,9 @@
}
},
"chalk": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
- "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -4804,12 +4626,6 @@
"binary-extensions": "^1.0.0"
}
},
- "is-boolean-object": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.0.1.tgz",
- "integrity": "sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ==",
- "dev": true
- },
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
@@ -4952,12 +4768,6 @@
}
}
},
- "is-number-object": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz",
- "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==",
- "dev": true
- },
"is-obj": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
@@ -5021,12 +4831,6 @@
"integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==",
"dev": true
},
- "is-subset": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz",
- "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=",
- "dev": true
- },
"is-symbol": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
@@ -5302,9 +5106,9 @@
}
},
"execa": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz",
- "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz",
+ "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==",
"dev": true,
"requires": {
"cross-spawn": "^7.0.0",
@@ -6818,14 +6622,6 @@
"whatwg-url": "^8.0.0",
"ws": "^7.2.3",
"xml-name-validator": "^3.0.0"
- },
- "dependencies": {
- "parse5": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
- "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
- "dev": true
- }
}
},
"jsesc": {
@@ -6983,24 +6779,6 @@
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
},
- "lodash.escape": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz",
- "integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=",
- "dev": true
- },
- "lodash.flattendeep": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
- "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
- "dev": true
- },
- "lodash.isequal": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
- "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
- "dev": true
- },
"lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@@ -7159,12 +6937,6 @@
"minimist": "^1.2.5"
}
},
- "moo": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz",
- "integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==",
- "dev": true
- },
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -7209,27 +6981,6 @@
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
- "nearley": {
- "version": "2.19.4",
- "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.19.4.tgz",
- "integrity": "sha512-oqj3m4oqwKsN77pETa9IPvxHHHLW68KrDc2KYoWMUOhDlrNUo7finubwffQMBRnwNCOXc4kRxCZO0Rvx4L6Zrw==",
- "dev": true,
- "requires": {
- "commander": "^2.19.0",
- "moo": "^0.5.0",
- "railroad-diagrams": "^1.0.0",
- "randexp": "0.4.6",
- "semver": "^5.4.1"
- },
- "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
- }
- }
- },
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
@@ -7369,15 +7120,6 @@
"through2": "^2.0.0"
}
},
- "nth-check": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
- "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
- "dev": true,
- "requires": {
- "boolbase": "~1.0.0"
- }
- },
"nwsapi": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
@@ -7433,16 +7175,6 @@
"integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==",
"dev": true
},
- "object-is": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz",
- "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==",
- "dev": true,
- "requires": {
- "define-properties": "^1.1.3",
- "es-abstract": "^1.17.5"
- }
- },
"object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
@@ -7619,13 +7351,10 @@
}
},
"parse5": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
- "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
- "dev": true,
- "requires": {
- "@types/node": "*"
- }
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
+ "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+ "dev": true
},
"pascalcase": {
"version": "0.1.1",
@@ -7779,12 +7508,6 @@
}
}
},
- "private": {
- "version": "0.1.8",
- "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
- "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
- "dev": true
- },
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -7818,17 +7541,6 @@
"react-is": "^16.8.1"
}
},
- "prop-types-exact": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/prop-types-exact/-/prop-types-exact-1.2.0.tgz",
- "integrity": "sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==",
- "dev": true,
- "requires": {
- "has": "^1.0.3",
- "object.assign": "^4.1.0",
- "reflect.ownkeys": "^0.2.0"
- }
- },
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
@@ -7869,31 +7581,6 @@
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
"dev": true
},
- "raf": {
- "version": "3.4.1",
- "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
- "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
- "dev": true,
- "requires": {
- "performance-now": "^2.1.0"
- }
- },
- "railroad-diagrams": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
- "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=",
- "dev": true
- },
- "randexp": {
- "version": "0.4.6",
- "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz",
- "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==",
- "dev": true,
- "requires": {
- "discontinuous-range": "1.0.0",
- "ret": "~0.1.10"
- }
- },
"rc": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@@ -8002,12 +7689,6 @@
"readable-stream": "^2.0.2"
}
},
- "reflect.ownkeys": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz",
- "integrity": "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=",
- "dev": true
- },
"regenerate": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz",
@@ -8030,13 +7711,12 @@
"dev": true
},
"regenerator-transform": {
- "version": "0.14.4",
- "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz",
- "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==",
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz",
+ "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==",
"dev": true,
"requires": {
- "@babel/runtime": "^7.8.4",
- "private": "^0.1.8"
+ "@babel/runtime": "^7.8.4"
}
},
"regex-not": {
@@ -8292,16 +7972,6 @@
"glob": "^7.1.3"
}
},
- "rst-selector-parser": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz",
- "integrity": "sha1-gbIw6i/MYGbInjRy3nlChdmwPZE=",
- "dev": true,
- "requires": {
- "lodash.flattendeep": "^4.4.0",
- "nearley": "^2.7.10"
- }
- },
"rsvp": {
"version": "4.8.5",
"resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz",
@@ -8315,9 +7985,9 @@
"dev": true
},
"rxjs": {
- "version": "6.5.5",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz",
- "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==",
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz",
+ "integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==",
"dev": true,
"requires": {
"tslib": "^1.9.0"
@@ -8808,17 +8478,6 @@
"side-channel": "^1.0.2"
}
},
- "string.prototype.trim": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz",
- "integrity": "sha512-MjGFEeqixw47dAMFMtgUro/I0+wNqZB5GKXGt1fFr24u3TzDXCPu7J9Buppzoe3r/LqkSDLDDJzE15RGWDGAVw==",
- "dev": true,
- "requires": {
- "define-properties": "^1.1.3",
- "es-abstract": "^1.17.0-next.1",
- "function-bind": "^1.1.1"
- }
- },
"string.prototype.trimend": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
@@ -9680,9 +9339,9 @@
}
},
"ws": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz",
- "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==",
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
+ "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==",
"dev": true
},
"xdg-basedir": {
@@ -9731,13 +9390,13 @@
"dev": true
},
"yargs": {
- "version": "15.3.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
- "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==",
+ "version": "15.4.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.0.tgz",
+ "integrity": "sha512-D3fRFnZwLWp8jVAAhPZBsmeIHY8tTsb8ItV9KaAaopmC6wde2u6Yw29JBIZHXw14kgkRnYmDgmQU4FVMDlIsWw==",
"dev": true,
"requires": {
"cliui": "^6.0.0",
- "decamelize": "^1.2.0",
+ "decamelize": "^3.2.0",
"find-up": "^4.1.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
@@ -9746,7 +9405,7 @@
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
- "yargs-parser": "^18.1.1"
+ "yargs-parser": "^18.1.2"
},
"dependencies": {
"find-up": {
@@ -9808,6 +9467,14 @@
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
+ },
+ "dependencies": {
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ }
}
}
}
diff --git a/package.json b/package.json
index 3f44c82..51325e5 100644
--- a/package.json
+++ b/package.json
@@ -1,12 +1,15 @@
{
"name": "react-speech-recognition",
- "version": "2.1.4",
+ "version": "3.0.0",
"description": "A React component that converts speech from the microphone to text.",
"main": "lib/index.js",
"scripts": {
- "build": "babel src -d lib",
+ "build": "babel src -d lib --ignore '**/*.test.js'",
"lint": "eslint src tests",
- "test": "jest",
+ "test": "jest --testPathIgnorePatterns=example",
+ "coverage": "npm run coverage:collect && npm run coverage:report",
+ "coverage:collect": "jest --testPathIgnorePatterns=example --collectCoverageFrom=src/**/*.{js,jsx} --coverage",
+ "coverage:report": "open coverage/lcov-report/index.html",
"prepublishOnly": "npm run build",
"update-example": "cp -R src/ example/src/SpeechRecognition",
"run-example": "cd example && npm i && npm start",
@@ -33,16 +36,15 @@
"author": "James Brill ",
"license": "MIT",
"peerDependencies": {
- "react": ">=16"
+ "react": ">=16.8.0"
},
"devDependencies": {
"@babel/cli": "^7.10.3",
"@babel/core": "^7.10.3",
"@babel/preset-env": "^7.10.3",
"@babel/preset-react": "^7.10.1",
+ "@testing-library/react-hooks": "^3.3.0",
"babel-eslint": "^10.0.2",
- "enzyme": "^3.11.0",
- "enzyme-adapter-react-16": "^1.15.2",
"eslint": "^6.0.1",
"eslint-config-standard": "^13.0.1",
"eslint-plugin-babel": "^5.3.0",
@@ -55,6 +57,17 @@
"jest": "^26.1.0",
"npm-watch": "^0.6.0",
"react": "^16.13.1",
- "react-dom": "^16.13.1"
+ "react-dom": "^16.13.1",
+ "react-test-renderer": "16.13.1"
+ },
+ "jest": {
+ "coverageThreshold": {
+ "global": {
+ "branches": 75,
+ "functions": 75,
+ "lines": 75,
+ "statements": 75
+ }
+ }
}
}
diff --git a/src/RecognitionManager.js b/src/RecognitionManager.js
new file mode 100644
index 0000000..1d21b17
--- /dev/null
+++ b/src/RecognitionManager.js
@@ -0,0 +1,197 @@
+import isAndroid from './isAndroid'
+import { debounce, concatTranscripts } from './utils'
+
+export default class RecognitionManager {
+ constructor() {
+ const BrowserSpeechRecognition =
+ typeof window !== 'undefined' &&
+ (window.SpeechRecognition ||
+ window.webkitSpeechRecognition ||
+ window.mozSpeechRecognition ||
+ window.msSpeechRecognition ||
+ window.oSpeechRecognition)
+ this.recognition = BrowserSpeechRecognition
+ ? new BrowserSpeechRecognition()
+ : null
+ this.browserSupportsSpeechRecognition = this.recognition !== null
+ this.pauseAfterDisconnect = false
+ this.interimTranscript = ''
+ this.finalTranscript = ''
+ this.listening = false
+ this.subscribers = {}
+ this.onStopListening = () => {}
+
+ if (this.browserSupportsSpeechRecognition) {
+ this.recognition.continuous = false
+ this.recognition.interimResults = true
+ this.recognition.onresult = this.updateTranscript.bind(this)
+ this.recognition.onend = this.onRecognitionDisconnect.bind(this)
+ }
+
+ this.resetTranscript = this.resetTranscript.bind(this)
+ this.startListening = this.startListening.bind(this)
+ this.stopListening = this.stopListening.bind(this)
+ this.abortListening = this.abortListening.bind(this)
+
+ if (isAndroid()) {
+ this.updateFinalTranscript = debounce(this.updateFinalTranscript, 250, true)
+ }
+ }
+
+ subscribe(id, callbacks) {
+ this.subscribers[id] = callbacks
+ }
+
+ unsubscribe(id) {
+ delete this.subscribers[id]
+ }
+
+ emitListeningChange(listening) {
+ this.listening = listening
+ Object.keys(this.subscribers).forEach((id) => {
+ const { onListeningChange } = this.subscribers[id]
+ onListeningChange(listening)
+ })
+ }
+
+ emitTranscriptChange(interimTranscript, finalTranscript) {
+ Object.keys(this.subscribers).forEach((id) => {
+ const { onTranscriptChange } = this.subscribers[id]
+ onTranscriptChange(interimTranscript, finalTranscript)
+ })
+ }
+
+ emitClearTranscript() {
+ Object.keys(this.subscribers).forEach((id) => {
+ const { onClearTranscript } = this.subscribers[id]
+ onClearTranscript()
+ })
+ }
+
+ disconnect(disconnectType) {
+ if (this.browserSupportsSpeechRecognition) {
+ switch (disconnectType) {
+ case 'ABORT':
+ this.pauseAfterDisconnect = true
+ this.abort()
+ break
+ case 'RESET':
+ this.pauseAfterDisconnect = false
+ this.abort()
+ break
+ case 'STOP':
+ default:
+ this.pauseAfterDisconnect = true
+ this.stop()
+ }
+ }
+ }
+
+ onRecognitionDisconnect() {
+ this.onStopListening()
+ this.listening = false
+ if (this.pauseAfterDisconnect) {
+ this.emitListeningChange(false)
+ } else if (this.browserSupportsSpeechRecognition) {
+ if (this.recognition.continuous) {
+ this.startListening({ continuous: this.recognition.continuous })
+ } else {
+ this.emitListeningChange(false)
+ }
+ }
+ this.pauseAfterDisconnect = false
+ }
+
+ updateTranscript(event) {
+ this.interimTranscript = ''
+ this.finalTranscript = ''
+ for (let i = event.resultIndex; i < event.results.length; ++i) {
+ if (event.results[i].isFinal && (!isAndroid() || event.results[i][0].confidence > 0)) {
+ this.updateFinalTranscript(event.results[i][0].transcript)
+ } else {
+ this.interimTranscript = concatTranscripts(
+ this.interimTranscript,
+ event.results[i][0].transcript
+ )
+ }
+ }
+ this.emitTranscriptChange(this.interimTranscript, this.finalTranscript)
+ }
+
+ updateFinalTranscript(newFinalTranscript) {
+ this.finalTranscript = concatTranscripts(
+ this.finalTranscript,
+ newFinalTranscript
+ )
+ }
+
+ resetTranscript() {
+ this.disconnect('RESET')
+ }
+
+ async startListening({ continuous = false, language } = {}) {
+ if (!this.browserSupportsSpeechRecognition) {
+ return
+ }
+
+ const isContinuousChanged = continuous !== this.recognition.continuous
+ const isLanguageChanged = language && language !== this.recognition.lang
+ if (isContinuousChanged || isLanguageChanged) {
+ if (this.listening) {
+ this.stopListening()
+ await new Promise(resolve => {
+ this.onStopListening = resolve
+ })
+ }
+ this.recognition.continuous = isContinuousChanged ? continuous : this.recognition.continuous
+ this.recognition.lang = isLanguageChanged ? language : this.recognition.lang
+ }
+ if (!this.listening) {
+ if (!this.recognition.continuous) {
+ this.resetTranscript()
+ this.emitClearTranscript()
+ }
+ try {
+ this.start()
+ } catch (DOMException) {
+ // Tried to start recognition after it has already started - safe to swallow this error
+ }
+ this.emitListeningChange(true)
+ }
+ }
+
+ abortListening() {
+ this.disconnect('ABORT')
+ this.emitListeningChange(false)
+ }
+
+ stopListening() {
+ this.disconnect('STOP')
+ this.emitListeningChange(false)
+ }
+
+ getRecognition() {
+ return this.recognition
+ }
+
+ start() {
+ if (this.browserSupportsSpeechRecognition && !this.listening) {
+ this.recognition.start()
+ this.listening = true
+ }
+ }
+
+ stop() {
+ if (this.browserSupportsSpeechRecognition && this.listening) {
+ this.recognition.stop()
+ this.listening = false
+ }
+ }
+
+ abort() {
+ if (this.browserSupportsSpeechRecognition && this.listening) {
+ this.recognition.abort()
+ this.listening = false
+ }
+ }
+}
diff --git a/src/SpeechRecognition.js b/src/SpeechRecognition.js
index eb57ec8..e9a73fe 100644
--- a/src/SpeechRecognition.js
+++ b/src/SpeechRecognition.js
@@ -1,180 +1,124 @@
-import React, { Component } from 'react'
-import { debounce } from './utils'
-
-export default function SpeechRecognition(options) {
- const SpeechRecognitionInner = function (WrappedComponent) {
- const BrowserSpeechRecognition =
- typeof window !== 'undefined' &&
- (window.SpeechRecognition ||
- window.webkitSpeechRecognition ||
- window.mozSpeechRecognition ||
- window.msSpeechRecognition ||
- window.oSpeechRecognition)
- const recognition = BrowserSpeechRecognition
- ? new BrowserSpeechRecognition()
- : null
- const browserSupportsSpeechRecognition = recognition !== null
- const isAndroid = /(android)/i.test(navigator.userAgent)
- let listening
- if (
- !browserSupportsSpeechRecognition ||
- (options && options.autoStart === false)
- ) {
- listening = false
- } else {
- recognition.start()
- listening = true
- }
- let pauseAfterDisconnect = false
- let interimTranscript = ''
- let finalTranscript = ''
-
- return class SpeechRecognitionContainer extends Component {
- constructor(props) {
- super(props)
-
- if (browserSupportsSpeechRecognition) {
- recognition.continuous = options.continuous !== false
- recognition.interimResults = true
- recognition.onresult = this.updateTranscript.bind(this)
- recognition.onend = this.onRecognitionDisconnect.bind(this)
- }
-
- this.disconnect = this.disconnect.bind(this)
- this.resetTranscript = this.resetTranscript.bind(this)
- this.startListening = this.startListening.bind(this)
- this.abortListening = this.abortListening.bind(this)
- this.stopListening = this.stopListening.bind(this)
-
- if (isAndroid) {
- this.updateFinalTranscript = debounce(this.updateFinalTranscript.bind(this), 250, true)
- }
-
- this.state = {
- interimTranscript,
- finalTranscript,
- listening
- }
- }
-
- disconnect(disconnectType) {
- if (recognition) {
- switch (disconnectType) {
- case 'ABORT':
- pauseAfterDisconnect = true
- recognition.abort()
- break
- case 'RESET':
- pauseAfterDisconnect = false
- recognition.abort()
- break
- case 'STOP':
- default:
- pauseAfterDisconnect = true
- recognition.stop()
- }
- }
- }
-
- onRecognitionDisconnect() {
- listening = false
- if (pauseAfterDisconnect) {
- this.setState({ listening })
- } else if (recognition) {
- if (recognition.continuous) {
- this.startListening()
- } else {
- this.setState({ listening })
- }
- }
- pauseAfterDisconnect = false
- }
-
- updateTranscript(event) {
- interimTranscript = ''
- for (let i = event.resultIndex; i < event.results.length; ++i) {
- if (event.results[i].isFinal && (!isAndroid || event.results[i][0].confidence > 0)) {
- this.updateFinalTranscript(event.results[i][0].transcript)
- } else {
- interimTranscript = this.concatTranscripts(
- interimTranscript,
- event.results[i][0].transcript
- )
- }
- }
- this.setState({ finalTranscript, interimTranscript })
- }
-
- updateFinalTranscript(newFinalTranscript) {
- finalTranscript = this.concatTranscripts(
- finalTranscript,
- newFinalTranscript
- )
- }
-
- concatTranscripts(...transcriptParts) {
- return transcriptParts.map(t => t.trim()).join(' ').trim()
- }
-
- resetTranscript() {
- interimTranscript = ''
- finalTranscript = ''
- this.disconnect('RESET')
- this.setState({ interimTranscript, finalTranscript })
- }
+import { useState, useEffect, useReducer, useCallback } from 'react'
+import { concatTranscripts, commandToRegExp } from './utils'
+import { clearTrancript, appendTrancript } from './actions'
+import { transcriptReducer } from './reducers'
+import RecognitionManager from './RecognitionManager'
+
+const useSpeechRecognition = ({
+ transcribing = true,
+ clearTranscriptOnListen = true,
+ commands = []
+} = {}) => {
+ const [recognitionManager] = useState(SpeechRecognition.getRecognitionManager())
+ const [{ interimTranscript, finalTranscript }, dispatch] = useReducer(transcriptReducer, {
+ interimTranscript: recognitionManager.interimTranscript,
+ finalTranscript: ''
+ })
+ const [listening, setListening] = useState(recognitionManager.listening)
+
+ const clearTranscript = () => {
+ dispatch(clearTrancript())
+ }
- startListening() {
- if (recognition && !listening) {
- if (!recognition.continuous) {
- this.resetTranscript()
- }
- try {
- recognition.start()
- } catch (DOMException) {
- // Tried to start recognition after it has already started - safe to swallow this error
- }
- listening = true
- this.setState({ listening })
+ const matchCommands = useCallback(
+ (newInterimTranscript, newFinalTranscript) => {
+ commands.forEach(({ command, callback, matchInterim = false }) => {
+ const pattern = commandToRegExp(command)
+ const input = !newFinalTranscript && matchInterim
+ ? newInterimTranscript.trim()
+ : newFinalTranscript.trim()
+ const result = pattern.exec(input)
+ if (result) {
+ const parameters = result.slice(1)
+ callback(...parameters)
}
+ })
+ }, [commands]
+ )
+
+ const handleTranscriptChange = useCallback(
+ (newInterimTranscript, newFinalTranscript) => {
+ matchCommands(newInterimTranscript, newFinalTranscript)
+ if (transcribing) {
+ dispatch(appendTrancript(newInterimTranscript, newFinalTranscript))
}
+ }, [matchCommands, transcribing]
+ )
- abortListening() {
- listening = false
- this.setState({ listening })
- this.disconnect('ABORT')
+ const handleClearTranscript = useCallback(
+ () => {
+ if (clearTranscriptOnListen) {
+ clearTranscript()
}
+ }, [clearTranscriptOnListen]
+ )
- stopListening() {
- listening = false
- this.setState({ listening })
- this.disconnect('STOP')
- }
+ const resetTranscript = () => {
+ recognitionManager.resetTranscript()
+ clearTranscript()
+ }
- render() {
- const transcript = this.concatTranscripts(
- finalTranscript,
- interimTranscript
- )
+ useEffect(() => {
+ const id = SpeechRecognition.counter
+ SpeechRecognition.counter += 1
+ const callbacks = {
+ onListeningChange: setListening,
+ onTranscriptChange: handleTranscriptChange,
+ onClearTranscript: handleClearTranscript
+ }
+ recognitionManager.subscribe(id, callbacks)
- return (
-
- )
- }
+ return () => {
+ recognitionManager.unsubscribe(id)
}
+ }, [
+ transcribing,
+ clearTranscriptOnListen,
+ recognitionManager,
+ handleTranscriptChange,
+ handleClearTranscript
+ ])
+
+ const transcript = concatTranscripts(finalTranscript, interimTranscript)
+ return {
+ transcript,
+ interimTranscript,
+ finalTranscript,
+ listening,
+ resetTranscript
}
+}
- if (typeof options === 'function') {
- return SpeechRecognitionInner(options)
- } else {
- return SpeechRecognitionInner
+let recognitionManager
+const SpeechRecognition = {
+ counter: 0,
+ getRecognitionManager: () => {
+ if (!recognitionManager) {
+ recognitionManager = new RecognitionManager()
+ }
+ return recognitionManager
+ },
+ getRecognition: () => {
+ const recognitionManager = SpeechRecognition.getRecognitionManager()
+ return recognitionManager.getRecognition()
+ },
+ startListening: async ({ continuous, language } = {}) => {
+ const recognitionManager = SpeechRecognition.getRecognitionManager()
+ await recognitionManager.startListening({ continuous, language })
+ },
+ stopListening: () => {
+ const recognitionManager = SpeechRecognition.getRecognitionManager()
+ recognitionManager.stopListening()
+ },
+ abortListening: () => {
+ const recognitionManager = SpeechRecognition.getRecognitionManager()
+ recognitionManager.abortListening()
+ },
+ browserSupportsSpeechRecognition: () => {
+ const recognitionManager = SpeechRecognition.getRecognitionManager()
+ return recognitionManager.browserSupportsSpeechRecognition
}
}
+
+export { useSpeechRecognition }
+export default SpeechRecognition
diff --git a/src/SpeechRecognition.test.js b/src/SpeechRecognition.test.js
new file mode 100644
index 0000000..c2fcfdf
--- /dev/null
+++ b/src/SpeechRecognition.test.js
@@ -0,0 +1,699 @@
+import { renderHook, act } from '@testing-library/react-hooks'
+import '../tests/vendor/corti'
+import SpeechRecognition, { useSpeechRecognition } from './SpeechRecognition'
+import isAndroid from './isAndroid'
+import RecognitionManager from './RecognitionManager'
+
+jest.mock('./isAndroid')
+
+const mockRecognitionManager = () => {
+ const recognitionManager = new RecognitionManager()
+ SpeechRecognition.getRecognitionManager = () => recognitionManager
+ return recognitionManager
+}
+
+describe('SpeechRecognition', () => {
+ beforeEach(() => {
+ isAndroid.mockClear()
+ })
+
+ test('indicates when SpeechRecognition API is available', () => {
+ const recognitionManager = mockRecognitionManager()
+ recognitionManager.browserSupportsSpeechRecognition = true
+
+ expect(SpeechRecognition.browserSupportsSpeechRecognition()).toEqual(true)
+ })
+
+ test('indicates when SpeechRecognition API is not available', () => {
+ const recognitionManager = mockRecognitionManager()
+ recognitionManager.browserSupportsSpeechRecognition = false
+
+ expect(SpeechRecognition.browserSupportsSpeechRecognition()).toEqual(false)
+ })
+
+ test('sets default transcripts correctly', () => {
+ const { result } = renderHook(() => useSpeechRecognition())
+
+ const { transcript, interimTranscript, finalTranscript } = result.current
+ expect(transcript).toEqual('')
+ expect(interimTranscript).toEqual('')
+ expect(finalTranscript).toEqual('')
+ })
+
+ test('updates transcripts correctly', async () => {
+ mockRecognitionManager()
+ const { result } = renderHook(() => useSpeechRecognition())
+ const speech = 'This is a test'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ const { transcript, interimTranscript, finalTranscript } = result.current
+ expect(transcript).toEqual(speech)
+ expect(interimTranscript).toEqual('')
+ expect(finalTranscript).toEqual(speech)
+ })
+
+ test('resets transcripts correctly', async () => {
+ mockRecognitionManager()
+ const { result } = renderHook(() => useSpeechRecognition())
+ const speech = 'This is a test'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+ act(() => {
+ result.current.resetTranscript()
+ })
+
+ const { transcript, interimTranscript, finalTranscript } = result.current
+ expect(transcript).toEqual('')
+ expect(interimTranscript).toEqual('')
+ expect(finalTranscript).toEqual('')
+ })
+
+ test('is listening when Speech Recognition is listening', async () => {
+ mockRecognitionManager()
+ const { result } = renderHook(() => useSpeechRecognition())
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+
+ expect(result.current.listening).toEqual(true)
+ })
+
+ test('is not listening when Speech Recognition is not listening', () => {
+ mockRecognitionManager()
+ const { result } = renderHook(() => useSpeechRecognition())
+
+ expect(result.current.listening).toEqual(false)
+ })
+
+ test('exposes Speech Recognition object', () => {
+ const recognitionManager = mockRecognitionManager()
+
+ expect(SpeechRecognition.getRecognition()).toEqual(recognitionManager.recognition)
+ })
+
+ test('ignores speech when listening is stopped', () => {
+ mockRecognitionManager()
+ const { result } = renderHook(() => useSpeechRecognition())
+ const speech = 'This is a test'
+
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ const { transcript, interimTranscript, finalTranscript } = result.current
+ expect(transcript).toEqual('')
+ expect(interimTranscript).toEqual('')
+ expect(finalTranscript).toEqual('')
+ })
+
+ test('ignores speech when listening is aborted', () => {
+ mockRecognitionManager()
+ const { result } = renderHook(() => useSpeechRecognition())
+ const speech = 'This is a test'
+
+ act(() => {
+ SpeechRecognition.abortListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ const { transcript, interimTranscript, finalTranscript } = result.current
+ expect(transcript).toEqual('')
+ expect(interimTranscript).toEqual('')
+ expect(finalTranscript).toEqual('')
+ })
+
+ test('transcibes when listening is started', async () => {
+ mockRecognitionManager()
+ const { result } = renderHook(() => useSpeechRecognition())
+ const speech = 'This is a test'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ const { transcript, interimTranscript, finalTranscript } = result.current
+ expect(transcript).toEqual(speech)
+ expect(interimTranscript).toEqual('')
+ expect(finalTranscript).toEqual(speech)
+ })
+
+ test('does not transcibe when listening is started but not transcribing', async () => {
+ mockRecognitionManager()
+ const { result } = renderHook(() => useSpeechRecognition({ transcribing: false }))
+ const speech = 'This is a test'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ const { transcript, interimTranscript, finalTranscript } = result.current
+ expect(transcript).toEqual('')
+ expect(interimTranscript).toEqual('')
+ expect(finalTranscript).toEqual('')
+ })
+
+ test('listens discontinuously by default', async () => {
+ mockRecognitionManager()
+ renderHook(() => useSpeechRecognition())
+ const speech = 'This is a test'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+ })
+
+ test('can turn continuous listening on', async () => {
+ mockRecognitionManager()
+ const { result } = renderHook(() => useSpeechRecognition())
+ const speech = 'This is a test'
+ const expectedTranscript = [speech, speech].join(' ')
+
+ await act(async () => {
+ await SpeechRecognition.startListening({ continuous: true })
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ const { transcript, interimTranscript, finalTranscript } = result.current
+ expect(transcript).toEqual(expectedTranscript)
+ expect(interimTranscript).toEqual('')
+ expect(finalTranscript).toEqual(expectedTranscript)
+ })
+
+ test('can set language', async () => {
+ mockRecognitionManager()
+ renderHook(() => useSpeechRecognition())
+
+ await act(async () => {
+ await SpeechRecognition.startListening({ language: 'zh-CN' })
+ })
+
+ expect(SpeechRecognition.getRecognition().lang).toEqual('zh-CN')
+ })
+
+ test('does not collect transcript after listening is stopped', async () => {
+ mockRecognitionManager()
+ const { result } = renderHook(() => useSpeechRecognition())
+ const speech = 'This is a test'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.stopListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ const { transcript, interimTranscript, finalTranscript } = result.current
+ expect(transcript).toEqual('')
+ expect(interimTranscript).toEqual('')
+ expect(finalTranscript).toEqual('')
+ })
+
+ test('sets interim transcript correctly', async() => {
+ mockRecognitionManager()
+ const { result } = renderHook(() => useSpeechRecognition())
+ const speech = 'This is a test'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech, { onlyFirstResult: true })
+ })
+
+ const { transcript, interimTranscript, finalTranscript } = result.current
+ expect(transcript).toEqual('This')
+ expect(interimTranscript).toEqual('This')
+ expect(finalTranscript).toEqual('')
+ })
+
+ test('appends interim transcript correctly', async () => {
+ mockRecognitionManager()
+ const { result } = renderHook(() => useSpeechRecognition())
+ const speech = 'This is a test'
+
+ await act(async () => {
+ await SpeechRecognition.startListening({ continuous: true })
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech, { onlyFirstResult: true })
+ })
+
+ const { transcript, interimTranscript, finalTranscript } = result.current
+ expect(transcript).toEqual('This is a test This')
+ expect(interimTranscript).toEqual('This')
+ expect(finalTranscript).toEqual(speech)
+ })
+
+ test('appends interim transcript correctly on Android', async () => {
+ isAndroid.mockReturnValue(true)
+ mockRecognitionManager()
+ const { result } = renderHook(() => useSpeechRecognition())
+ const speech = 'This is a test'
+
+ await act(async () => {
+ await SpeechRecognition.startListening({ continuous: true })
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech, { isAndroid: true })
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech, { onlyFirstResult: true, isAndroid: true })
+ })
+
+ const { transcript, interimTranscript, finalTranscript } = result.current
+ expect(transcript).toEqual('This is a test This')
+ expect(interimTranscript).toEqual('This')
+ expect(finalTranscript).toEqual(speech)
+ })
+
+ test('resets transcript on subsequent discontinuous speech when clearTranscriptOnListen set', async () => {
+ mockRecognitionManager()
+ const { result } = renderHook(() => useSpeechRecognition())
+ const speech = 'This is a test'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ expect(result.current.transcript).toEqual(speech)
+ expect(result.current.interimTranscript).toEqual('')
+ expect(result.current.finalTranscript).toEqual(speech)
+
+ act(() => {
+ SpeechRecognition.stopListening()
+ })
+
+ expect(result.current.transcript).toEqual(speech)
+ expect(result.current.interimTranscript).toEqual('')
+ expect(result.current.finalTranscript).toEqual(speech)
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+
+ expect(result.current.transcript).toEqual('')
+ expect(result.current.interimTranscript).toEqual('')
+ expect(result.current.finalTranscript).toEqual('')
+ })
+
+ test('does not reset transcript on subsequent discontinuous speech when clearTranscriptOnListen not set', async () => {
+ mockRecognitionManager()
+ const { result } = renderHook(() => useSpeechRecognition({ clearTranscriptOnListen: false }))
+ const speech = 'This is a test'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+ expect(result.current.transcript).toEqual(speech)
+ expect(result.current.interimTranscript).toEqual('')
+ expect(result.current.finalTranscript).toEqual(speech)
+
+ act(() => {
+ SpeechRecognition.stopListening()
+ })
+
+ expect(result.current.transcript).toEqual(speech)
+ expect(result.current.interimTranscript).toEqual('')
+ expect(result.current.finalTranscript).toEqual(speech)
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+
+ expect(result.current.transcript).toEqual(speech)
+ expect(result.current.interimTranscript).toEqual('')
+ expect(result.current.finalTranscript).toEqual(speech)
+ })
+
+ test('does not call command callback when no command matched', async () => {
+ mockRecognitionManager()
+ const mockCommandCallback = jest.fn()
+ const commands = [
+ {
+ command: 'hello world',
+ callback: mockCommandCallback,
+ matchInterim: false
+ }
+ ]
+ renderHook(() => useSpeechRecognition({ commands }))
+ const speech = 'This is a test'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ expect(mockCommandCallback.mock.calls.length).toBe(0)
+ })
+
+ test('matches simple command', async () => {
+ mockRecognitionManager()
+ const mockCommandCallback = jest.fn()
+ const commands = [
+ {
+ command: 'hello world',
+ callback: mockCommandCallback
+ }
+ ]
+ renderHook(() => useSpeechRecognition({ commands }))
+ const speech = 'hello world'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ expect(mockCommandCallback.mock.calls.length).toBe(1)
+ })
+
+ test('matches one splat', async () => {
+ mockRecognitionManager()
+ const mockCommandCallback = jest.fn()
+ const commands = [
+ {
+ command: 'I want to eat * and fries',
+ callback: mockCommandCallback
+ }
+ ]
+ renderHook(() => useSpeechRecognition({ commands }))
+ const speech = 'I want to eat pizza and fries'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ expect(mockCommandCallback.mock.calls.length).toBe(1)
+ expect(mockCommandCallback).toBeCalledWith('pizza')
+ })
+
+ test('matches one splat at the end of the sentence', async () => {
+ mockRecognitionManager()
+ const mockCommandCallback = jest.fn()
+ const commands = [
+ {
+ command: 'I want to eat *',
+ callback: mockCommandCallback
+ }
+ ]
+ renderHook(() => useSpeechRecognition({ commands }))
+ const speech = 'I want to eat pizza and fries'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ expect(mockCommandCallback.mock.calls.length).toBe(1)
+ expect(mockCommandCallback).toBeCalledWith('pizza and fries')
+ })
+
+ test('matches two splats', async () => {
+ mockRecognitionManager()
+ const mockCommandCallback = jest.fn()
+ const commands = [
+ {
+ command: 'I want to eat * and *',
+ callback: mockCommandCallback
+ }
+ ]
+ renderHook(() => useSpeechRecognition({ commands }))
+ const speech = 'I want to eat pizza and fries'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ expect(mockCommandCallback.mock.calls.length).toBe(1)
+ expect(mockCommandCallback).toBeCalledWith('pizza', 'fries')
+ })
+
+ test('matches optional words when optional word spoken', async () => {
+ mockRecognitionManager()
+ const mockCommandCallback = jest.fn()
+ const commands = [
+ {
+ command: 'Hello (to) you',
+ callback: mockCommandCallback
+ }
+ ]
+ renderHook(() => useSpeechRecognition({ commands }))
+ const speech = 'Hello to you'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ expect(mockCommandCallback.mock.calls.length).toBe(1)
+ })
+
+ test('matches optional words when optional word not spoken', async () => {
+ mockRecognitionManager()
+ const mockCommandCallback = jest.fn()
+ const commands = [
+ {
+ command: 'Hello (to) you',
+ callback: mockCommandCallback
+ }
+ ]
+ renderHook(() => useSpeechRecognition({ commands }))
+ const speech = 'Hello you'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ expect(mockCommandCallback.mock.calls.length).toBe(1)
+ })
+
+ test('matches named variable', async () => {
+ mockRecognitionManager()
+ const mockCommandCallback = jest.fn()
+ const commands = [
+ {
+ command: 'I :action with my little eye',
+ callback: mockCommandCallback
+ }
+ ]
+ renderHook(() => useSpeechRecognition({ commands }))
+ const speech = 'I spy with my little eye'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ expect(mockCommandCallback.mock.calls.length).toBe(1)
+ expect(mockCommandCallback).toBeCalledWith('spy')
+ })
+
+ test('matches regex', async () => {
+ mockRecognitionManager()
+ const mockCommandCallback = jest.fn()
+ const commands = [
+ {
+ command: new RegExp('This is a \\s+ test\\.+'),
+ callback: mockCommandCallback
+ }
+ ]
+ renderHook(() => useSpeechRecognition({ commands }))
+ const speech = 'This is a test.......'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ expect(mockCommandCallback.mock.calls.length).toBe(1)
+ })
+
+ test('matches regex case-insensitively', async () => {
+ mockRecognitionManager()
+ const mockCommandCallback = jest.fn()
+ const commands = [
+ {
+ command: new RegExp('This is a \\s+ test\\.+'),
+ callback: mockCommandCallback
+ }
+ ]
+ renderHook(() => useSpeechRecognition({ commands }))
+ const speech = 'this is a TEST.......'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ expect(mockCommandCallback.mock.calls.length).toBe(1)
+ })
+
+ test('matches multiple commands', async () => {
+ mockRecognitionManager()
+ const mockCommandCallback1 = jest.fn()
+ const mockCommandCallback2 = jest.fn()
+ const mockCommandCallback3 = jest.fn()
+ const commands = [
+ {
+ command: 'I want to eat * and *',
+ callback: mockCommandCallback1
+ },
+ {
+ command: '* and fries are great',
+ callback: mockCommandCallback2
+ },
+ {
+ command: 'flibble',
+ callback: mockCommandCallback3
+ }
+ ]
+ renderHook(() => useSpeechRecognition({ commands }))
+ const speech = 'I want to eat pizza and fries are great'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ expect(mockCommandCallback1.mock.calls.length).toBe(1)
+ expect(mockCommandCallback1).toBeCalledWith('pizza', 'fries are great')
+ expect(mockCommandCallback2.mock.calls.length).toBe(1)
+ expect(mockCommandCallback2).toBeCalledWith('I want to eat pizza')
+ expect(mockCommandCallback3.mock.calls.length).toBe(0)
+ })
+
+ test('does not match interim results by default', async () => {
+ mockRecognitionManager()
+ const mockCommandCallback = jest.fn()
+ const commands = [
+ {
+ command: 'This is',
+ callback: mockCommandCallback
+ }
+ ]
+ renderHook(() => useSpeechRecognition({ commands }))
+ const speech = 'This is a test'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ expect(mockCommandCallback.mock.calls.length).toBe(0)
+ })
+
+ test('matches interim results when configured', async () => {
+ mockRecognitionManager()
+ const mockCommandCallback = jest.fn()
+ const commands = [
+ {
+ command: 'This is',
+ callback: mockCommandCallback,
+ matchInterim: true
+ }
+ ]
+ renderHook(() => useSpeechRecognition({ commands }))
+ const speech = 'This is a test'
+
+ await act(async () => {
+ await SpeechRecognition.startListening()
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+
+ expect(mockCommandCallback.mock.calls.length).toBe(1)
+ })
+
+ test('transcript resets should be per instance, not global', async () => {
+ mockRecognitionManager()
+ const hook1 = renderHook(() => useSpeechRecognition())
+ const hook2 = renderHook(() => useSpeechRecognition())
+ const speech = 'This is a test'
+
+ await act(async () => {
+ await SpeechRecognition.startListening({ continuous: true })
+ })
+ act(() => {
+ SpeechRecognition.getRecognition().say(speech)
+ })
+ act(() => {
+ hook2.result.current.resetTranscript()
+ })
+
+ expect(hook2.result.current.transcript).toEqual('')
+ expect(hook2.result.current.interimTranscript).toEqual('')
+ expect(hook2.result.current.finalTranscript).toEqual('')
+ expect(hook1.result.current.transcript).toEqual(speech)
+ expect(hook1.result.current.interimTranscript).toEqual('')
+ expect(hook1.result.current.finalTranscript).toEqual(speech)
+ })
+})
diff --git a/src/actions.js b/src/actions.js
new file mode 100644
index 0000000..92e9b4d
--- /dev/null
+++ b/src/actions.js
@@ -0,0 +1,15 @@
+import { CLEAR_TRANSCRIPT, APPEND_TRANSCRIPT } from './constants'
+
+export const clearTrancript = () => {
+ return { type: CLEAR_TRANSCRIPT }
+}
+
+export const appendTrancript = (interimTranscript, finalTranscript) => {
+ return {
+ type: APPEND_TRANSCRIPT,
+ payload: {
+ interimTranscript,
+ finalTranscript
+ }
+ }
+}
diff --git a/src/constants.js b/src/constants.js
new file mode 100644
index 0000000..2a3aa46
--- /dev/null
+++ b/src/constants.js
@@ -0,0 +1,2 @@
+export const CLEAR_TRANSCRIPT = 'CLEAR_TRANSCRIPT'
+export const APPEND_TRANSCRIPT = 'APPEND_TRANSCRIPT'
diff --git a/src/index.js b/src/index.js
index 81ef8c8..c211bf8 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,3 +1,4 @@
-import SpeechRecognition from './SpeechRecognition'
+import SpeechRecognition, { useSpeechRecognition } from './SpeechRecognition'
+export { useSpeechRecognition }
export default SpeechRecognition
diff --git a/src/isAndroid.js b/src/isAndroid.js
new file mode 100644
index 0000000..6b84000
--- /dev/null
+++ b/src/isAndroid.js
@@ -0,0 +1 @@
+export default () => /(android)/i.test(navigator.userAgent)
diff --git a/src/reducers.js b/src/reducers.js
new file mode 100644
index 0000000..09fffd9
--- /dev/null
+++ b/src/reducers.js
@@ -0,0 +1,21 @@
+import { CLEAR_TRANSCRIPT, APPEND_TRANSCRIPT } from './constants'
+import { concatTranscripts } from './utils'
+
+const transcriptReducer = (state, action) => {
+ switch (action.type) {
+ case CLEAR_TRANSCRIPT:
+ return {
+ interimTranscript: '',
+ finalTranscript: ''
+ }
+ case APPEND_TRANSCRIPT:
+ return {
+ interimTranscript: action.payload.interimTranscript,
+ finalTranscript: concatTranscripts(state.finalTranscript, action.payload.finalTranscript)
+ }
+ default:
+ throw new Error()
+ }
+}
+
+export { transcriptReducer }
diff --git a/src/utils.js b/src/utils.js
index 66c0cfe..87ae433 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -14,4 +14,29 @@ const debounce = (func, wait, immediate) => {
}
}
-export { debounce }
+const concatTranscripts = (...transcriptParts) => {
+ return transcriptParts.map(t => t.trim()).join(' ').trim()
+}
+
+// The command matching code is a modified version of Backbone.Router by Jeremy Ashkenas, under the MIT license.
+const optionalParam = /\s*\((.*?)\)\s*/g
+const optionalRegex = /(\(\?:[^)]+\))\?/g
+const namedParam = /(\(\?)?:\w+/g
+const splatParam = /\*/g
+const escapeRegExp = /[-{}[\]+?.,\\^$|#]/g
+const commandToRegExp = (command) => {
+ if (command instanceof RegExp) {
+ return new RegExp(command.source, 'i')
+ }
+ command = command
+ .replace(escapeRegExp, '\\$&')
+ .replace(optionalParam, '(?:$1)?')
+ .replace(namedParam, (match, optional) => {
+ return optional ? match : '([^\\s]+)'
+ })
+ .replace(splatParam, '(.*?)')
+ .replace(optionalRegex, '\\s*$1?\\s*')
+ return new RegExp('^' + command + '$', 'i')
+}
+
+export { debounce, concatTranscripts, commandToRegExp }
diff --git a/tests/SpeechRecognition.test.js b/tests/SpeechRecognition.test.js
deleted file mode 100644
index 546a2f4..0000000
--- a/tests/SpeechRecognition.test.js
+++ /dev/null
@@ -1,237 +0,0 @@
-import React from 'react'
-import { shallow, configure } from 'enzyme'
-import Adapter from 'enzyme-adapter-react-16'
-import Corti from './vendor/corti'
-import SpeechRecognition from '../src'
-
-configure({ adapter: new Adapter() })
-
-const setUserAgent = (userAgent) => {
- Object.defineProperty(navigator, 'userAgent', {
- get: function () {
- return userAgent
- },
- configurable: true
- })
-}
-
-describe('SpeechRecognition', () => {
- const mockSpeechRecognition = Corti(global)
-
- beforeEach(() => {
- mockSpeechRecognition.unpatch()
- })
-
- test('indicates when SpeechRecognition API is available', () => {
- mockSpeechRecognition.patch()
- const WrappedComponent = SpeechRecognition(() => null)
- const component = shallow( )
- const props = component.props()
-
- expect(props.browserSupportsSpeechRecognition).toEqual(true)
- expect(props.listening).toEqual(true)
- })
-
- test('indicates when SpeechRecognition API is not available', () => {
- const WrappedComponent = SpeechRecognition(() => null)
- const component = shallow( )
- const props = component.props()
-
- expect(props.browserSupportsSpeechRecognition).toEqual(false)
- expect(props.listening).toEqual(false)
- })
-
- test('sets default transcripts correctly', () => {
- mockSpeechRecognition.patch()
- const WrappedComponent = SpeechRecognition(() => null)
- const component = shallow( )
- const props = component.props()
-
- expect(props.transcript).toEqual('')
- expect(props.interimTranscript).toEqual('')
- expect(props.finalTranscript).toEqual('')
- })
-
- test('updates transcripts correctly', () => {
- mockSpeechRecognition.patch()
- const WrappedComponent = SpeechRecognition(() => null)
- const component = shallow( )
- const speech = 'This is a test'
-
- component.props().recognition.say(speech)
-
- const props = component.props()
- expect(props.transcript).toEqual(speech)
- expect(props.interimTranscript).toEqual('')
- expect(props.finalTranscript).toEqual(speech)
- })
-
- test('resets transcripts correctly', () => {
- mockSpeechRecognition.patch()
- const WrappedComponent = SpeechRecognition(() => null)
- const component = shallow( )
- const speech = 'This is a test'
-
- component.props().recognition.say(speech)
- component.props().resetTranscript()
-
- const props = component.props()
- expect(props.transcript).toEqual('')
- expect(props.interimTranscript).toEqual('')
- expect(props.finalTranscript).toEqual('')
- })
-
- test('stops listening correctly', () => {
- mockSpeechRecognition.patch()
- const WrappedComponent = SpeechRecognition(() => null)
- const component = shallow( )
- const speech = 'This is a test'
-
- component.props().stopListening()
- component.props().recognition.say(speech)
-
- const props = component.props()
- expect(props.transcript).toEqual('')
- expect(props.interimTranscript).toEqual('')
- expect(props.finalTranscript).toEqual('')
- })
-
- test('aborts listening correctly', () => {
- mockSpeechRecognition.patch()
- const WrappedComponent = SpeechRecognition(() => null)
- const component = shallow( )
- const speech = 'This is a test'
-
- component.props().abortListening()
- component.props().recognition.say(speech)
-
- const props = component.props()
- expect(props.transcript).toEqual('')
- expect(props.interimTranscript).toEqual('')
- expect(props.finalTranscript).toEqual('')
- })
-
- test('starts listening correctly', () => {
- mockSpeechRecognition.patch()
- const WrappedComponent = SpeechRecognition(() => null)
- const component = shallow( )
- const speech = 'This is a test'
-
- component.props().stopListening()
- component.props().startListening()
- component.props().recognition.say(speech)
-
- const props = component.props()
- expect(props.transcript).toEqual(speech)
- expect(props.interimTranscript).toEqual('')
- expect(props.finalTranscript).toEqual(speech)
- })
-
- test('can turn auto-start off', () => {
- mockSpeechRecognition.patch()
- const options = { autoStart: false }
- const WrappedComponent = SpeechRecognition(options)(() => null)
- const component = shallow( )
- const speech = 'This is a test'
-
- component.props().recognition.say(speech)
-
- const props = component.props()
- expect(props.transcript).toEqual('')
- expect(props.interimTranscript).toEqual('')
- expect(props.finalTranscript).toEqual('')
- })
-
- test('can listen again after auto-start turned off', () => {
- mockSpeechRecognition.patch()
- const options = { autoStart: false }
- const WrappedComponent = SpeechRecognition(options)(() => null)
- const component = shallow( )
- const speech = 'This is a test'
-
- component.props().startListening()
- component.props().recognition.say(speech)
-
- const props = component.props()
- expect(props.transcript).toEqual(speech)
- expect(props.interimTranscript).toEqual('')
- expect(props.finalTranscript).toEqual(speech)
- })
-
- test('listens continuously by default', () => {
- mockSpeechRecognition.patch()
- const WrappedComponent = SpeechRecognition(() => null)
- const component = shallow( )
- const speech = 'This is a test'
- const expectedTranscript = [speech, speech].join(' ')
-
- component.props().recognition.say(speech)
- component.props().recognition.say(speech)
-
- const props = component.props()
- expect(props.transcript).toEqual(expectedTranscript)
- expect(props.interimTranscript).toEqual('')
- expect(props.finalTranscript).toEqual(expectedTranscript)
- })
-
- test('can turn continuous listening off', () => {
- mockSpeechRecognition.patch()
- const options = { continuous: false }
- const WrappedComponent = SpeechRecognition(options)(() => null)
- const component = shallow( )
- const speech = 'This is a test'
-
- component.props().recognition.say(speech)
- component.props().recognition.say(speech)
-
- const props = component.props()
- expect(props.transcript).toEqual(speech)
- expect(props.interimTranscript).toEqual('')
- expect(props.finalTranscript).toEqual(speech)
- })
-
- test('sets interim transcript correctly', () => {
- mockSpeechRecognition.patch()
- const WrappedComponent = SpeechRecognition(() => null)
- const component = shallow( )
- const speech = 'This is a test'
-
- component.props().recognition.say(speech, { onlyFirstResult: true })
-
- const props = component.props()
- expect(props.transcript).toEqual('This')
- expect(props.interimTranscript).toEqual('This')
- expect(props.finalTranscript).toEqual('')
- })
-
- test('appends interim transcript correctly', () => {
- mockSpeechRecognition.patch()
- const WrappedComponent = SpeechRecognition(() => null)
- const component = shallow( )
- const speech = 'This is a test'
-
- component.props().recognition.say(speech)
- component.props().recognition.say(speech, { onlyFirstResult: true })
-
- const props = component.props()
- expect(props.transcript).toEqual('This is a test This')
- expect(props.interimTranscript).toEqual('This')
- expect(props.finalTranscript).toEqual(speech)
- })
-
- test('appends interim transcript correctly on Android', () => {
- mockSpeechRecognition.patch()
- setUserAgent('android')
- const WrappedComponent = SpeechRecognition(() => null)
- const component = shallow( )
- const speech = 'This is a test'
-
- component.props().recognition.say(speech, { isAndroid: true })
- component.props().recognition.say(speech, { onlyFirstResult: true, isAndroid: true })
-
- const props = component.props()
- expect(props.transcript).toEqual('This is a test This')
- expect(props.interimTranscript).toEqual('This')
- expect(props.finalTranscript).toEqual(speech)
- })
-})
diff --git a/tests/vendor/corti.js b/tests/vendor/corti.js
index 477bb39..93e3fa2 100644
--- a/tests/vendor/corti.js
+++ b/tests/vendor/corti.js
@@ -4,7 +4,7 @@
//! license : MIT
//! https://github.com/TalAter/Corti
-export default function (_root) {
+const Corti = (_root) => {
// Holds the browser's implementation
var _productionVersion = false
@@ -202,3 +202,7 @@ export default function (_root) {
}
}
}
+
+const mockSpeechRecognition = Corti(global)
+mockSpeechRecognition.patch()
+export default mockSpeechRecognition